diff --git a/macos-vm/export-macos-vm.ps1 b/macos-vm/export-macos-vm.ps1 deleted file mode 100644 index 787ff63f..00000000 --- a/macos-vm/export-macos-vm.ps1 +++ /dev/null @@ -1,20 +0,0 @@ -$ErrorActionPreference = "Stop" - -$timestamp = Get-Date -Format "yyyyMMdd_HHmmss" -$src = "C:\Users\29195\Mycontent\macos-vm\OneClick-macOS-Simple-KVM" -$dst = "C:\Users\29195\Mycontent\macos-vm\macos-vm-snapshot-$timestamp.zip" - -Write-Host "打包目录: $src" -Write-Host "目标文件: $dst" - -if (-not (Test-Path $src)) { - Write-Error "源目录不存在:$src" -} - -if (Test-Path $dst) { - Remove-Item $dst -Force -} - -Compress-Archive -Path $src -DestinationPath $dst -Force -Write-Host '打包完成.' - diff --git a/macos-vm/一键启动-macOS虚拟机.bat b/macos-vm/一键启动-macOS虚拟机.bat deleted file mode 100644 index 3dac307f..00000000 --- a/macos-vm/一键启动-macOS虚拟机.bat +++ /dev/null @@ -1,37 +0,0 @@ -@echo off -chcp 65001 >nul -title 一键启动 macOS 虚拟机 + TightVNC - -echo ======================================== -echo 一键启动 macOS 虚拟机(龙虾方案) -echo ======================================== -echo. - -set "VM_DIR=%USERPROFILE%\Mycontent\macos-vm\OneClick-macOS-Simple-KVM" -if not exist "%VM_DIR%\basic.sh" ( - echo [错误] 未找到虚拟机目录: %VM_DIR% - echo 请先运行龙虾安装流程完成首次部署。 - pause - exit /b 1 -) - -echo [1] 在新窗口启动 macOS 虚拟机(8G 内存 / 4 核)... -start "macOS 虚拟机 - 勿关此窗口" wsl -d Ubuntu-24.04 -e bash -lc "cd /mnt/c/Users/%USERNAME%/Mycontent/macos-vm/OneClick-macOS-Simple-KVM && sudo HEADLESS=1 ./basic.sh" - -echo [2] 等待约 10 秒后自动打开 TightVNC Viewer 连接 localhost:5900 ... -timeout /t 10 /nobreak >nul - -set "TVN=%ProgramFiles%\TightVNC\tvnviewer.exe" -if not exist "%TVN%" set "TVN=%ProgramFiles(x86)%\TightVNC\tvnviewer.exe" -if exist "%TVN%" ( - start "" "%TVN%" localhost::5900 - echo [3] 已启动 TightVNC Viewer,连接 localhost:5900 -) else ( - echo [3] 未找到 TightVNC,请手动打开 VNC 客户端连接: localhost:5900 -) - -echo. -echo 虚拟机在「macOS 虚拟机 - 勿关此窗口」中运行,关闭该窗口会关闭虚拟机。 -echo 本窗口可以关闭。 -echo ======================================== -pause diff --git a/macos-vm/安装mac.bat b/macos-vm/安装mac.bat deleted file mode 100644 index 9932eae6..00000000 --- a/macos-vm/安装mac.bat +++ /dev/null @@ -1,62 +0,0 @@ -@echo off -chcp 65001 >nul -title 安装 macOS 虚拟机(龙虾方案) - -setlocal - -echo ============================================ -echo 安装 macOS 虚拟机(WSL2 + QEMU + OneClick) -echo ============================================ -echo. - -rem 1. 定位 Python 安装脚本(仓库内已有) -set "ROOT=%~dp0.." -set "PY_SCRIPT=%ROOT%开发文档\服务器管理\scripts\lobster_macos_vm.py" - -if not exist "%PY_SCRIPT%" ( - echo [错误] 找不到 Python 安装脚本: - echo %PY_SCRIPT% - echo 请确认仓库已完整同步。 - pause - exit /b 1 -) - -rem 2. 检查 Python -where python >nul 2>&1 -if errorlevel 1 ( - where py >nul 2>&1 - if errorlevel 1 ( - echo [错误] 未检测到 Python 3,请先安装 Python 3 再运行本脚本。 - echo 将打开 Python 官网下載頁面,請安裝完後重新運行本腳本。 - start "" "https://www.python.org/downloads/windows/" - pause - exit /b 1 - ) -) - -rem 3. 检查 / 引导安装 TightVNC -echo [1] 检查 TightVNC Viewer ... -set "TVN=%ProgramFiles%\TightVNC\tvnviewer.exe" -if not exist "%TVN%" set "TVN=%ProgramFiles(x86)%\TightVNC\tvnviewer.exe" - -if exist "%TVN%" ( - echo 已检测到 TightVNC: %TVN% -) else ( - echo 未检测到 TightVNC,將打開官網請手動下載並安裝。 - start "" "https://www.tightvnc.com/download.php" -) - -echo. -echo [2] 開始調用 Python 腳本,一鍵安裝 macOS 虛擬機 ... -echo 腳本將檢查 WSL/Ubuntu、下載 OneClick、安裝 QEMU、下載 macOS 恢復鏡像等。 -echo. - -python "%PY_SCRIPT%" || py -3 "%PY_SCRIPT%" - -echo. -echo [3] 安裝流程結束(若上方無紅色錯誤信息,即表示完成)。 -echo 之後可使用同目錄下的「一键启动-macOS虚拟机.bat」啟動虛擬機。 -echo ============================================ -echo. -pause - diff --git a/macos-vm/迁移-macos-vm-到E盘.bat b/macos-vm/迁移-macos-vm-到E盘.bat deleted file mode 100644 index ff8acc69..00000000 --- a/macos-vm/迁移-macos-vm-到E盘.bat +++ /dev/null @@ -1,57 +0,0 @@ -@echo off -chcp 65001 >nul -title 迁移 macOS 虚拟机 到 E:\Gongsi\Mycontent\macos-vm - -echo ============================================ -echo 迁移 macOS 虚拟机目录 到 E:\Gongsi\Mycontent\macos-vm -echo ============================================ -echo. - -setlocal - -set "SRC=C:\Users\%USERNAME%\Mycontent\macos-vm" -set "DST=E:\Gongsi\Mycontent\macos-vm" - -echo [1] 源目录: %SRC% -echo [1] 目标目录: %DST% -echo. - -if not exist "%SRC%" ( - echo [错误] 未找到源目录: %SRC% - echo 请确认当前用户下已存在 macos-vm 目录。 - pause - exit /b 1 -) - -rem 尝试关闭正在运行的 QEMU(通过 WSL) -echo [2] 尝试关闭正在运行的 macOS 虚拟机(如有)... -wsl -d Ubuntu-24.04 -e bash -lc "ps -ef | grep qemu-system-x86_64 | grep -v grep || true" >nul 2>&1 -for /f "tokens=2" %%P in ('wsl -d Ubuntu-24.04 -e bash -lc "ps -ef | grep qemu-system-x86_64 | grep -v grep || true" ^| find "qemu-system-x86_64"') do ( - echo 检测到 QEMU 进程 PID=%%P,正在尝试结束... - wsl -d Ubuntu-24.04 -e bash -lc "sudo kill -TERM %%P; sleep 2; ps -p %%P >/dev/null && sudo kill -KILL %%P || true" >nul 2>&1 -) - -echo [3] 创建目标目录(如不存在)... -mkdir "%DST%" 2>nul - -echo [4] 使用 robocopy 迁移所有文件(可能需要一段时间)... -echo. -robocopy "%SRC%" "%DST%" /MIR - -if errorlevel 8 ( - echo. - echo [警告] robocopy 返回代码 %errorlevel%(>=8),可能有错误,請檢查上方輸出。 - echo 不會自動刪除源目錄,請手動確認。 - pause - exit /b 1 -) - -echo. -echo [5] 迁移完成。 -echo 源目录: %SRC% -echo 目标目录: %DST% -echo. -echo 如確認新位置可以正常啟動虛擬機,可手動刪除源目錄以釋放 C 盤空間。 -echo ============================================ -pause - diff --git a/miniprogram/app.js b/miniprogram/app.js index a3755b46..53a7282e 100644 --- a/miniprogram/app.js +++ b/miniprogram/app.js @@ -8,8 +8,8 @@ const { parseScene } = require('./utils/scene.js') App({ globalData: { // API 基础地址(切换环境时注释/取消注释) - baseUrl: 'https://soulapi.quwanzhi.com', - // baseUrl: 'http://localhost:8080', // 本地调试 + // baseUrl: 'https://soulapi.quwanzhi.com', + baseUrl: 'http://localhost:8080', // 本地调试 // baseUrl: 'https://souldev.quwanzhi.com', // 测试环境 diff --git a/miniprogram/pages/profile-edit/profile-edit.js b/miniprogram/pages/profile-edit/profile-edit.js index 7460ae93..1fb7c0dc 100644 --- a/miniprogram/pages/profile-edit/profile-edit.js +++ b/miniprogram/pages/profile-edit/profile-edit.js @@ -18,6 +18,7 @@ Page({ isVip: false, avatar: '', nickname: '', + shareCardPath: '', // 分享名片封面图(预生成) mbti: '', mbtiIndex: 0, region: '', @@ -40,8 +41,15 @@ Page({ showAvatarModal: false, }, - onLoad() { + onLoad(options) { this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44 }) + wx.showShareMenu({ withShareTimeline: true }) + // 从朋友圈/分享打开且带 id:跳转到名片详情(member-detail) + if (options?.id) { + const ref = options.ref ? `&ref=${options.ref}` : '' + wx.redirectTo({ url: `/pages/member-detail/member-detail?id=${options.id}${ref}` }) + return + } this.loadProfile() }, @@ -85,6 +93,7 @@ Page({ projectIntro: v('projectIntro'), loading: false, }) + setTimeout(() => this.generateShareCard(), 200) } else { this.setData({ loading: false }) } @@ -95,17 +104,128 @@ Page({ goBack() { getApp().goBackOrToHome() }, + // 生成分享名片封面图(头像+昵称,5:4 比例) + async generateShareCard() { + const { avatar, nickname } = this.data + const userId = app.globalData.userInfo?.id + if (!userId) return + try { + const ctx = wx.createCanvasContext('shareCardCanvas', this) + const w = 500 + const h = 400 + // 背景渐变(Soul 深色风格) + const grd = ctx.createLinearGradient(0, 0, w, h) + grd.addColorStop(0, '#0F172A') + grd.addColorStop(0.5, '#050B14') + grd.addColorStop(1, '#0F172A') + ctx.setFillStyle(grd) + ctx.fillRect(0, 0, w, h) + // 顶部装饰条 + ctx.setFillStyle('#5EEAD4') + ctx.fillRect(0, 0, w, 4) + // 头像:居中偏上,圆形 120px + const avatarSize = 120 + const avatarX = (w - avatarSize) / 2 + const avatarY = 80 + const avatarRadius = avatarSize / 2 + const drawAvatar = () => new Promise((resolve) => { + if (avatar && avatar.startsWith('http')) { + wx.downloadFile({ + url: avatar, + success: (res) => { + if (res.statusCode === 200) { + ctx.save() + ctx.beginPath() + ctx.arc(avatarX + avatarRadius, avatarY + avatarRadius, avatarRadius, 0, Math.PI * 2) + ctx.clip() + ctx.drawImage(res.tempFilePath, avatarX, avatarY, avatarSize, avatarSize) + ctx.restore() + } else { + this.drawAvatarPlaceholder(ctx, avatarX, avatarY, avatarSize, nickname) + } + resolve() + }, + fail: () => { + this.drawAvatarPlaceholder(ctx, avatarX, avatarY, avatarSize, nickname) + resolve() + }, + }) + } else { + this.drawAvatarPlaceholder(ctx, avatarX, avatarY, avatarSize, nickname) + resolve() + } + }) + await drawAvatar() + // 头像外圈描边 + ctx.setStrokeStyle('#5EEAD4') + ctx.setLineWidth(3) + ctx.beginPath() + ctx.arc(avatarX + avatarRadius, avatarY + avatarRadius, avatarRadius, 0, Math.PI * 2) + ctx.stroke() + // 昵称 + const displayName = (nickname || '').trim() || '创业者' + ctx.setFillStyle('#ffffff') + ctx.setFontSize(24) + ctx.setTextAlign('center') + ctx.fillText(displayName, w / 2, avatarY + avatarSize + 50) + // 副标题 + ctx.setFillStyle('rgba(94,234,212,0.9)') + ctx.setFontSize(14) + ctx.fillText('Soul创业派对 · 名片', w / 2, avatarY + avatarSize + 78) + ctx.draw(true, () => { + wx.canvasToTempFilePath({ + canvasId: 'shareCardCanvas', + destWidth: 500, + destHeight: 400, + success: (res) => { + this.setData({ shareCardPath: res.tempFilePath }) + }, + }, this) + }) + } catch (e) { + console.warn('[ShareCard] 生成失败:', e) + } + }, + + drawAvatarPlaceholder(ctx, x, y, size, nickname) { + ctx.setFillStyle('rgba(94,234,212,0.25)') + ctx.beginPath() + ctx.arc(x + size / 2, y + size / 2, size / 2, 0, Math.PI * 2) + ctx.fill() + ctx.setFillStyle('#5EEAD4') + ctx.setFontSize(size * 0.45) + ctx.setTextAlign('center') + ctx.fillText((nickname || '?')[0], x + size / 2, y + size / 2 + size * 0.15) + }, + onShareAppMessage() { const ref = app.getMyReferralCode() - return { - title: 'Soul创业派对 - 编辑资料', - path: ref ? `/pages/profile-edit/profile-edit?ref=${ref}` : '/pages/profile-edit/profile-edit' + const userId = app.globalData.userInfo?.id + const nickname = (this.data.nickname || '').trim() || '我' + const path = userId + ? (ref ? `/pages/member-detail/member-detail?id=${userId}&ref=${ref}` : `/pages/member-detail/member-detail?id=${userId}`) + : (ref ? `/pages/profile-edit/profile-edit?ref=${ref}` : '/pages/profile-edit/profile-edit') + const result = { + title: `${nickname}为您分享名片`, + path, } + if (this.data.shareCardPath) result.imageUrl = this.data.shareCardPath + return result }, onShareTimeline() { const ref = app.getMyReferralCode() - return { title: 'Soul创业派对 - 编辑资料', query: ref ? `ref=${ref}` : '' } + const userId = app.globalData.userInfo?.id + const nickname = (this.data.nickname || '').trim() || '我' + const query = userId + ? (ref ? `id=${userId}&ref=${ref}` : `id=${userId}`) + : (ref ? `ref=${ref}` : '') + const result = { + title: `${nickname}为您分享名片`, + query: query || '', + } + if (this.data.shareCardPath) result.imageUrl = this.data.shareCardPath + return result }, onNicknameInput(e) { this.setData({ nickname: e.detail.value }) }, @@ -186,6 +306,7 @@ Page({ } wx.hideLoading() wx.showToast({ title: '头像已更新', icon: 'success' }) + setTimeout(() => this.generateShareCard(), 200) } catch (e) { wx.hideLoading() wx.showToast({ title: e.message || '上传失败', icon: 'none' }) @@ -234,6 +355,7 @@ Page({ } wx.hideLoading() wx.showToast({ title: '头像已更新', icon: 'success' }) + setTimeout(() => this.generateShareCard(), 200) } catch (err) { wx.hideLoading() wx.showToast({ title: err.message || '上传失败,请重试', icon: 'none' }) diff --git a/miniprogram/pages/profile-edit/profile-edit.wxml b/miniprogram/pages/profile-edit/profile-edit.wxml index 8c6d57ad..8e596269 100644 --- a/miniprogram/pages/profile-edit/profile-edit.wxml +++ b/miniprogram/pages/profile-edit/profile-edit.wxml @@ -146,6 +146,9 @@ + + + diff --git a/miniprogram/pages/profile-edit/profile-edit.wxss b/miniprogram/pages/profile-edit/profile-edit.wxss index 77801e8b..b623fca1 100644 --- a/miniprogram/pages/profile-edit/profile-edit.wxss +++ b/miniprogram/pages/profile-edit/profile-edit.wxss @@ -1,4 +1,9 @@ /* 资料编辑 - comprehensive_profile_editor_v1_1 | 配色 enhanced,input/textarea 用 view 包裹 */ + +/* 分享名片 canvas:隐藏,仅用于生成图片 */ +.share-card-canvas { + position: fixed; left: -9999px; top: 0; width: 500px; height: 400px; +} .page { background: #050B14; min-height: 100vh; color: #fff; width: 100%; box-sizing: border-box; overflow-x: hidden; diff --git a/miniprogram/project.private.config.json b/miniprogram/project.private.config.json index a4caf5f6..b75b4c26 100644 --- a/miniprogram/project.private.config.json +++ b/miniprogram/project.private.config.json @@ -23,12 +23,19 @@ "condition": { "miniprogram": { "list": [ + { + "name": "pages/read/read", + "pathName": "pages/read/read", + "query": "mid=219", + "scene": null, + "launchMode": "default" + }, { "name": "唤醒", "pathName": "pages/read/read", "query": "mid=209", - "scene": null, - "launchMode": "default" + "launchMode": "default", + "scene": null }, { "name": "pages/my/my", diff --git a/soul-admin/deploy.py b/soul-admin/deploy.py new file mode 100644 index 00000000..85dc79ab --- /dev/null +++ b/soul-admin/deploy.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +soul-admin-dev 静态站点部署:打包 dist → 上传 → 解压到 dist2 → dist/dist2 互换实现无缝切换。 +不安装依赖、不重启、不调用宝塔 API。 +""" + +from __future__ import print_function + +import os +import sys +import shlex +import tempfile +import argparse +import zipfile + +try: + import paramiko +except ImportError: + print("错误: 请先安装 paramiko") + print(" pip install paramiko") + sys.exit(1) + +# ==================== 配置 ==================== + +# 站点根目录(Nginx 等指向的目录的上一级,即 dist 的父目录) +DEPLOY_BASE_PATH = "/www/wwwroot/self/soul-admin-dev" +# 切换后 chown 的属主,宝塔一般为 www:www,空则跳过 +DEPLOY_WWW_USER = os.environ.get("DEPLOY_WWW_USER", "www:www") +DEFAULT_SSH_PORT = int(os.environ.get("DEPLOY_SSH_PORT", "22022")) + + +def get_cfg(): + base = os.environ.get("DEPLOY_BASE_PATH", DEPLOY_BASE_PATH).rstrip("/") + return { + "host": os.environ.get("DEPLOY_HOST", "43.139.27.93"), + "user": os.environ.get("DEPLOY_USER", "root"), + "password": os.environ.get("DEPLOY_PASSWORD", "Zhiqun1984"), + "ssh_key": os.environ.get("DEPLOY_SSH_KEY", ""), + "base_path": base, + "dist_path": base + "/dist", + "dist2_path": base + "/dist2", + "www_user": os.environ.get("DEPLOY_WWW_USER", DEPLOY_WWW_USER).strip(), + } + + +# ==================== 本地构建 ==================== + + +def run_build(root): + """执行本地 pnpm build(使用 .env.development 测试环境配置)""" + use_shell = sys.platform == "win32" + dist_dir = os.path.join(root, "dist") + index_html = os.path.join(dist_dir, "index.html") + + try: + r = __import__("subprocess").run( + ["pnpm", "run", "build:dev"], + cwd=root, + shell=use_shell, + timeout=300, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + ) + if r.returncode != 0: + print(" [失败] 构建失败,退出码:", r.returncode) + for line in (r.stdout or "").strip().split("\n")[-10:]: + print(" " + line) + return False + except __import__("subprocess").TimeoutExpired: + print(" [失败] 构建超时") + return False + except FileNotFoundError: + print(" [失败] 未找到 pnpm,请安装: npm install -g pnpm") + return False + except Exception as e: + print(" [失败] 构建异常:", str(e)) + return False + + if not os.path.isfile(index_html): + print(" [失败] 未找到 dist/index.html") + return False + print(" [成功] 构建完成") + return True + + +# ==================== 打包 dist 为 zip ==================== + + +def pack_dist_zip(root): + """将本地 dist 目录打包为 zip(解压到 dist2 后即为站点根内容)""" + print("[2/4] 打包 dist 为 zip ...") + dist_dir = os.path.join(root, "dist") + if not os.path.isdir(dist_dir): + print(" [失败] 未找到 dist 目录") + return None + index_html = os.path.join(dist_dir, "index.html") + if not os.path.isfile(index_html): + print(" [失败] 未找到 dist/index.html,请先执行 pnpm build") + return None + + zip_path = os.path.join(tempfile.gettempdir(), "soul_admin_deploy.zip") + try: + with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf: + for dirpath, _dirs, filenames in os.walk(dist_dir): + for f in filenames: + full = os.path.join(dirpath, f) + arcname = os.path.relpath(full, dist_dir).replace("\\", "/") + zf.write(full, arcname) + print(" [成功] 打包完成: %s (%.2f MB)" % (zip_path, os.path.getsize(zip_path) / 1024 / 1024)) + return zip_path + except Exception as e: + print(" [失败] 打包异常:", str(e)) + return None + + +# ==================== SSH 上传并解压到 dist2 ==================== + + +def upload_zip_and_extract_to_dist2(cfg, zip_path): + """上传 zip 到服务器并解压到 dist2""" + print("[3/4] SSH 上传 zip 并解压到 dist2 ...") + sys.stdout.flush() + if not cfg.get("password") and not cfg.get("ssh_key"): + print(" [失败] 请设置 DEPLOY_PASSWORD 或 DEPLOY_SSH_KEY") + return False + zip_size_mb = os.path.getsize(zip_path) / (1024 * 1024) + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + try: + print(" 正在连接 %s@%s:%s ..." % (cfg["user"], cfg["host"], DEFAULT_SSH_PORT)) + sys.stdout.flush() + if cfg.get("ssh_key") and os.path.isfile(cfg["ssh_key"]): + client.connect( + cfg["host"], + port=DEFAULT_SSH_PORT, + username=cfg["user"], + key_filename=cfg["ssh_key"], + timeout=30, + banner_timeout=30, + ) + else: + client.connect( + cfg["host"], + port=DEFAULT_SSH_PORT, + username=cfg["user"], + password=cfg["password"], + timeout=30, + banner_timeout=30, + ) + print(" [OK] SSH 已连接,正在上传 zip(%.1f MB)..." % zip_size_mb) + sys.stdout.flush() + remote_zip = cfg["base_path"] + "/soul_admin_deploy.zip" + sftp = client.open_sftp() + chunk_mb = 5.0 + last_reported = [0] + + def _progress(transferred, total): + if total and total > 0: + now_mb = transferred / (1024 * 1024) + if now_mb - last_reported[0] >= chunk_mb or transferred >= total: + last_reported[0] = now_mb + print("\r 上传进度: %.1f / %.1f MB" % (now_mb, total / (1024 * 1024)), end="") + sys.stdout.flush() + + sftp.put(zip_path, remote_zip, callback=_progress) + if zip_size_mb >= chunk_mb: + print("") + print(" [OK] zip 已上传,正在服务器解压到 dist2 ...") + sys.stdout.flush() + sftp.close() + dist2 = cfg["dist2_path"] + cmd = "rm -rf %s && mkdir -p %s && unzip -o -q %s -d %s && rm -f %s && echo OK" % ( + dist2, + dist2, + remote_zip, + dist2, + remote_zip, + ) + stdin, stdout, stderr = client.exec_command(cmd, timeout=120) + out = stdout.read().decode("utf-8", errors="replace").strip() + err = stderr.read().decode("utf-8", errors="replace").strip() + if err: + print(" 服务器 stderr: %s" % err[:500]) + exit_status = stdout.channel.recv_exit_status() + if exit_status != 0 or "OK" not in out: + print(" [失败] 解压失败,退出码: %s" % exit_status) + if out: + print(" stdout: %s" % out[:300]) + return False + print(" [成功] 已解压到: %s" % dist2) + return True + except Exception as e: + print(" [失败] SSH 错误: %s" % str(e)) + import traceback + traceback.print_exc() + return False + finally: + client.close() + + +# ==================== 服务器目录切换:dist → dist1,dist2 → dist ==================== + + +def remote_swap_dist(cfg): + """服务器上:dist→dist1,dist2→dist,删除 dist1,实现无缝切换""" + print("[4/4] 服务器切换目录: dist→dist1, dist2→dist ...") + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + try: + if cfg.get("ssh_key") and os.path.isfile(cfg["ssh_key"]): + client.connect( + cfg["host"], + port=DEFAULT_SSH_PORT, + username=cfg["user"], + key_filename=cfg["ssh_key"], + timeout=15, + ) + else: + client.connect( + cfg["host"], + port=DEFAULT_SSH_PORT, + username=cfg["user"], + password=cfg["password"], + timeout=15, + ) + base = cfg["base_path"] + # 若当前没有 dist(首次部署),则 dist2 直接改名为 dist;若有 dist 则先备份再替换 + cmd = "cd %s && (test -d dist && (mv dist dist1 && mv dist2 dist && rm -rf dist1) || mv dist2 dist) && echo OK" % base + stdin, stdout, stderr = client.exec_command(cmd, timeout=60) + out = stdout.read().decode("utf-8", errors="replace").strip() + err = stderr.read().decode("utf-8", errors="replace").strip() + exit_status = stdout.channel.recv_exit_status() + if exit_status != 0 or "OK" not in out: + print(" [失败] 切换失败 (退出码: %s)" % exit_status) + if err: + print(" 服务器 stderr: %s" % err) + if out and "OK" not in out: + print(" 服务器 stdout: %s" % out) + return False + print(" [成功] 新版本已切换至: %s" % cfg["dist_path"]) + # 切换后设置 www 访问权限,否则 Nginx 无法读文件导致无法访问 + www_user = cfg.get("www_user") + if www_user: + dist_path = cfg["dist_path"] + chown_cmd = "chown -R %s %s && echo OK" % (www_user, shlex.quote(dist_path)) + stdin, stdout, stderr = client.exec_command(chown_cmd, timeout=60) + chown_out = stdout.read().decode("utf-8", errors="replace").strip() + chown_err = stderr.read().decode("utf-8", errors="replace").strip() + if stdout.channel.recv_exit_status() != 0 or "OK" not in chown_out: + print(" [警告] chown 失败,站点可能无法访问: %s" % (chown_err or chown_out)) + else: + print(" [成功] 已设置属主: %s" % www_user) + return True + except Exception as e: + print(" [失败] SSH 错误: %s" % str(e)) + return False + finally: + client.close() + + +# ==================== 主函数 ==================== + + +def main(): + parser = argparse.ArgumentParser( + description="soul-admin-dev 静态站点部署(dist2 解压后目录切换,无缝更新)", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="不安装依赖、不重启、不调用宝塔 API。站点路径: " + DEPLOY_BASE_PATH + "/dist", + ) + parser.add_argument("--no-build", action="store_true", help="跳过本地 pnpm build") + args = parser.parse_args() + + script_dir = os.path.dirname(os.path.abspath(__file__)) + if os.path.isfile(os.path.join(script_dir, "package.json")): + root = script_dir + else: + root = os.path.dirname(script_dir) + + cfg = get_cfg() + print("=" * 60) + print(" soul-admin-dev 部署(dist/dist2 无缝切换)") + print("=" * 60) + print(" 服务器: %s@%s 站点目录: %s" % (cfg["user"], cfg["host"], cfg["dist_path"])) + print("=" * 60) + + if not args.no_build: + print("[1/4] 本地构建 pnpm build ...") + if not run_build(root): + return 1 + else: + if not os.path.isdir(os.path.join(root, "dist")) or not os.path.isfile( + os.path.join(root, "dist", "index.html") + ): + print("[错误] 未找到 dist/index.html,请先执行 pnpm build 或去掉 --no-build") + return 1 + print("[1/4] 跳过本地构建") + + zip_path = pack_dist_zip(root) + if not zip_path: + return 1 + if not upload_zip_and_extract_to_dist2(cfg, zip_path): + return 1 + try: + os.remove(zip_path) + except Exception: + pass + if not remote_swap_dist(cfg): + return 1 + print("") + print(" 部署完成!站点目录: %s" % cfg["dist_path"]) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/soul-admin/dist/assets/index-BQTdJZ32.js b/soul-admin/dist/assets/index-C2K6IQif.js similarity index 94% rename from soul-admin/dist/assets/index-BQTdJZ32.js rename to soul-admin/dist/assets/index-C2K6IQif.js index a2cea3ce..30faf19c 100644 --- a/soul-admin/dist/assets/index-BQTdJZ32.js +++ b/soul-admin/dist/assets/index-C2K6IQif.js @@ -534,7 +534,7 @@ Error generating stack: `+S.message+` * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. - */const qA=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],aa=Ce("zap",qA),Ox="admin_token";function Dx(){try{return localStorage.getItem(Ox)}catch{return null}}function GA(t){try{localStorage.setItem(Ox,t)}catch{}}function JA(){try{localStorage.removeItem(Ox)}catch{}}const YA="https://soulapi.quwanzhi.com",QA=15e3,$b=6e4,XA=()=>{const t="https://soulapi.quwanzhi.com";return t.length>0?t.replace(/\/$/,""):YA};function fo(t){const e=XA(),n=t.startsWith("/")?t:`/${t}`;return e?`${e}${n}`:n}async function uf(t,e={}){const{data:n,...r}=e,i=fo(t),a=new Headers(r.headers),o=Dx();o&&a.set("Authorization",`Bearer ${o}`),n!=null&&!a.has("Content-Type")&&a.set("Content-Type","application/json");const c=n!=null?JSON.stringify(n):r.body,u=r.timeout??QA,h=new AbortController,f=setTimeout(()=>h.abort(),u),m=await fetch(i,{...r,headers:a,body:c,credentials:"include",signal:h.signal}).finally(()=>clearTimeout(f)),y=(m.headers.get("Content-Type")||"").includes("application/json")?await m.json():m,w=N=>{const b=N,k=((b==null?void 0:b.message)||(b==null?void 0:b.error)||"").toString();(k.includes("可提现金额不足")||k.includes("可提现不足")||k.includes("余额不足"))&&window.dispatchEvent(new CustomEvent("recharge-alert",{detail:k}))};if(!m.ok){w(y);const N=new Error((y==null?void 0:y.error)||`HTTP ${m.status}`);throw N.status=m.status,N.data=y,N}return w(y),y}function Le(t,e){return uf(t,{...e,method:"GET"})}function yt(t,e,n){return uf(t,{...n,method:"POST",data:e})}function It(t,e,n){return uf(t,{...n,method:"PUT",data:e})}function Rs(t,e){return uf(t,{...e,method:"DELETE"})}function ZA(){const[t,e]=v.useState(!1),[n,r]=v.useState("");return v.useEffect(()=>{const i=a=>{const o=a.detail;r(o||"可提现/余额不足,请及时充值商户号"),e(!0)};return window.addEventListener("recharge-alert",i),()=>window.removeEventListener("recharge-alert",i)},[]),t?s.jsxs("div",{className:"flex items-center justify-between gap-4 px-4 py-3 bg-red-900/80 border-b border-red-600/50 text-red-100",role:"alert",children:[s.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[s.jsx(HN,{className:"w-5 h-5 shrink-0 text-red-400"}),s.jsxs("span",{className:"text-sm font-medium",children:[n,s.jsx("span",{className:"ml-2 text-red-300",children:"请及时充值商户号或核对账户后重试。"})]})]}),s.jsx("button",{type:"button",onClick:()=>e(!1),className:"shrink-0 p-1 rounded hover:bg-red-800/50 transition-colors","aria-label":"关闭告警",children:s.jsx(er,{className:"w-4 h-4"})})]}):null}const eI=[{icon:zM,label:"数据概览",href:"/dashboard"},{icon:Xr,label:"内容管理",href:"/content"},{icon:qn,label:"用户管理",href:"/users"},{icon:mM,label:"找伙伴",href:"/find-partner"},{icon:wl,label:"推广中心",href:"/distribution"}];function tI(){const t=ja(),e=ka(),[n,r]=v.useState(!1),[i,a]=v.useState(!1);v.useEffect(()=>{r(!0)},[]),v.useEffect(()=>{if(!n)return;a(!1);let c=!1;return Le("/api/admin").then(u=>{c||(u&&u.success!==!1?a(!0):e("/login",{replace:!0}))}).catch(()=>{c||e("/login",{replace:!0})}),()=>{c=!0}},[n,e]);const o=async()=>{JA();try{await yt("/api/admin/logout",{})}catch{}e("/login",{replace:!0})};return!n||!i?s.jsxs("div",{className:"flex min-h-screen bg-[#0a1628]",children:[s.jsx("div",{className:"w-64 bg-[#0f2137] border-r border-gray-700/50"}),s.jsx("div",{className:"flex-1 flex items-center justify-center",children:s.jsx("div",{className:"text-[#38bdac]",children:"加载中..."})})]}):s.jsxs("div",{className:"flex min-h-screen bg-[#0a1628]",children:[s.jsxs("div",{className:"w-64 bg-[#0f2137] flex flex-col border-r border-gray-700/50 shadow-xl",children:[s.jsxs("div",{className:"p-6 border-b border-gray-700/50",children:[s.jsx("h1",{className:"text-xl font-bold text-[#38bdac]",children:"管理后台"}),s.jsx("p",{className:"text-xs text-gray-400 mt-1",children:"Soul创业派对"})]}),s.jsxs("nav",{className:"flex-1 p-4 space-y-1 overflow-y-auto",children:[eI.map(c=>{const u=t.pathname===c.href;return s.jsxs(wg,{to:c.href,className:`flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${u?"bg-[#38bdac]/20 text-[#38bdac] font-medium":"text-gray-400 hover:bg-gray-700/50 hover:text-white"}`,children:[s.jsx(c.icon,{className:"w-5 h-5 shrink-0"}),s.jsx("span",{className:"text-sm",children:c.label})]},c.href)}),s.jsx("div",{className:"pt-4 mt-4 border-t border-gray-700/50",children:s.jsxs(wg,{to:"/settings",className:`flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${t.pathname==="/settings"?"bg-[#38bdac]/20 text-[#38bdac] font-medium":"text-gray-400 hover:bg-gray-700/50 hover:text-white"}`,children:[s.jsx(io,{className:"w-5 h-5 shrink-0"}),s.jsx("span",{className:"text-sm",children:"系统设置"})]})})]}),s.jsx("div",{className:"p-4 border-t border-gray-700/50 space-y-1",children:s.jsxs("button",{type:"button",onClick:o,className:"w-full flex items-center gap-3 px-4 py-3 text-gray-400 hover:text-white rounded-lg hover:bg-gray-700/50 transition-colors",children:[s.jsx(GM,{className:"w-5 h-5"}),s.jsx("span",{className:"text-sm",children:"退出登录"})]})})]}),s.jsxs("div",{className:"flex-1 overflow-auto bg-[#0a1628] min-w-0 flex flex-col",children:[s.jsx(ZA,{}),s.jsx("div",{className:"w-full min-w-[1024px] min-h-full flex-1",children:s.jsx(fT,{})})]})]})}function Fb(t,e){if(typeof t=="function")return t(e);t!=null&&(t.current=e)}function Lx(...t){return e=>{let n=!1;const r=t.map(i=>{const a=Fb(i,e);return!n&&typeof a=="function"&&(n=!0),a});if(n)return()=>{for(let i=0;i{let{children:a,...o}=r;XN(a)&&typeof ch=="function"&&(a=ch(a._payload));const c=v.Children.toArray(a),u=c.find(aI);if(u){const h=u.props.children,f=c.map(m=>m===u?v.Children.count(h)>1?v.Children.only(null):v.isValidElement(h)?h.props.children:null:m);return s.jsx(e,{...o,ref:i,children:v.isValidElement(h)?v.cloneElement(h,void 0,f):null})}return s.jsx(e,{...o,ref:i,children:a})});return n.displayName=`${t}.Slot`,n}var ej=ZN("Slot");function sI(t){const e=v.forwardRef((n,r)=>{let{children:i,...a}=n;if(XN(i)&&typeof ch=="function"&&(i=ch(i._payload)),v.isValidElement(i)){const o=lI(i),c=oI(a,i.props);return i.type!==v.Fragment&&(c.ref=r?Lx(r,o):o),v.cloneElement(i,c)}return v.Children.count(i)>1?v.Children.only(null):null});return e.displayName=`${t}.SlotClone`,e}var iI=Symbol("radix.slottable");function aI(t){return v.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===iI}function oI(t,e){const n={...e};for(const r in e){const i=t[r],a=e[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...c)=>{const u=a(...c);return i(...c),u}:i&&(n[r]=i):r==="style"?n[r]={...i,...a}:r==="className"&&(n[r]=[i,a].filter(Boolean).join(" "))}return{...t,...n}}function lI(t){var r,i;let e=(r=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:r.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}function tj(t){var e,n,r="";if(typeof t=="string"||typeof t=="number")r+=t;else if(typeof t=="object")if(Array.isArray(t)){var i=t.length;for(e=0;etypeof t=="boolean"?`${t}`:t===0?"0":t,Vb=nj,rj=(t,e)=>n=>{var r;if((e==null?void 0:e.variants)==null)return Vb(t,n==null?void 0:n.class,n==null?void 0:n.className);const{variants:i,defaultVariants:a}=e,o=Object.keys(i).map(h=>{const f=n==null?void 0:n[h],m=a==null?void 0:a[h];if(f===null)return null;const g=Bb(f)||Bb(m);return i[h][g]}),c=n&&Object.entries(n).reduce((h,f)=>{let[m,g]=f;return g===void 0||(h[m]=g),h},{}),u=e==null||(r=e.compoundVariants)===null||r===void 0?void 0:r.reduce((h,f)=>{let{class:m,className:g,...y}=f;return Object.entries(y).every(w=>{let[N,b]=w;return Array.isArray(b)?b.includes({...a,...c}[N]):{...a,...c}[N]===b})?[...h,m,g]:h},[]);return Vb(t,o,u,n==null?void 0:n.class,n==null?void 0:n.className)},cI=(t,e)=>{const n=new Array(t.length+e.length);for(let r=0;r({classGroupId:t,validator:e}),sj=(t=new Map,e=null,n)=>({nextPart:t,validators:e,classGroupId:n}),dh="-",Hb=[],uI="arbitrary..",hI=t=>{const e=pI(t),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=t;return{getClassGroupId:o=>{if(o.startsWith("[")&&o.endsWith("]"))return fI(o);const c=o.split(dh),u=c[0]===""&&c.length>1?1:0;return ij(c,u,e)},getConflictingClassGroupIds:(o,c)=>{if(c){const u=r[o],h=n[o];return u?h?cI(h,u):u:h||Hb}return n[o]||Hb}}},ij=(t,e,n)=>{if(t.length-e===0)return n.classGroupId;const i=t[e],a=n.nextPart.get(i);if(a){const h=ij(t,e+1,a);if(h)return h}const o=n.validators;if(o===null)return;const c=e===0?t.join(dh):t.slice(e).join(dh),u=o.length;for(let h=0;ht.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const e=t.slice(1,-1),n=e.indexOf(":"),r=e.slice(0,n);return r?uI+r:void 0})(),pI=t=>{const{theme:e,classGroups:n}=t;return mI(n,e)},mI=(t,e)=>{const n=sj();for(const r in t){const i=t[r];_x(i,n,r,e)}return n},_x=(t,e,n,r)=>{const i=t.length;for(let a=0;a{if(typeof t=="string"){xI(t,e,n);return}if(typeof t=="function"){yI(t,e,n,r);return}vI(t,e,n,r)},xI=(t,e,n)=>{const r=t===""?e:aj(e,t);r.classGroupId=n},yI=(t,e,n,r)=>{if(bI(t)){_x(t(r),e,n,r);return}e.validators===null&&(e.validators=[]),e.validators.push(dI(n,t))},vI=(t,e,n,r)=>{const i=Object.entries(t),a=i.length;for(let o=0;o{let n=t;const r=e.split(dh),i=r.length;for(let a=0;a"isThemeGetter"in t&&t.isThemeGetter===!0,wI=t=>{if(t<1)return{get:()=>{},set:()=>{}};let e=0,n=Object.create(null),r=Object.create(null);const i=(a,o)=>{n[a]=o,e++,e>t&&(e=0,r=n,n=Object.create(null))};return{get(a){let o=n[a];if(o!==void 0)return o;if((o=r[a])!==void 0)return i(a,o),o},set(a,o){a in n?n[a]=o:i(a,o)}}},Mg="!",Wb=":",NI=[],Ub=(t,e,n,r,i)=>({modifiers:t,hasImportantModifier:e,baseClassName:n,maybePostfixModifierPosition:r,isExternal:i}),jI=t=>{const{prefix:e,experimentalParseClassName:n}=t;let r=i=>{const a=[];let o=0,c=0,u=0,h;const f=i.length;for(let N=0;Nu?h-u:void 0;return Ub(a,y,g,w)};if(e){const i=e+Wb,a=r;r=o=>o.startsWith(i)?a(o.slice(i.length)):Ub(NI,!1,o,void 0,!0)}if(n){const i=r;r=a=>n({className:a,parseClassName:i})}return r},kI=t=>{const e=new Map;return t.orderSensitiveModifiers.forEach((n,r)=>{e.set(n,1e6+r)}),n=>{const r=[];let i=[];for(let a=0;a0&&(i.sort(),r.push(...i),i=[]),r.push(o)):i.push(o)}return i.length>0&&(i.sort(),r.push(...i)),r}},SI=t=>({cache:wI(t.cacheSize),parseClassName:jI(t),sortModifiers:kI(t),...hI(t)}),CI=/\s+/,EI=(t,e)=>{const{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:a}=e,o=[],c=t.trim().split(CI);let u="";for(let h=c.length-1;h>=0;h-=1){const f=c[h],{isExternal:m,modifiers:g,hasImportantModifier:y,baseClassName:w,maybePostfixModifierPosition:N}=n(f);if(m){u=f+(u.length>0?" "+u:u);continue}let b=!!N,k=r(b?w.substring(0,N):w);if(!k){if(!b){u=f+(u.length>0?" "+u:u);continue}if(k=r(w),!k){u=f+(u.length>0?" "+u:u);continue}b=!1}const C=g.length===0?"":g.length===1?g[0]:a(g).join(":"),E=y?C+Mg:C,T=E+k;if(o.indexOf(T)>-1)continue;o.push(T);const I=i(k,b);for(let O=0;O0?" "+u:u)}return u},TI=(...t)=>{let e=0,n,r,i="";for(;e{if(typeof t=="string")return t;let e,n="";for(let r=0;r{let n,r,i,a;const o=u=>{const h=e.reduce((f,m)=>m(f),t());return n=SI(h),r=n.cache.get,i=n.cache.set,a=c,c(u)},c=u=>{const h=r(u);if(h)return h;const f=EI(u,n);return i(u,f),f};return a=o,(...u)=>a(TI(...u))},AI=[],Tn=t=>{const e=n=>n[t]||AI;return e.isThemeGetter=!0,e},lj=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,cj=/^\((?:(\w[\w-]*):)?(.+)\)$/i,II=/^\d+\/\d+$/,RI=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,PI=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,OI=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,DI=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,LI=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,el=t=>II.test(t),ut=t=>!!t&&!Number.isNaN(Number(t)),Gi=t=>!!t&&Number.isInteger(Number(t)),km=t=>t.endsWith("%")&&ut(t.slice(0,-1)),ai=t=>RI.test(t),_I=()=>!0,zI=t=>PI.test(t)&&!OI.test(t),dj=()=>!1,$I=t=>DI.test(t),FI=t=>LI.test(t),BI=t=>!ze(t)&&!$e(t),VI=t=>Rl(t,fj,dj),ze=t=>lj.test(t),Ya=t=>Rl(t,pj,zI),Sm=t=>Rl(t,qI,ut),Kb=t=>Rl(t,uj,dj),HI=t=>Rl(t,hj,FI),ju=t=>Rl(t,mj,$I),$e=t=>cj.test(t),jc=t=>Pl(t,pj),WI=t=>Pl(t,GI),qb=t=>Pl(t,uj),UI=t=>Pl(t,fj),KI=t=>Pl(t,hj),ku=t=>Pl(t,mj,!0),Rl=(t,e,n)=>{const r=lj.exec(t);return r?r[1]?e(r[1]):n(r[2]):!1},Pl=(t,e,n=!1)=>{const r=cj.exec(t);return r?r[1]?e(r[1]):n:!1},uj=t=>t==="position"||t==="percentage",hj=t=>t==="image"||t==="url",fj=t=>t==="length"||t==="size"||t==="bg-size",pj=t=>t==="length",qI=t=>t==="number",GI=t=>t==="family-name",mj=t=>t==="shadow",JI=()=>{const t=Tn("color"),e=Tn("font"),n=Tn("text"),r=Tn("font-weight"),i=Tn("tracking"),a=Tn("leading"),o=Tn("breakpoint"),c=Tn("container"),u=Tn("spacing"),h=Tn("radius"),f=Tn("shadow"),m=Tn("inset-shadow"),g=Tn("text-shadow"),y=Tn("drop-shadow"),w=Tn("blur"),N=Tn("perspective"),b=Tn("aspect"),k=Tn("ease"),C=Tn("animate"),E=()=>["auto","avoid","all","avoid-page","page","left","right","column"],T=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],I=()=>[...T(),$e,ze],O=()=>["auto","hidden","clip","visible","scroll"],D=()=>["auto","contain","none"],P=()=>[$e,ze,u],L=()=>[el,"full","auto",...P()],_=()=>[Gi,"none","subgrid",$e,ze],J=()=>["auto",{span:["full",Gi,$e,ze]},Gi,$e,ze],ee=()=>[Gi,"auto",$e,ze],Y=()=>["auto","min","max","fr",$e,ze],U=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],R=()=>["start","end","center","stretch","center-safe","end-safe"],F=()=>["auto",...P()],re=()=>[el,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...P()],z=()=>[t,$e,ze],ie=()=>[...T(),qb,Kb,{position:[$e,ze]}],G=()=>["no-repeat",{repeat:["","x","y","space","round"]}],$=()=>["auto","cover","contain",UI,VI,{size:[$e,ze]}],V=()=>[km,jc,Ya],ce=()=>["","none","full",h,$e,ze],W=()=>["",ut,jc,Ya],fe=()=>["solid","dashed","dotted","double"],X=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],de=()=>[ut,km,qb,Kb],he=()=>["","none",w,$e,ze],be=()=>["none",ut,$e,ze],Te=()=>["none",ut,$e,ze],Ve=()=>[ut,$e,ze],He=()=>[el,"full",...P()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[ai],breakpoint:[ai],color:[_I],container:[ai],"drop-shadow":[ai],ease:["in","out","in-out"],font:[BI],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[ai],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[ai],shadow:[ai],spacing:["px",ut],text:[ai],"text-shadow":[ai],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",el,ze,$e,b]}],container:["container"],columns:[{columns:[ut,ze,$e,c]}],"break-after":[{"break-after":E()}],"break-before":[{"break-before":E()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:I()}],overflow:[{overflow:O()}],"overflow-x":[{"overflow-x":O()}],"overflow-y":[{"overflow-y":O()}],overscroll:[{overscroll:D()}],"overscroll-x":[{"overscroll-x":D()}],"overscroll-y":[{"overscroll-y":D()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:L()}],"inset-x":[{"inset-x":L()}],"inset-y":[{"inset-y":L()}],start:[{start:L()}],end:[{end:L()}],top:[{top:L()}],right:[{right:L()}],bottom:[{bottom:L()}],left:[{left:L()}],visibility:["visible","invisible","collapse"],z:[{z:[Gi,"auto",$e,ze]}],basis:[{basis:[el,"full","auto",c,...P()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[ut,el,"auto","initial","none",ze]}],grow:[{grow:["",ut,$e,ze]}],shrink:[{shrink:["",ut,$e,ze]}],order:[{order:[Gi,"first","last","none",$e,ze]}],"grid-cols":[{"grid-cols":_()}],"col-start-end":[{col:J()}],"col-start":[{"col-start":ee()}],"col-end":[{"col-end":ee()}],"grid-rows":[{"grid-rows":_()}],"row-start-end":[{row:J()}],"row-start":[{"row-start":ee()}],"row-end":[{"row-end":ee()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":Y()}],"auto-rows":[{"auto-rows":Y()}],gap:[{gap:P()}],"gap-x":[{"gap-x":P()}],"gap-y":[{"gap-y":P()}],"justify-content":[{justify:[...U(),"normal"]}],"justify-items":[{"justify-items":[...R(),"normal"]}],"justify-self":[{"justify-self":["auto",...R()]}],"align-content":[{content:["normal",...U()]}],"align-items":[{items:[...R(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...R(),{baseline:["","last"]}]}],"place-content":[{"place-content":U()}],"place-items":[{"place-items":[...R(),"baseline"]}],"place-self":[{"place-self":["auto",...R()]}],p:[{p:P()}],px:[{px:P()}],py:[{py:P()}],ps:[{ps:P()}],pe:[{pe:P()}],pt:[{pt:P()}],pr:[{pr:P()}],pb:[{pb:P()}],pl:[{pl:P()}],m:[{m:F()}],mx:[{mx:F()}],my:[{my:F()}],ms:[{ms:F()}],me:[{me:F()}],mt:[{mt:F()}],mr:[{mr:F()}],mb:[{mb:F()}],ml:[{ml:F()}],"space-x":[{"space-x":P()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":P()}],"space-y-reverse":["space-y-reverse"],size:[{size:re()}],w:[{w:[c,"screen",...re()]}],"min-w":[{"min-w":[c,"screen","none",...re()]}],"max-w":[{"max-w":[c,"screen","none","prose",{screen:[o]},...re()]}],h:[{h:["screen","lh",...re()]}],"min-h":[{"min-h":["screen","lh","none",...re()]}],"max-h":[{"max-h":["screen","lh",...re()]}],"font-size":[{text:["base",n,jc,Ya]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[r,$e,Sm]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",km,ze]}],"font-family":[{font:[WI,ze,e]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[i,$e,ze]}],"line-clamp":[{"line-clamp":[ut,"none",$e,Sm]}],leading:[{leading:[a,...P()]}],"list-image":[{"list-image":["none",$e,ze]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",$e,ze]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:z()}],"text-color":[{text:z()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...fe(),"wavy"]}],"text-decoration-thickness":[{decoration:[ut,"from-font","auto",$e,Ya]}],"text-decoration-color":[{decoration:z()}],"underline-offset":[{"underline-offset":[ut,"auto",$e,ze]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:P()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",$e,ze]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",$e,ze]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ie()}],"bg-repeat":[{bg:G()}],"bg-size":[{bg:$()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Gi,$e,ze],radial:["",$e,ze],conic:[Gi,$e,ze]},KI,HI]}],"bg-color":[{bg:z()}],"gradient-from-pos":[{from:V()}],"gradient-via-pos":[{via:V()}],"gradient-to-pos":[{to:V()}],"gradient-from":[{from:z()}],"gradient-via":[{via:z()}],"gradient-to":[{to:z()}],rounded:[{rounded:ce()}],"rounded-s":[{"rounded-s":ce()}],"rounded-e":[{"rounded-e":ce()}],"rounded-t":[{"rounded-t":ce()}],"rounded-r":[{"rounded-r":ce()}],"rounded-b":[{"rounded-b":ce()}],"rounded-l":[{"rounded-l":ce()}],"rounded-ss":[{"rounded-ss":ce()}],"rounded-se":[{"rounded-se":ce()}],"rounded-ee":[{"rounded-ee":ce()}],"rounded-es":[{"rounded-es":ce()}],"rounded-tl":[{"rounded-tl":ce()}],"rounded-tr":[{"rounded-tr":ce()}],"rounded-br":[{"rounded-br":ce()}],"rounded-bl":[{"rounded-bl":ce()}],"border-w":[{border:W()}],"border-w-x":[{"border-x":W()}],"border-w-y":[{"border-y":W()}],"border-w-s":[{"border-s":W()}],"border-w-e":[{"border-e":W()}],"border-w-t":[{"border-t":W()}],"border-w-r":[{"border-r":W()}],"border-w-b":[{"border-b":W()}],"border-w-l":[{"border-l":W()}],"divide-x":[{"divide-x":W()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":W()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...fe(),"hidden","none"]}],"divide-style":[{divide:[...fe(),"hidden","none"]}],"border-color":[{border:z()}],"border-color-x":[{"border-x":z()}],"border-color-y":[{"border-y":z()}],"border-color-s":[{"border-s":z()}],"border-color-e":[{"border-e":z()}],"border-color-t":[{"border-t":z()}],"border-color-r":[{"border-r":z()}],"border-color-b":[{"border-b":z()}],"border-color-l":[{"border-l":z()}],"divide-color":[{divide:z()}],"outline-style":[{outline:[...fe(),"none","hidden"]}],"outline-offset":[{"outline-offset":[ut,$e,ze]}],"outline-w":[{outline:["",ut,jc,Ya]}],"outline-color":[{outline:z()}],shadow:[{shadow:["","none",f,ku,ju]}],"shadow-color":[{shadow:z()}],"inset-shadow":[{"inset-shadow":["none",m,ku,ju]}],"inset-shadow-color":[{"inset-shadow":z()}],"ring-w":[{ring:W()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:z()}],"ring-offset-w":[{"ring-offset":[ut,Ya]}],"ring-offset-color":[{"ring-offset":z()}],"inset-ring-w":[{"inset-ring":W()}],"inset-ring-color":[{"inset-ring":z()}],"text-shadow":[{"text-shadow":["none",g,ku,ju]}],"text-shadow-color":[{"text-shadow":z()}],opacity:[{opacity:[ut,$e,ze]}],"mix-blend":[{"mix-blend":[...X(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":X()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[ut]}],"mask-image-linear-from-pos":[{"mask-linear-from":de()}],"mask-image-linear-to-pos":[{"mask-linear-to":de()}],"mask-image-linear-from-color":[{"mask-linear-from":z()}],"mask-image-linear-to-color":[{"mask-linear-to":z()}],"mask-image-t-from-pos":[{"mask-t-from":de()}],"mask-image-t-to-pos":[{"mask-t-to":de()}],"mask-image-t-from-color":[{"mask-t-from":z()}],"mask-image-t-to-color":[{"mask-t-to":z()}],"mask-image-r-from-pos":[{"mask-r-from":de()}],"mask-image-r-to-pos":[{"mask-r-to":de()}],"mask-image-r-from-color":[{"mask-r-from":z()}],"mask-image-r-to-color":[{"mask-r-to":z()}],"mask-image-b-from-pos":[{"mask-b-from":de()}],"mask-image-b-to-pos":[{"mask-b-to":de()}],"mask-image-b-from-color":[{"mask-b-from":z()}],"mask-image-b-to-color":[{"mask-b-to":z()}],"mask-image-l-from-pos":[{"mask-l-from":de()}],"mask-image-l-to-pos":[{"mask-l-to":de()}],"mask-image-l-from-color":[{"mask-l-from":z()}],"mask-image-l-to-color":[{"mask-l-to":z()}],"mask-image-x-from-pos":[{"mask-x-from":de()}],"mask-image-x-to-pos":[{"mask-x-to":de()}],"mask-image-x-from-color":[{"mask-x-from":z()}],"mask-image-x-to-color":[{"mask-x-to":z()}],"mask-image-y-from-pos":[{"mask-y-from":de()}],"mask-image-y-to-pos":[{"mask-y-to":de()}],"mask-image-y-from-color":[{"mask-y-from":z()}],"mask-image-y-to-color":[{"mask-y-to":z()}],"mask-image-radial":[{"mask-radial":[$e,ze]}],"mask-image-radial-from-pos":[{"mask-radial-from":de()}],"mask-image-radial-to-pos":[{"mask-radial-to":de()}],"mask-image-radial-from-color":[{"mask-radial-from":z()}],"mask-image-radial-to-color":[{"mask-radial-to":z()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":T()}],"mask-image-conic-pos":[{"mask-conic":[ut]}],"mask-image-conic-from-pos":[{"mask-conic-from":de()}],"mask-image-conic-to-pos":[{"mask-conic-to":de()}],"mask-image-conic-from-color":[{"mask-conic-from":z()}],"mask-image-conic-to-color":[{"mask-conic-to":z()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ie()}],"mask-repeat":[{mask:G()}],"mask-size":[{mask:$()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",$e,ze]}],filter:[{filter:["","none",$e,ze]}],blur:[{blur:he()}],brightness:[{brightness:[ut,$e,ze]}],contrast:[{contrast:[ut,$e,ze]}],"drop-shadow":[{"drop-shadow":["","none",y,ku,ju]}],"drop-shadow-color":[{"drop-shadow":z()}],grayscale:[{grayscale:["",ut,$e,ze]}],"hue-rotate":[{"hue-rotate":[ut,$e,ze]}],invert:[{invert:["",ut,$e,ze]}],saturate:[{saturate:[ut,$e,ze]}],sepia:[{sepia:["",ut,$e,ze]}],"backdrop-filter":[{"backdrop-filter":["","none",$e,ze]}],"backdrop-blur":[{"backdrop-blur":he()}],"backdrop-brightness":[{"backdrop-brightness":[ut,$e,ze]}],"backdrop-contrast":[{"backdrop-contrast":[ut,$e,ze]}],"backdrop-grayscale":[{"backdrop-grayscale":["",ut,$e,ze]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[ut,$e,ze]}],"backdrop-invert":[{"backdrop-invert":["",ut,$e,ze]}],"backdrop-opacity":[{"backdrop-opacity":[ut,$e,ze]}],"backdrop-saturate":[{"backdrop-saturate":[ut,$e,ze]}],"backdrop-sepia":[{"backdrop-sepia":["",ut,$e,ze]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":P()}],"border-spacing-x":[{"border-spacing-x":P()}],"border-spacing-y":[{"border-spacing-y":P()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",$e,ze]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[ut,"initial",$e,ze]}],ease:[{ease:["linear","initial",k,$e,ze]}],delay:[{delay:[ut,$e,ze]}],animate:[{animate:["none",C,$e,ze]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[N,$e,ze]}],"perspective-origin":[{"perspective-origin":I()}],rotate:[{rotate:be()}],"rotate-x":[{"rotate-x":be()}],"rotate-y":[{"rotate-y":be()}],"rotate-z":[{"rotate-z":be()}],scale:[{scale:Te()}],"scale-x":[{"scale-x":Te()}],"scale-y":[{"scale-y":Te()}],"scale-z":[{"scale-z":Te()}],"scale-3d":["scale-3d"],skew:[{skew:Ve()}],"skew-x":[{"skew-x":Ve()}],"skew-y":[{"skew-y":Ve()}],transform:[{transform:[$e,ze,"","none","gpu","cpu"]}],"transform-origin":[{origin:I()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:He()}],"translate-x":[{"translate-x":He()}],"translate-y":[{"translate-y":He()}],"translate-z":[{"translate-z":He()}],"translate-none":["translate-none"],accent:[{accent:z()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:z()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",$e,ze]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":P()}],"scroll-mx":[{"scroll-mx":P()}],"scroll-my":[{"scroll-my":P()}],"scroll-ms":[{"scroll-ms":P()}],"scroll-me":[{"scroll-me":P()}],"scroll-mt":[{"scroll-mt":P()}],"scroll-mr":[{"scroll-mr":P()}],"scroll-mb":[{"scroll-mb":P()}],"scroll-ml":[{"scroll-ml":P()}],"scroll-p":[{"scroll-p":P()}],"scroll-px":[{"scroll-px":P()}],"scroll-py":[{"scroll-py":P()}],"scroll-ps":[{"scroll-ps":P()}],"scroll-pe":[{"scroll-pe":P()}],"scroll-pt":[{"scroll-pt":P()}],"scroll-pr":[{"scroll-pr":P()}],"scroll-pb":[{"scroll-pb":P()}],"scroll-pl":[{"scroll-pl":P()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",$e,ze]}],fill:[{fill:["none",...z()]}],"stroke-w":[{stroke:[ut,jc,Ya,Sm]}],stroke:[{stroke:["none",...z()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},YI=MI(JI);function Mt(...t){return YI(nj(t))}const QI=rj("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-white hover:bg-destructive/90",outline:"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2 has-[>svg]:px-3",sm:"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",lg:"h-10 rounded-md px-6 has-[>svg]:px-4",icon:"size-9","icon-sm":"size-8","icon-lg":"size-10"}},defaultVariants:{variant:"default",size:"default"}});function te({className:t,variant:e,size:n,asChild:r=!1,...i}){const a=r?ej:"button";return s.jsx(a,{"data-slot":"button",className:Mt(QI({variant:e,size:n,className:t})),...i})}function oe({className:t,type:e,...n}){return s.jsx("input",{type:e,"data-slot":"input",className:Mt("h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 md:text-sm focus-visible:ring-2 focus-visible:ring-ring",t),...n})}function XI(){const t=ka(),[e,n]=v.useState(""),[r,i]=v.useState(""),[a,o]=v.useState(""),[c,u]=v.useState(!1),h=async()=>{o(""),u(!0);try{const f=await yt("/api/admin",{username:e.trim(),password:r});if((f==null?void 0:f.success)!==!1&&(f!=null&&f.token)){GA(f.token),t("/dashboard",{replace:!0});return}o(f.error||"用户名或密码错误")}catch(f){const m=f;o(m.status===401?"用户名或密码错误":(m==null?void 0:m.message)||"网络错误,请重试")}finally{u(!1)}};return s.jsxs("div",{className:"min-h-screen bg-[#0a1628] flex items-center justify-center p-4",children:[s.jsxs("div",{className:"absolute inset-0 overflow-hidden",children:[s.jsx("div",{className:"absolute top-1/4 left-1/4 w-96 h-96 bg-[#38bdac]/5 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-1/4 right-1/4 w-96 h-96 bg-blue-500/5 rounded-full blur-3xl"})]}),s.jsxs("div",{className:"w-full max-w-md relative z-10",children:[s.jsxs("div",{className:"text-center mb-8",children:[s.jsx("div",{className:"w-16 h-16 bg-[#38bdac]/20 rounded-2xl flex items-center justify-center mx-auto mb-4 border border-[#38bdac]/30",children:s.jsx(Px,{className:"w-8 h-8 text-[#38bdac]"})}),s.jsx("h1",{className:"text-2xl font-bold text-white mb-2",children:"管理后台"}),s.jsx("p",{className:"text-gray-400",children:"一场SOUL的创业实验场"})]}),s.jsxs("div",{className:"bg-[#0f2137] rounded-2xl p-8 shadow-xl border border-gray-700/50 backdrop-blur-xl",children:[s.jsx("h2",{className:"text-xl font-semibold text-white mb-6 text-center",children:"管理员登录"}),s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"block text-gray-400 text-sm mb-2",children:"用户名"}),s.jsxs("div",{className:"relative",children:[s.jsx(gl,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500"}),s.jsx(oe,{type:"text",value:e,onChange:f=>n(f.target.value),placeholder:"请输入用户名",className:"pl-10 bg-[#0a1628] border-gray-700 text-white placeholder:text-gray-500 focus:border-[#38bdac]"})]})]}),s.jsxs("div",{children:[s.jsx("label",{className:"block text-gray-400 text-sm mb-2",children:"密码"}),s.jsxs("div",{className:"relative",children:[s.jsx(KM,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500"}),s.jsx(oe,{type:"password",value:r,onChange:f=>i(f.target.value),placeholder:"请输入密码",className:"pl-10 bg-[#0a1628] border-gray-700 text-white placeholder:text-gray-500 focus:border-[#38bdac]",onKeyDown:f=>f.key==="Enter"&&h()})]})]}),a&&s.jsx("div",{className:"bg-red-500/10 text-red-400 text-sm p-3 rounded-lg border border-red-500/20",children:a}),s.jsx(te,{onClick:h,disabled:c,className:"w-full bg-[#38bdac] hover:bg-[#2da396] text-white py-5 disabled:opacity-50",children:c?"登录中...":"登录"})]})]}),s.jsx("p",{className:"text-center text-gray-500 text-xs mt-6",children:"Soul创业实验场 · 后台管理系统"})]})]})}const Me=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("rounded-xl border bg-card text-card-foreground shadow",t),...e}));Me.displayName="Card";const rt=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("flex flex-col space-y-1.5 p-6",t),...e}));rt.displayName="CardHeader";const st=v.forwardRef(({className:t,...e},n)=>s.jsx("h3",{ref:n,className:Mt("font-semibold leading-none tracking-tight",t),...e}));st.displayName="CardTitle";const Vt=v.forwardRef(({className:t,...e},n)=>s.jsx("p",{ref:n,className:Mt("text-sm text-muted-foreground",t),...e}));Vt.displayName="CardDescription";const Ae=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("p-6 pt-0",t),...e}));Ae.displayName="CardContent";const ZI=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("flex items-center p-6 pt-0",t),...e}));ZI.displayName="CardFooter";const e5={success:{bg:"#f0fdf4",border:"#22c55e",icon:"✓"},error:{bg:"#fef2f2",border:"#ef4444",icon:"✕"},info:{bg:"#eff6ff",border:"#3b82f6",icon:"ℹ"}};function Cm(t,e="info",n=3e3){const r=`toast-${Date.now()}`,i=e5[e],a=document.createElement("div");a.id=r,a.setAttribute("role","alert"),Object.assign(a.style,{position:"fixed",top:"24px",right:"24px",zIndex:"9999",display:"flex",alignItems:"center",gap:"10px",padding:"12px 18px",borderRadius:"10px",background:i.bg,border:`1.5px solid ${i.border}`,boxShadow:"0 4px 20px rgba(0,0,0,.12)",fontSize:"14px",color:"#1a1a1a",fontWeight:"500",maxWidth:"380px",lineHeight:"1.5",opacity:"0",transform:"translateY(-8px)",transition:"opacity .22s ease, transform .22s ease",pointerEvents:"none"});const o=document.createElement("span");Object.assign(o.style,{width:"20px",height:"20px",borderRadius:"50%",background:i.border,color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"12px",fontWeight:"700",flexShrink:"0"}),o.textContent=i.icon;const c=document.createElement("span");c.textContent=t,a.appendChild(o),a.appendChild(c),document.body.appendChild(a),requestAnimationFrame(()=>{a.style.opacity="1",a.style.transform="translateY(0)"});const u=setTimeout(()=>h(r),n);function h(f){clearTimeout(u);const m=document.getElementById(f);m&&(m.style.opacity="0",m.style.transform="translateY(-8px)",setTimeout(()=>{var g;return(g=m.parentNode)==null?void 0:g.removeChild(m)},250))}}const ae={success:(t,e)=>Cm(t,"success",e),error:(t,e)=>Cm(t,"error",e),info:(t,e)=>Cm(t,"info",e)};function ot(t,e,{checkForDefaultPrevented:n=!0}={}){return function(i){if(t==null||t(i),n===!1||!i.defaultPrevented)return e==null?void 0:e(i)}}function t5(t,e){const n=v.createContext(e),r=a=>{const{children:o,...c}=a,u=v.useMemo(()=>c,Object.values(c));return s.jsx(n.Provider,{value:u,children:o})};r.displayName=t+"Provider";function i(a){const o=v.useContext(n);if(o)return o;if(e!==void 0)return e;throw new Error(`\`${a}\` must be used within \`${t}\``)}return[r,i]}function Sa(t,e=[]){let n=[];function r(a,o){const c=v.createContext(o),u=n.length;n=[...n,o];const h=m=>{var k;const{scope:g,children:y,...w}=m,N=((k=g==null?void 0:g[t])==null?void 0:k[u])||c,b=v.useMemo(()=>w,Object.values(w));return s.jsx(N.Provider,{value:b,children:y})};h.displayName=a+"Provider";function f(m,g){var N;const y=((N=g==null?void 0:g[t])==null?void 0:N[u])||c,w=v.useContext(y);if(w)return w;if(o!==void 0)return o;throw new Error(`\`${m}\` must be used within \`${a}\``)}return[h,f]}const i=()=>{const a=n.map(o=>v.createContext(o));return function(c){const u=(c==null?void 0:c[t])||a;return v.useMemo(()=>({[`__scope${t}`]:{...c,[t]:u}}),[c,u])}};return i.scopeName=t,[r,n5(i,...e)]}function n5(...t){const e=t[0];if(t.length===1)return e;const n=()=>{const r=t.map(i=>({useScope:i(),scopeName:i.scopeName}));return function(a){const o=r.reduce((c,{useScope:u,scopeName:h})=>{const m=u(a)[`__scope${h}`];return{...c,...m}},{});return v.useMemo(()=>({[`__scope${e.scopeName}`]:o}),[o])}};return n.scopeName=e.scopeName,n}var tr=globalThis!=null&&globalThis.document?v.useLayoutEffect:()=>{},r5=lf[" useId ".trim().toString()]||(()=>{}),s5=0;function ha(t){const[e,n]=v.useState(r5());return tr(()=>{n(r=>r??String(s5++))},[t]),e?`radix-${e}`:""}var i5=lf[" useInsertionEffect ".trim().toString()]||tr;function po({prop:t,defaultProp:e,onChange:n=()=>{},caller:r}){const[i,a,o]=a5({defaultProp:e,onChange:n}),c=t!==void 0,u=c?t:i;{const f=v.useRef(t!==void 0);v.useEffect(()=>{const m=f.current;m!==c&&console.warn(`${r} is changing from ${m?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=c},[c,r])}const h=v.useCallback(f=>{var m;if(c){const g=o5(f)?f(t):f;g!==t&&((m=o.current)==null||m.call(o,g))}else a(f)},[c,t,a,o]);return[u,h]}function a5({defaultProp:t,onChange:e}){const[n,r]=v.useState(t),i=v.useRef(n),a=v.useRef(e);return i5(()=>{a.current=e},[e]),v.useEffect(()=>{var o;i.current!==n&&((o=a.current)==null||o.call(a,n),i.current=n)},[n,i]),[n,r,a]}function o5(t){return typeof t=="function"}function Yc(t){const e=l5(t),n=v.forwardRef((r,i)=>{const{children:a,...o}=r,c=v.Children.toArray(a),u=c.find(d5);if(u){const h=u.props.children,f=c.map(m=>m===u?v.Children.count(h)>1?v.Children.only(null):v.isValidElement(h)?h.props.children:null:m);return s.jsx(e,{...o,ref:i,children:v.isValidElement(h)?v.cloneElement(h,void 0,f):null})}return s.jsx(e,{...o,ref:i,children:a})});return n.displayName=`${t}.Slot`,n}function l5(t){const e=v.forwardRef((n,r)=>{const{children:i,...a}=n;if(v.isValidElement(i)){const o=h5(i),c=u5(a,i.props);return i.type!==v.Fragment&&(c.ref=r?Lx(r,o):o),v.cloneElement(i,c)}return v.Children.count(i)>1?v.Children.only(null):null});return e.displayName=`${t}.SlotClone`,e}var c5=Symbol("radix.slottable");function d5(t){return v.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===c5}function u5(t,e){const n={...e};for(const r in e){const i=t[r],a=e[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...c)=>{const u=a(...c);return i(...c),u}:i&&(n[r]=i):r==="style"?n[r]={...i,...a}:r==="className"&&(n[r]=[i,a].filter(Boolean).join(" "))}return{...t,...n}}function h5(t){var r,i;let e=(r=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:r.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}var f5=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],ht=f5.reduce((t,e)=>{const n=Yc(`Primitive.${e}`),r=v.forwardRef((i,a)=>{const{asChild:o,...c}=i,u=o?n:e;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),s.jsx(u,{...c,ref:a})});return r.displayName=`Primitive.${e}`,{...t,[e]:r}},{});function p5(t,e){t&&ud.flushSync(()=>t.dispatchEvent(e))}function xa(t){const e=v.useRef(t);return v.useEffect(()=>{e.current=t}),v.useMemo(()=>(...n)=>{var r;return(r=e.current)==null?void 0:r.call(e,...n)},[])}function m5(t,e=globalThis==null?void 0:globalThis.document){const n=xa(t);v.useEffect(()=>{const r=i=>{i.key==="Escape"&&n(i)};return e.addEventListener("keydown",r,{capture:!0}),()=>e.removeEventListener("keydown",r,{capture:!0})},[n,e])}var g5="DismissableLayer",Ag="dismissableLayer.update",x5="dismissableLayer.pointerDownOutside",y5="dismissableLayer.focusOutside",Gb,gj=v.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),zx=v.forwardRef((t,e)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:i,onFocusOutside:a,onInteractOutside:o,onDismiss:c,...u}=t,h=v.useContext(gj),[f,m]=v.useState(null),g=(f==null?void 0:f.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,y]=v.useState({}),w=Tt(e,D=>m(D)),N=Array.from(h.layers),[b]=[...h.layersWithOutsidePointerEventsDisabled].slice(-1),k=N.indexOf(b),C=f?N.indexOf(f):-1,E=h.layersWithOutsidePointerEventsDisabled.size>0,T=C>=k,I=w5(D=>{const P=D.target,L=[...h.branches].some(_=>_.contains(P));!T||L||(i==null||i(D),o==null||o(D),D.defaultPrevented||c==null||c())},g),O=N5(D=>{const P=D.target;[...h.branches].some(_=>_.contains(P))||(a==null||a(D),o==null||o(D),D.defaultPrevented||c==null||c())},g);return m5(D=>{C===h.layers.size-1&&(r==null||r(D),!D.defaultPrevented&&c&&(D.preventDefault(),c()))},g),v.useEffect(()=>{if(f)return n&&(h.layersWithOutsidePointerEventsDisabled.size===0&&(Gb=g.body.style.pointerEvents,g.body.style.pointerEvents="none"),h.layersWithOutsidePointerEventsDisabled.add(f)),h.layers.add(f),Jb(),()=>{n&&h.layersWithOutsidePointerEventsDisabled.size===1&&(g.body.style.pointerEvents=Gb)}},[f,g,n,h]),v.useEffect(()=>()=>{f&&(h.layers.delete(f),h.layersWithOutsidePointerEventsDisabled.delete(f),Jb())},[f,h]),v.useEffect(()=>{const D=()=>y({});return document.addEventListener(Ag,D),()=>document.removeEventListener(Ag,D)},[]),s.jsx(ht.div,{...u,ref:w,style:{pointerEvents:E?T?"auto":"none":void 0,...t.style},onFocusCapture:ot(t.onFocusCapture,O.onFocusCapture),onBlurCapture:ot(t.onBlurCapture,O.onBlurCapture),onPointerDownCapture:ot(t.onPointerDownCapture,I.onPointerDownCapture)})});zx.displayName=g5;var v5="DismissableLayerBranch",b5=v.forwardRef((t,e)=>{const n=v.useContext(gj),r=v.useRef(null),i=Tt(e,r);return v.useEffect(()=>{const a=r.current;if(a)return n.branches.add(a),()=>{n.branches.delete(a)}},[n.branches]),s.jsx(ht.div,{...t,ref:i})});b5.displayName=v5;function w5(t,e=globalThis==null?void 0:globalThis.document){const n=xa(t),r=v.useRef(!1),i=v.useRef(()=>{});return v.useEffect(()=>{const a=c=>{if(c.target&&!r.current){let u=function(){xj(x5,n,h,{discrete:!0})};const h={originalEvent:c};c.pointerType==="touch"?(e.removeEventListener("click",i.current),i.current=u,e.addEventListener("click",i.current,{once:!0})):u()}else e.removeEventListener("click",i.current);r.current=!1},o=window.setTimeout(()=>{e.addEventListener("pointerdown",a)},0);return()=>{window.clearTimeout(o),e.removeEventListener("pointerdown",a),e.removeEventListener("click",i.current)}},[e,n]),{onPointerDownCapture:()=>r.current=!0}}function N5(t,e=globalThis==null?void 0:globalThis.document){const n=xa(t),r=v.useRef(!1);return v.useEffect(()=>{const i=a=>{a.target&&!r.current&&xj(y5,n,{originalEvent:a},{discrete:!1})};return e.addEventListener("focusin",i),()=>e.removeEventListener("focusin",i)},[e,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function Jb(){const t=new CustomEvent(Ag);document.dispatchEvent(t)}function xj(t,e,n,{discrete:r}){const i=n.originalEvent.target,a=new CustomEvent(t,{bubbles:!1,cancelable:!0,detail:n});e&&i.addEventListener(t,e,{once:!0}),r?p5(i,a):i.dispatchEvent(a)}var Em="focusScope.autoFocusOnMount",Tm="focusScope.autoFocusOnUnmount",Yb={bubbles:!1,cancelable:!0},j5="FocusScope",$x=v.forwardRef((t,e)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=t,[c,u]=v.useState(null),h=xa(i),f=xa(a),m=v.useRef(null),g=Tt(e,N=>u(N)),y=v.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;v.useEffect(()=>{if(r){let N=function(E){if(y.paused||!c)return;const T=E.target;c.contains(T)?m.current=T:Qi(m.current,{select:!0})},b=function(E){if(y.paused||!c)return;const T=E.relatedTarget;T!==null&&(c.contains(T)||Qi(m.current,{select:!0}))},k=function(E){if(document.activeElement===document.body)for(const I of E)I.removedNodes.length>0&&Qi(c)};document.addEventListener("focusin",N),document.addEventListener("focusout",b);const C=new MutationObserver(k);return c&&C.observe(c,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",N),document.removeEventListener("focusout",b),C.disconnect()}}},[r,c,y.paused]),v.useEffect(()=>{if(c){Xb.add(y);const N=document.activeElement;if(!c.contains(N)){const k=new CustomEvent(Em,Yb);c.addEventListener(Em,h),c.dispatchEvent(k),k.defaultPrevented||(k5(M5(yj(c)),{select:!0}),document.activeElement===N&&Qi(c))}return()=>{c.removeEventListener(Em,h),setTimeout(()=>{const k=new CustomEvent(Tm,Yb);c.addEventListener(Tm,f),c.dispatchEvent(k),k.defaultPrevented||Qi(N??document.body,{select:!0}),c.removeEventListener(Tm,f),Xb.remove(y)},0)}}},[c,h,f,y]);const w=v.useCallback(N=>{if(!n&&!r||y.paused)return;const b=N.key==="Tab"&&!N.altKey&&!N.ctrlKey&&!N.metaKey,k=document.activeElement;if(b&&k){const C=N.currentTarget,[E,T]=S5(C);E&&T?!N.shiftKey&&k===T?(N.preventDefault(),n&&Qi(E,{select:!0})):N.shiftKey&&k===E&&(N.preventDefault(),n&&Qi(T,{select:!0})):k===C&&N.preventDefault()}},[n,r,y.paused]);return s.jsx(ht.div,{tabIndex:-1,...o,ref:g,onKeyDown:w})});$x.displayName=j5;function k5(t,{select:e=!1}={}){const n=document.activeElement;for(const r of t)if(Qi(r,{select:e}),document.activeElement!==n)return}function S5(t){const e=yj(t),n=Qb(e,t),r=Qb(e.reverse(),t);return[n,r]}function yj(t){const e=[],n=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const i=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||i?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)e.push(n.currentNode);return e}function Qb(t,e){for(const n of t)if(!C5(n,{upTo:e}))return n}function C5(t,{upTo:e}){if(getComputedStyle(t).visibility==="hidden")return!0;for(;t;){if(e!==void 0&&t===e)return!1;if(getComputedStyle(t).display==="none")return!0;t=t.parentElement}return!1}function E5(t){return t instanceof HTMLInputElement&&"select"in t}function Qi(t,{select:e=!1}={}){if(t&&t.focus){const n=document.activeElement;t.focus({preventScroll:!0}),t!==n&&E5(t)&&e&&t.select()}}var Xb=T5();function T5(){let t=[];return{add(e){const n=t[0];e!==n&&(n==null||n.pause()),t=Zb(t,e),t.unshift(e)},remove(e){var n;t=Zb(t,e),(n=t[0])==null||n.resume()}}}function Zb(t,e){const n=[...t],r=n.indexOf(e);return r!==-1&&n.splice(r,1),n}function M5(t){return t.filter(e=>e.tagName!=="A")}var A5="Portal",Fx=v.forwardRef((t,e)=>{var c;const{container:n,...r}=t,[i,a]=v.useState(!1);tr(()=>a(!0),[]);const o=n||i&&((c=globalThis==null?void 0:globalThis.document)==null?void 0:c.body);return o?AN.createPortal(s.jsx(ht.div,{...r,ref:e}),o):null});Fx.displayName=A5;function I5(t,e){return v.useReducer((n,r)=>e[n][r]??n,t)}var hd=t=>{const{present:e,children:n}=t,r=R5(e),i=typeof n=="function"?n({present:r.isPresent}):v.Children.only(n),a=Tt(r.ref,P5(i));return typeof n=="function"||r.isPresent?v.cloneElement(i,{ref:a}):null};hd.displayName="Presence";function R5(t){const[e,n]=v.useState(),r=v.useRef(null),i=v.useRef(t),a=v.useRef("none"),o=t?"mounted":"unmounted",[c,u]=I5(o,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return v.useEffect(()=>{const h=Su(r.current);a.current=c==="mounted"?h:"none"},[c]),tr(()=>{const h=r.current,f=i.current;if(f!==t){const g=a.current,y=Su(h);t?u("MOUNT"):y==="none"||(h==null?void 0:h.display)==="none"?u("UNMOUNT"):u(f&&g!==y?"ANIMATION_OUT":"UNMOUNT"),i.current=t}},[t,u]),tr(()=>{if(e){let h;const f=e.ownerDocument.defaultView??window,m=y=>{const N=Su(r.current).includes(CSS.escape(y.animationName));if(y.target===e&&N&&(u("ANIMATION_END"),!i.current)){const b=e.style.animationFillMode;e.style.animationFillMode="forwards",h=f.setTimeout(()=>{e.style.animationFillMode==="forwards"&&(e.style.animationFillMode=b)})}},g=y=>{y.target===e&&(a.current=Su(r.current))};return e.addEventListener("animationstart",g),e.addEventListener("animationcancel",m),e.addEventListener("animationend",m),()=>{f.clearTimeout(h),e.removeEventListener("animationstart",g),e.removeEventListener("animationcancel",m),e.removeEventListener("animationend",m)}}else u("ANIMATION_END")},[e,u]),{isPresent:["mounted","unmountSuspended"].includes(c),ref:v.useCallback(h=>{r.current=h?getComputedStyle(h):null,n(h)},[])}}function Su(t){return(t==null?void 0:t.animationName)||"none"}function P5(t){var r,i;let e=(r=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:r.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}var Mm=0;function vj(){v.useEffect(()=>{const t=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",t[0]??e1()),document.body.insertAdjacentElement("beforeend",t[1]??e1()),Mm++,()=>{Mm===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(e=>e.remove()),Mm--}},[])}function e1(){const t=document.createElement("span");return t.setAttribute("data-radix-focus-guard",""),t.tabIndex=0,t.style.outline="none",t.style.opacity="0",t.style.position="fixed",t.style.pointerEvents="none",t}var Ps=function(){return Ps=Object.assign||function(e){for(var n,r=1,i=arguments.length;r"u")return Y5;var e=Q5(t),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:e[0],top:e[1],right:e[2],gap:Math.max(0,r-n+e[2]-e[0])}},Z5=jj(),xl="data-scroll-locked",eR=function(t,e,n,r){var i=t.left,a=t.top,o=t.right,c=t.gap;return n===void 0&&(n="margin"),` + */const qA=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],aa=Ce("zap",qA),Ox="admin_token";function Dx(){try{return localStorage.getItem(Ox)}catch{return null}}function GA(t){try{localStorage.setItem(Ox,t)}catch{}}function JA(){try{localStorage.removeItem(Ox)}catch{}}const YA="https://soulapi.quwanzhi.com",QA=15e3,$b=6e4,XA=()=>{const t="http://localhost:8080";return t.length>0?t.replace(/\/$/,""):YA};function fo(t){const e=XA(),n=t.startsWith("/")?t:`/${t}`;return e?`${e}${n}`:n}async function uf(t,e={}){const{data:n,...r}=e,i=fo(t),a=new Headers(r.headers),o=Dx();o&&a.set("Authorization",`Bearer ${o}`),n!=null&&!a.has("Content-Type")&&a.set("Content-Type","application/json");const c=n!=null?JSON.stringify(n):r.body,u=r.timeout??QA,h=new AbortController,f=setTimeout(()=>h.abort(),u),m=await fetch(i,{...r,headers:a,body:c,credentials:"include",signal:h.signal}).finally(()=>clearTimeout(f)),y=(m.headers.get("Content-Type")||"").includes("application/json")?await m.json():m,w=N=>{const b=N,k=((b==null?void 0:b.message)||(b==null?void 0:b.error)||"").toString();(k.includes("可提现金额不足")||k.includes("可提现不足")||k.includes("余额不足"))&&window.dispatchEvent(new CustomEvent("recharge-alert",{detail:k}))};if(!m.ok){w(y);const N=new Error((y==null?void 0:y.error)||`HTTP ${m.status}`);throw N.status=m.status,N.data=y,N}return w(y),y}function Le(t,e){return uf(t,{...e,method:"GET"})}function yt(t,e,n){return uf(t,{...n,method:"POST",data:e})}function It(t,e,n){return uf(t,{...n,method:"PUT",data:e})}function Rs(t,e){return uf(t,{...e,method:"DELETE"})}function ZA(){const[t,e]=v.useState(!1),[n,r]=v.useState("");return v.useEffect(()=>{const i=a=>{const o=a.detail;r(o||"可提现/余额不足,请及时充值商户号"),e(!0)};return window.addEventListener("recharge-alert",i),()=>window.removeEventListener("recharge-alert",i)},[]),t?s.jsxs("div",{className:"flex items-center justify-between gap-4 px-4 py-3 bg-red-900/80 border-b border-red-600/50 text-red-100",role:"alert",children:[s.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[s.jsx(HN,{className:"w-5 h-5 shrink-0 text-red-400"}),s.jsxs("span",{className:"text-sm font-medium",children:[n,s.jsx("span",{className:"ml-2 text-red-300",children:"请及时充值商户号或核对账户后重试。"})]})]}),s.jsx("button",{type:"button",onClick:()=>e(!1),className:"shrink-0 p-1 rounded hover:bg-red-800/50 transition-colors","aria-label":"关闭告警",children:s.jsx(er,{className:"w-4 h-4"})})]}):null}const eI=[{icon:zM,label:"数据概览",href:"/dashboard"},{icon:Xr,label:"内容管理",href:"/content"},{icon:qn,label:"用户管理",href:"/users"},{icon:mM,label:"找伙伴",href:"/find-partner"},{icon:wl,label:"推广中心",href:"/distribution"}];function tI(){const t=ja(),e=ka(),[n,r]=v.useState(!1),[i,a]=v.useState(!1);v.useEffect(()=>{r(!0)},[]),v.useEffect(()=>{if(!n)return;a(!1);let c=!1;return Le("/api/admin").then(u=>{c||(u&&u.success!==!1?a(!0):e("/login",{replace:!0}))}).catch(()=>{c||e("/login",{replace:!0})}),()=>{c=!0}},[n,e]);const o=async()=>{JA();try{await yt("/api/admin/logout",{})}catch{}e("/login",{replace:!0})};return!n||!i?s.jsxs("div",{className:"flex min-h-screen bg-[#0a1628]",children:[s.jsx("div",{className:"w-64 bg-[#0f2137] border-r border-gray-700/50"}),s.jsx("div",{className:"flex-1 flex items-center justify-center",children:s.jsx("div",{className:"text-[#38bdac]",children:"加载中..."})})]}):s.jsxs("div",{className:"flex min-h-screen bg-[#0a1628]",children:[s.jsxs("div",{className:"w-64 bg-[#0f2137] flex flex-col border-r border-gray-700/50 shadow-xl",children:[s.jsxs("div",{className:"p-6 border-b border-gray-700/50",children:[s.jsx("h1",{className:"text-xl font-bold text-[#38bdac]",children:"管理后台"}),s.jsx("p",{className:"text-xs text-gray-400 mt-1",children:"Soul创业派对"})]}),s.jsxs("nav",{className:"flex-1 p-4 space-y-1 overflow-y-auto",children:[eI.map(c=>{const u=t.pathname===c.href;return s.jsxs(wg,{to:c.href,className:`flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${u?"bg-[#38bdac]/20 text-[#38bdac] font-medium":"text-gray-400 hover:bg-gray-700/50 hover:text-white"}`,children:[s.jsx(c.icon,{className:"w-5 h-5 shrink-0"}),s.jsx("span",{className:"text-sm",children:c.label})]},c.href)}),s.jsx("div",{className:"pt-4 mt-4 border-t border-gray-700/50",children:s.jsxs(wg,{to:"/settings",className:`flex items-center gap-3 px-4 py-3 rounded-lg transition-colors ${t.pathname==="/settings"?"bg-[#38bdac]/20 text-[#38bdac] font-medium":"text-gray-400 hover:bg-gray-700/50 hover:text-white"}`,children:[s.jsx(io,{className:"w-5 h-5 shrink-0"}),s.jsx("span",{className:"text-sm",children:"系统设置"})]})})]}),s.jsx("div",{className:"p-4 border-t border-gray-700/50 space-y-1",children:s.jsxs("button",{type:"button",onClick:o,className:"w-full flex items-center gap-3 px-4 py-3 text-gray-400 hover:text-white rounded-lg hover:bg-gray-700/50 transition-colors",children:[s.jsx(GM,{className:"w-5 h-5"}),s.jsx("span",{className:"text-sm",children:"退出登录"})]})})]}),s.jsxs("div",{className:"flex-1 overflow-auto bg-[#0a1628] min-w-0 flex flex-col",children:[s.jsx(ZA,{}),s.jsx("div",{className:"w-full min-w-[1024px] min-h-full flex-1",children:s.jsx(fT,{})})]})]})}function Fb(t,e){if(typeof t=="function")return t(e);t!=null&&(t.current=e)}function Lx(...t){return e=>{let n=!1;const r=t.map(i=>{const a=Fb(i,e);return!n&&typeof a=="function"&&(n=!0),a});if(n)return()=>{for(let i=0;i{let{children:a,...o}=r;XN(a)&&typeof ch=="function"&&(a=ch(a._payload));const c=v.Children.toArray(a),u=c.find(aI);if(u){const h=u.props.children,f=c.map(m=>m===u?v.Children.count(h)>1?v.Children.only(null):v.isValidElement(h)?h.props.children:null:m);return s.jsx(e,{...o,ref:i,children:v.isValidElement(h)?v.cloneElement(h,void 0,f):null})}return s.jsx(e,{...o,ref:i,children:a})});return n.displayName=`${t}.Slot`,n}var ej=ZN("Slot");function sI(t){const e=v.forwardRef((n,r)=>{let{children:i,...a}=n;if(XN(i)&&typeof ch=="function"&&(i=ch(i._payload)),v.isValidElement(i)){const o=lI(i),c=oI(a,i.props);return i.type!==v.Fragment&&(c.ref=r?Lx(r,o):o),v.cloneElement(i,c)}return v.Children.count(i)>1?v.Children.only(null):null});return e.displayName=`${t}.SlotClone`,e}var iI=Symbol("radix.slottable");function aI(t){return v.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===iI}function oI(t,e){const n={...e};for(const r in e){const i=t[r],a=e[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...c)=>{const u=a(...c);return i(...c),u}:i&&(n[r]=i):r==="style"?n[r]={...i,...a}:r==="className"&&(n[r]=[i,a].filter(Boolean).join(" "))}return{...t,...n}}function lI(t){var r,i;let e=(r=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:r.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}function tj(t){var e,n,r="";if(typeof t=="string"||typeof t=="number")r+=t;else if(typeof t=="object")if(Array.isArray(t)){var i=t.length;for(e=0;etypeof t=="boolean"?`${t}`:t===0?"0":t,Vb=nj,rj=(t,e)=>n=>{var r;if((e==null?void 0:e.variants)==null)return Vb(t,n==null?void 0:n.class,n==null?void 0:n.className);const{variants:i,defaultVariants:a}=e,o=Object.keys(i).map(h=>{const f=n==null?void 0:n[h],m=a==null?void 0:a[h];if(f===null)return null;const g=Bb(f)||Bb(m);return i[h][g]}),c=n&&Object.entries(n).reduce((h,f)=>{let[m,g]=f;return g===void 0||(h[m]=g),h},{}),u=e==null||(r=e.compoundVariants)===null||r===void 0?void 0:r.reduce((h,f)=>{let{class:m,className:g,...y}=f;return Object.entries(y).every(w=>{let[N,b]=w;return Array.isArray(b)?b.includes({...a,...c}[N]):{...a,...c}[N]===b})?[...h,m,g]:h},[]);return Vb(t,o,u,n==null?void 0:n.class,n==null?void 0:n.className)},cI=(t,e)=>{const n=new Array(t.length+e.length);for(let r=0;r({classGroupId:t,validator:e}),sj=(t=new Map,e=null,n)=>({nextPart:t,validators:e,classGroupId:n}),dh="-",Hb=[],uI="arbitrary..",hI=t=>{const e=pI(t),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=t;return{getClassGroupId:o=>{if(o.startsWith("[")&&o.endsWith("]"))return fI(o);const c=o.split(dh),u=c[0]===""&&c.length>1?1:0;return ij(c,u,e)},getConflictingClassGroupIds:(o,c)=>{if(c){const u=r[o],h=n[o];return u?h?cI(h,u):u:h||Hb}return n[o]||Hb}}},ij=(t,e,n)=>{if(t.length-e===0)return n.classGroupId;const i=t[e],a=n.nextPart.get(i);if(a){const h=ij(t,e+1,a);if(h)return h}const o=n.validators;if(o===null)return;const c=e===0?t.join(dh):t.slice(e).join(dh),u=o.length;for(let h=0;ht.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const e=t.slice(1,-1),n=e.indexOf(":"),r=e.slice(0,n);return r?uI+r:void 0})(),pI=t=>{const{theme:e,classGroups:n}=t;return mI(n,e)},mI=(t,e)=>{const n=sj();for(const r in t){const i=t[r];_x(i,n,r,e)}return n},_x=(t,e,n,r)=>{const i=t.length;for(let a=0;a{if(typeof t=="string"){xI(t,e,n);return}if(typeof t=="function"){yI(t,e,n,r);return}vI(t,e,n,r)},xI=(t,e,n)=>{const r=t===""?e:aj(e,t);r.classGroupId=n},yI=(t,e,n,r)=>{if(bI(t)){_x(t(r),e,n,r);return}e.validators===null&&(e.validators=[]),e.validators.push(dI(n,t))},vI=(t,e,n,r)=>{const i=Object.entries(t),a=i.length;for(let o=0;o{let n=t;const r=e.split(dh),i=r.length;for(let a=0;a"isThemeGetter"in t&&t.isThemeGetter===!0,wI=t=>{if(t<1)return{get:()=>{},set:()=>{}};let e=0,n=Object.create(null),r=Object.create(null);const i=(a,o)=>{n[a]=o,e++,e>t&&(e=0,r=n,n=Object.create(null))};return{get(a){let o=n[a];if(o!==void 0)return o;if((o=r[a])!==void 0)return i(a,o),o},set(a,o){a in n?n[a]=o:i(a,o)}}},Mg="!",Wb=":",NI=[],Ub=(t,e,n,r,i)=>({modifiers:t,hasImportantModifier:e,baseClassName:n,maybePostfixModifierPosition:r,isExternal:i}),jI=t=>{const{prefix:e,experimentalParseClassName:n}=t;let r=i=>{const a=[];let o=0,c=0,u=0,h;const f=i.length;for(let N=0;Nu?h-u:void 0;return Ub(a,y,g,w)};if(e){const i=e+Wb,a=r;r=o=>o.startsWith(i)?a(o.slice(i.length)):Ub(NI,!1,o,void 0,!0)}if(n){const i=r;r=a=>n({className:a,parseClassName:i})}return r},kI=t=>{const e=new Map;return t.orderSensitiveModifiers.forEach((n,r)=>{e.set(n,1e6+r)}),n=>{const r=[];let i=[];for(let a=0;a0&&(i.sort(),r.push(...i),i=[]),r.push(o)):i.push(o)}return i.length>0&&(i.sort(),r.push(...i)),r}},SI=t=>({cache:wI(t.cacheSize),parseClassName:jI(t),sortModifiers:kI(t),...hI(t)}),CI=/\s+/,EI=(t,e)=>{const{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:a}=e,o=[],c=t.trim().split(CI);let u="";for(let h=c.length-1;h>=0;h-=1){const f=c[h],{isExternal:m,modifiers:g,hasImportantModifier:y,baseClassName:w,maybePostfixModifierPosition:N}=n(f);if(m){u=f+(u.length>0?" "+u:u);continue}let b=!!N,k=r(b?w.substring(0,N):w);if(!k){if(!b){u=f+(u.length>0?" "+u:u);continue}if(k=r(w),!k){u=f+(u.length>0?" "+u:u);continue}b=!1}const C=g.length===0?"":g.length===1?g[0]:a(g).join(":"),E=y?C+Mg:C,T=E+k;if(o.indexOf(T)>-1)continue;o.push(T);const I=i(k,b);for(let O=0;O0?" "+u:u)}return u},TI=(...t)=>{let e=0,n,r,i="";for(;e{if(typeof t=="string")return t;let e,n="";for(let r=0;r{let n,r,i,a;const o=u=>{const h=e.reduce((f,m)=>m(f),t());return n=SI(h),r=n.cache.get,i=n.cache.set,a=c,c(u)},c=u=>{const h=r(u);if(h)return h;const f=EI(u,n);return i(u,f),f};return a=o,(...u)=>a(TI(...u))},AI=[],Tn=t=>{const e=n=>n[t]||AI;return e.isThemeGetter=!0,e},lj=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,cj=/^\((?:(\w[\w-]*):)?(.+)\)$/i,II=/^\d+\/\d+$/,RI=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,PI=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,OI=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,DI=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,LI=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,el=t=>II.test(t),ut=t=>!!t&&!Number.isNaN(Number(t)),Gi=t=>!!t&&Number.isInteger(Number(t)),km=t=>t.endsWith("%")&&ut(t.slice(0,-1)),ai=t=>RI.test(t),_I=()=>!0,zI=t=>PI.test(t)&&!OI.test(t),dj=()=>!1,$I=t=>DI.test(t),FI=t=>LI.test(t),BI=t=>!ze(t)&&!$e(t),VI=t=>Rl(t,fj,dj),ze=t=>lj.test(t),Ya=t=>Rl(t,pj,zI),Sm=t=>Rl(t,qI,ut),Kb=t=>Rl(t,uj,dj),HI=t=>Rl(t,hj,FI),ju=t=>Rl(t,mj,$I),$e=t=>cj.test(t),jc=t=>Pl(t,pj),WI=t=>Pl(t,GI),qb=t=>Pl(t,uj),UI=t=>Pl(t,fj),KI=t=>Pl(t,hj),ku=t=>Pl(t,mj,!0),Rl=(t,e,n)=>{const r=lj.exec(t);return r?r[1]?e(r[1]):n(r[2]):!1},Pl=(t,e,n=!1)=>{const r=cj.exec(t);return r?r[1]?e(r[1]):n:!1},uj=t=>t==="position"||t==="percentage",hj=t=>t==="image"||t==="url",fj=t=>t==="length"||t==="size"||t==="bg-size",pj=t=>t==="length",qI=t=>t==="number",GI=t=>t==="family-name",mj=t=>t==="shadow",JI=()=>{const t=Tn("color"),e=Tn("font"),n=Tn("text"),r=Tn("font-weight"),i=Tn("tracking"),a=Tn("leading"),o=Tn("breakpoint"),c=Tn("container"),u=Tn("spacing"),h=Tn("radius"),f=Tn("shadow"),m=Tn("inset-shadow"),g=Tn("text-shadow"),y=Tn("drop-shadow"),w=Tn("blur"),N=Tn("perspective"),b=Tn("aspect"),k=Tn("ease"),C=Tn("animate"),E=()=>["auto","avoid","all","avoid-page","page","left","right","column"],T=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],I=()=>[...T(),$e,ze],O=()=>["auto","hidden","clip","visible","scroll"],D=()=>["auto","contain","none"],P=()=>[$e,ze,u],L=()=>[el,"full","auto",...P()],_=()=>[Gi,"none","subgrid",$e,ze],J=()=>["auto",{span:["full",Gi,$e,ze]},Gi,$e,ze],ee=()=>[Gi,"auto",$e,ze],Y=()=>["auto","min","max","fr",$e,ze],U=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],R=()=>["start","end","center","stretch","center-safe","end-safe"],F=()=>["auto",...P()],re=()=>[el,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...P()],z=()=>[t,$e,ze],ie=()=>[...T(),qb,Kb,{position:[$e,ze]}],G=()=>["no-repeat",{repeat:["","x","y","space","round"]}],$=()=>["auto","cover","contain",UI,VI,{size:[$e,ze]}],V=()=>[km,jc,Ya],ce=()=>["","none","full",h,$e,ze],W=()=>["",ut,jc,Ya],fe=()=>["solid","dashed","dotted","double"],X=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],de=()=>[ut,km,qb,Kb],he=()=>["","none",w,$e,ze],be=()=>["none",ut,$e,ze],Te=()=>["none",ut,$e,ze],Ve=()=>[ut,$e,ze],He=()=>[el,"full",...P()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[ai],breakpoint:[ai],color:[_I],container:[ai],"drop-shadow":[ai],ease:["in","out","in-out"],font:[BI],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[ai],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[ai],shadow:[ai],spacing:["px",ut],text:[ai],"text-shadow":[ai],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",el,ze,$e,b]}],container:["container"],columns:[{columns:[ut,ze,$e,c]}],"break-after":[{"break-after":E()}],"break-before":[{"break-before":E()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:I()}],overflow:[{overflow:O()}],"overflow-x":[{"overflow-x":O()}],"overflow-y":[{"overflow-y":O()}],overscroll:[{overscroll:D()}],"overscroll-x":[{"overscroll-x":D()}],"overscroll-y":[{"overscroll-y":D()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:L()}],"inset-x":[{"inset-x":L()}],"inset-y":[{"inset-y":L()}],start:[{start:L()}],end:[{end:L()}],top:[{top:L()}],right:[{right:L()}],bottom:[{bottom:L()}],left:[{left:L()}],visibility:["visible","invisible","collapse"],z:[{z:[Gi,"auto",$e,ze]}],basis:[{basis:[el,"full","auto",c,...P()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[ut,el,"auto","initial","none",ze]}],grow:[{grow:["",ut,$e,ze]}],shrink:[{shrink:["",ut,$e,ze]}],order:[{order:[Gi,"first","last","none",$e,ze]}],"grid-cols":[{"grid-cols":_()}],"col-start-end":[{col:J()}],"col-start":[{"col-start":ee()}],"col-end":[{"col-end":ee()}],"grid-rows":[{"grid-rows":_()}],"row-start-end":[{row:J()}],"row-start":[{"row-start":ee()}],"row-end":[{"row-end":ee()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":Y()}],"auto-rows":[{"auto-rows":Y()}],gap:[{gap:P()}],"gap-x":[{"gap-x":P()}],"gap-y":[{"gap-y":P()}],"justify-content":[{justify:[...U(),"normal"]}],"justify-items":[{"justify-items":[...R(),"normal"]}],"justify-self":[{"justify-self":["auto",...R()]}],"align-content":[{content:["normal",...U()]}],"align-items":[{items:[...R(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...R(),{baseline:["","last"]}]}],"place-content":[{"place-content":U()}],"place-items":[{"place-items":[...R(),"baseline"]}],"place-self":[{"place-self":["auto",...R()]}],p:[{p:P()}],px:[{px:P()}],py:[{py:P()}],ps:[{ps:P()}],pe:[{pe:P()}],pt:[{pt:P()}],pr:[{pr:P()}],pb:[{pb:P()}],pl:[{pl:P()}],m:[{m:F()}],mx:[{mx:F()}],my:[{my:F()}],ms:[{ms:F()}],me:[{me:F()}],mt:[{mt:F()}],mr:[{mr:F()}],mb:[{mb:F()}],ml:[{ml:F()}],"space-x":[{"space-x":P()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":P()}],"space-y-reverse":["space-y-reverse"],size:[{size:re()}],w:[{w:[c,"screen",...re()]}],"min-w":[{"min-w":[c,"screen","none",...re()]}],"max-w":[{"max-w":[c,"screen","none","prose",{screen:[o]},...re()]}],h:[{h:["screen","lh",...re()]}],"min-h":[{"min-h":["screen","lh","none",...re()]}],"max-h":[{"max-h":["screen","lh",...re()]}],"font-size":[{text:["base",n,jc,Ya]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[r,$e,Sm]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",km,ze]}],"font-family":[{font:[WI,ze,e]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[i,$e,ze]}],"line-clamp":[{"line-clamp":[ut,"none",$e,Sm]}],leading:[{leading:[a,...P()]}],"list-image":[{"list-image":["none",$e,ze]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",$e,ze]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:z()}],"text-color":[{text:z()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...fe(),"wavy"]}],"text-decoration-thickness":[{decoration:[ut,"from-font","auto",$e,Ya]}],"text-decoration-color":[{decoration:z()}],"underline-offset":[{"underline-offset":[ut,"auto",$e,ze]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:P()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",$e,ze]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",$e,ze]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ie()}],"bg-repeat":[{bg:G()}],"bg-size":[{bg:$()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},Gi,$e,ze],radial:["",$e,ze],conic:[Gi,$e,ze]},KI,HI]}],"bg-color":[{bg:z()}],"gradient-from-pos":[{from:V()}],"gradient-via-pos":[{via:V()}],"gradient-to-pos":[{to:V()}],"gradient-from":[{from:z()}],"gradient-via":[{via:z()}],"gradient-to":[{to:z()}],rounded:[{rounded:ce()}],"rounded-s":[{"rounded-s":ce()}],"rounded-e":[{"rounded-e":ce()}],"rounded-t":[{"rounded-t":ce()}],"rounded-r":[{"rounded-r":ce()}],"rounded-b":[{"rounded-b":ce()}],"rounded-l":[{"rounded-l":ce()}],"rounded-ss":[{"rounded-ss":ce()}],"rounded-se":[{"rounded-se":ce()}],"rounded-ee":[{"rounded-ee":ce()}],"rounded-es":[{"rounded-es":ce()}],"rounded-tl":[{"rounded-tl":ce()}],"rounded-tr":[{"rounded-tr":ce()}],"rounded-br":[{"rounded-br":ce()}],"rounded-bl":[{"rounded-bl":ce()}],"border-w":[{border:W()}],"border-w-x":[{"border-x":W()}],"border-w-y":[{"border-y":W()}],"border-w-s":[{"border-s":W()}],"border-w-e":[{"border-e":W()}],"border-w-t":[{"border-t":W()}],"border-w-r":[{"border-r":W()}],"border-w-b":[{"border-b":W()}],"border-w-l":[{"border-l":W()}],"divide-x":[{"divide-x":W()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":W()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...fe(),"hidden","none"]}],"divide-style":[{divide:[...fe(),"hidden","none"]}],"border-color":[{border:z()}],"border-color-x":[{"border-x":z()}],"border-color-y":[{"border-y":z()}],"border-color-s":[{"border-s":z()}],"border-color-e":[{"border-e":z()}],"border-color-t":[{"border-t":z()}],"border-color-r":[{"border-r":z()}],"border-color-b":[{"border-b":z()}],"border-color-l":[{"border-l":z()}],"divide-color":[{divide:z()}],"outline-style":[{outline:[...fe(),"none","hidden"]}],"outline-offset":[{"outline-offset":[ut,$e,ze]}],"outline-w":[{outline:["",ut,jc,Ya]}],"outline-color":[{outline:z()}],shadow:[{shadow:["","none",f,ku,ju]}],"shadow-color":[{shadow:z()}],"inset-shadow":[{"inset-shadow":["none",m,ku,ju]}],"inset-shadow-color":[{"inset-shadow":z()}],"ring-w":[{ring:W()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:z()}],"ring-offset-w":[{"ring-offset":[ut,Ya]}],"ring-offset-color":[{"ring-offset":z()}],"inset-ring-w":[{"inset-ring":W()}],"inset-ring-color":[{"inset-ring":z()}],"text-shadow":[{"text-shadow":["none",g,ku,ju]}],"text-shadow-color":[{"text-shadow":z()}],opacity:[{opacity:[ut,$e,ze]}],"mix-blend":[{"mix-blend":[...X(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":X()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[ut]}],"mask-image-linear-from-pos":[{"mask-linear-from":de()}],"mask-image-linear-to-pos":[{"mask-linear-to":de()}],"mask-image-linear-from-color":[{"mask-linear-from":z()}],"mask-image-linear-to-color":[{"mask-linear-to":z()}],"mask-image-t-from-pos":[{"mask-t-from":de()}],"mask-image-t-to-pos":[{"mask-t-to":de()}],"mask-image-t-from-color":[{"mask-t-from":z()}],"mask-image-t-to-color":[{"mask-t-to":z()}],"mask-image-r-from-pos":[{"mask-r-from":de()}],"mask-image-r-to-pos":[{"mask-r-to":de()}],"mask-image-r-from-color":[{"mask-r-from":z()}],"mask-image-r-to-color":[{"mask-r-to":z()}],"mask-image-b-from-pos":[{"mask-b-from":de()}],"mask-image-b-to-pos":[{"mask-b-to":de()}],"mask-image-b-from-color":[{"mask-b-from":z()}],"mask-image-b-to-color":[{"mask-b-to":z()}],"mask-image-l-from-pos":[{"mask-l-from":de()}],"mask-image-l-to-pos":[{"mask-l-to":de()}],"mask-image-l-from-color":[{"mask-l-from":z()}],"mask-image-l-to-color":[{"mask-l-to":z()}],"mask-image-x-from-pos":[{"mask-x-from":de()}],"mask-image-x-to-pos":[{"mask-x-to":de()}],"mask-image-x-from-color":[{"mask-x-from":z()}],"mask-image-x-to-color":[{"mask-x-to":z()}],"mask-image-y-from-pos":[{"mask-y-from":de()}],"mask-image-y-to-pos":[{"mask-y-to":de()}],"mask-image-y-from-color":[{"mask-y-from":z()}],"mask-image-y-to-color":[{"mask-y-to":z()}],"mask-image-radial":[{"mask-radial":[$e,ze]}],"mask-image-radial-from-pos":[{"mask-radial-from":de()}],"mask-image-radial-to-pos":[{"mask-radial-to":de()}],"mask-image-radial-from-color":[{"mask-radial-from":z()}],"mask-image-radial-to-color":[{"mask-radial-to":z()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":T()}],"mask-image-conic-pos":[{"mask-conic":[ut]}],"mask-image-conic-from-pos":[{"mask-conic-from":de()}],"mask-image-conic-to-pos":[{"mask-conic-to":de()}],"mask-image-conic-from-color":[{"mask-conic-from":z()}],"mask-image-conic-to-color":[{"mask-conic-to":z()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ie()}],"mask-repeat":[{mask:G()}],"mask-size":[{mask:$()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",$e,ze]}],filter:[{filter:["","none",$e,ze]}],blur:[{blur:he()}],brightness:[{brightness:[ut,$e,ze]}],contrast:[{contrast:[ut,$e,ze]}],"drop-shadow":[{"drop-shadow":["","none",y,ku,ju]}],"drop-shadow-color":[{"drop-shadow":z()}],grayscale:[{grayscale:["",ut,$e,ze]}],"hue-rotate":[{"hue-rotate":[ut,$e,ze]}],invert:[{invert:["",ut,$e,ze]}],saturate:[{saturate:[ut,$e,ze]}],sepia:[{sepia:["",ut,$e,ze]}],"backdrop-filter":[{"backdrop-filter":["","none",$e,ze]}],"backdrop-blur":[{"backdrop-blur":he()}],"backdrop-brightness":[{"backdrop-brightness":[ut,$e,ze]}],"backdrop-contrast":[{"backdrop-contrast":[ut,$e,ze]}],"backdrop-grayscale":[{"backdrop-grayscale":["",ut,$e,ze]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[ut,$e,ze]}],"backdrop-invert":[{"backdrop-invert":["",ut,$e,ze]}],"backdrop-opacity":[{"backdrop-opacity":[ut,$e,ze]}],"backdrop-saturate":[{"backdrop-saturate":[ut,$e,ze]}],"backdrop-sepia":[{"backdrop-sepia":["",ut,$e,ze]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":P()}],"border-spacing-x":[{"border-spacing-x":P()}],"border-spacing-y":[{"border-spacing-y":P()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",$e,ze]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[ut,"initial",$e,ze]}],ease:[{ease:["linear","initial",k,$e,ze]}],delay:[{delay:[ut,$e,ze]}],animate:[{animate:["none",C,$e,ze]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[N,$e,ze]}],"perspective-origin":[{"perspective-origin":I()}],rotate:[{rotate:be()}],"rotate-x":[{"rotate-x":be()}],"rotate-y":[{"rotate-y":be()}],"rotate-z":[{"rotate-z":be()}],scale:[{scale:Te()}],"scale-x":[{"scale-x":Te()}],"scale-y":[{"scale-y":Te()}],"scale-z":[{"scale-z":Te()}],"scale-3d":["scale-3d"],skew:[{skew:Ve()}],"skew-x":[{"skew-x":Ve()}],"skew-y":[{"skew-y":Ve()}],transform:[{transform:[$e,ze,"","none","gpu","cpu"]}],"transform-origin":[{origin:I()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:He()}],"translate-x":[{"translate-x":He()}],"translate-y":[{"translate-y":He()}],"translate-z":[{"translate-z":He()}],"translate-none":["translate-none"],accent:[{accent:z()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:z()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",$e,ze]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":P()}],"scroll-mx":[{"scroll-mx":P()}],"scroll-my":[{"scroll-my":P()}],"scroll-ms":[{"scroll-ms":P()}],"scroll-me":[{"scroll-me":P()}],"scroll-mt":[{"scroll-mt":P()}],"scroll-mr":[{"scroll-mr":P()}],"scroll-mb":[{"scroll-mb":P()}],"scroll-ml":[{"scroll-ml":P()}],"scroll-p":[{"scroll-p":P()}],"scroll-px":[{"scroll-px":P()}],"scroll-py":[{"scroll-py":P()}],"scroll-ps":[{"scroll-ps":P()}],"scroll-pe":[{"scroll-pe":P()}],"scroll-pt":[{"scroll-pt":P()}],"scroll-pr":[{"scroll-pr":P()}],"scroll-pb":[{"scroll-pb":P()}],"scroll-pl":[{"scroll-pl":P()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",$e,ze]}],fill:[{fill:["none",...z()]}],"stroke-w":[{stroke:[ut,jc,Ya,Sm]}],stroke:[{stroke:["none",...z()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},YI=MI(JI);function Mt(...t){return YI(nj(t))}const QI=rj("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-white hover:bg-destructive/90",outline:"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2 has-[>svg]:px-3",sm:"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",lg:"h-10 rounded-md px-6 has-[>svg]:px-4",icon:"size-9","icon-sm":"size-8","icon-lg":"size-10"}},defaultVariants:{variant:"default",size:"default"}});function te({className:t,variant:e,size:n,asChild:r=!1,...i}){const a=r?ej:"button";return s.jsx(a,{"data-slot":"button",className:Mt(QI({variant:e,size:n,className:t})),...i})}function oe({className:t,type:e,...n}){return s.jsx("input",{type:e,"data-slot":"input",className:Mt("h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 md:text-sm focus-visible:ring-2 focus-visible:ring-ring",t),...n})}function XI(){const t=ka(),[e,n]=v.useState(""),[r,i]=v.useState(""),[a,o]=v.useState(""),[c,u]=v.useState(!1),h=async()=>{o(""),u(!0);try{const f=await yt("/api/admin",{username:e.trim(),password:r});if((f==null?void 0:f.success)!==!1&&(f!=null&&f.token)){GA(f.token),t("/dashboard",{replace:!0});return}o(f.error||"用户名或密码错误")}catch(f){const m=f;o(m.status===401?"用户名或密码错误":(m==null?void 0:m.message)||"网络错误,请重试")}finally{u(!1)}};return s.jsxs("div",{className:"min-h-screen bg-[#0a1628] flex items-center justify-center p-4",children:[s.jsxs("div",{className:"absolute inset-0 overflow-hidden",children:[s.jsx("div",{className:"absolute top-1/4 left-1/4 w-96 h-96 bg-[#38bdac]/5 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-1/4 right-1/4 w-96 h-96 bg-blue-500/5 rounded-full blur-3xl"})]}),s.jsxs("div",{className:"w-full max-w-md relative z-10",children:[s.jsxs("div",{className:"text-center mb-8",children:[s.jsx("div",{className:"w-16 h-16 bg-[#38bdac]/20 rounded-2xl flex items-center justify-center mx-auto mb-4 border border-[#38bdac]/30",children:s.jsx(Px,{className:"w-8 h-8 text-[#38bdac]"})}),s.jsx("h1",{className:"text-2xl font-bold text-white mb-2",children:"管理后台"}),s.jsx("p",{className:"text-gray-400",children:"一场SOUL的创业实验场"})]}),s.jsxs("div",{className:"bg-[#0f2137] rounded-2xl p-8 shadow-xl border border-gray-700/50 backdrop-blur-xl",children:[s.jsx("h2",{className:"text-xl font-semibold text-white mb-6 text-center",children:"管理员登录"}),s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"block text-gray-400 text-sm mb-2",children:"用户名"}),s.jsxs("div",{className:"relative",children:[s.jsx(gl,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500"}),s.jsx(oe,{type:"text",value:e,onChange:f=>n(f.target.value),placeholder:"请输入用户名",className:"pl-10 bg-[#0a1628] border-gray-700 text-white placeholder:text-gray-500 focus:border-[#38bdac]"})]})]}),s.jsxs("div",{children:[s.jsx("label",{className:"block text-gray-400 text-sm mb-2",children:"密码"}),s.jsxs("div",{className:"relative",children:[s.jsx(KM,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500"}),s.jsx(oe,{type:"password",value:r,onChange:f=>i(f.target.value),placeholder:"请输入密码",className:"pl-10 bg-[#0a1628] border-gray-700 text-white placeholder:text-gray-500 focus:border-[#38bdac]",onKeyDown:f=>f.key==="Enter"&&h()})]})]}),a&&s.jsx("div",{className:"bg-red-500/10 text-red-400 text-sm p-3 rounded-lg border border-red-500/20",children:a}),s.jsx(te,{onClick:h,disabled:c,className:"w-full bg-[#38bdac] hover:bg-[#2da396] text-white py-5 disabled:opacity-50",children:c?"登录中...":"登录"})]})]}),s.jsx("p",{className:"text-center text-gray-500 text-xs mt-6",children:"Soul创业实验场 · 后台管理系统"})]})]})}const Me=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("rounded-xl border bg-card text-card-foreground shadow",t),...e}));Me.displayName="Card";const rt=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("flex flex-col space-y-1.5 p-6",t),...e}));rt.displayName="CardHeader";const st=v.forwardRef(({className:t,...e},n)=>s.jsx("h3",{ref:n,className:Mt("font-semibold leading-none tracking-tight",t),...e}));st.displayName="CardTitle";const Vt=v.forwardRef(({className:t,...e},n)=>s.jsx("p",{ref:n,className:Mt("text-sm text-muted-foreground",t),...e}));Vt.displayName="CardDescription";const Ae=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("p-6 pt-0",t),...e}));Ae.displayName="CardContent";const ZI=v.forwardRef(({className:t,...e},n)=>s.jsx("div",{ref:n,className:Mt("flex items-center p-6 pt-0",t),...e}));ZI.displayName="CardFooter";const e5={success:{bg:"#f0fdf4",border:"#22c55e",icon:"✓"},error:{bg:"#fef2f2",border:"#ef4444",icon:"✕"},info:{bg:"#eff6ff",border:"#3b82f6",icon:"ℹ"}};function Cm(t,e="info",n=3e3){const r=`toast-${Date.now()}`,i=e5[e],a=document.createElement("div");a.id=r,a.setAttribute("role","alert"),Object.assign(a.style,{position:"fixed",top:"24px",right:"24px",zIndex:"9999",display:"flex",alignItems:"center",gap:"10px",padding:"12px 18px",borderRadius:"10px",background:i.bg,border:`1.5px solid ${i.border}`,boxShadow:"0 4px 20px rgba(0,0,0,.12)",fontSize:"14px",color:"#1a1a1a",fontWeight:"500",maxWidth:"380px",lineHeight:"1.5",opacity:"0",transform:"translateY(-8px)",transition:"opacity .22s ease, transform .22s ease",pointerEvents:"none"});const o=document.createElement("span");Object.assign(o.style,{width:"20px",height:"20px",borderRadius:"50%",background:i.border,color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"12px",fontWeight:"700",flexShrink:"0"}),o.textContent=i.icon;const c=document.createElement("span");c.textContent=t,a.appendChild(o),a.appendChild(c),document.body.appendChild(a),requestAnimationFrame(()=>{a.style.opacity="1",a.style.transform="translateY(0)"});const u=setTimeout(()=>h(r),n);function h(f){clearTimeout(u);const m=document.getElementById(f);m&&(m.style.opacity="0",m.style.transform="translateY(-8px)",setTimeout(()=>{var g;return(g=m.parentNode)==null?void 0:g.removeChild(m)},250))}}const ae={success:(t,e)=>Cm(t,"success",e),error:(t,e)=>Cm(t,"error",e),info:(t,e)=>Cm(t,"info",e)};function ot(t,e,{checkForDefaultPrevented:n=!0}={}){return function(i){if(t==null||t(i),n===!1||!i.defaultPrevented)return e==null?void 0:e(i)}}function t5(t,e){const n=v.createContext(e),r=a=>{const{children:o,...c}=a,u=v.useMemo(()=>c,Object.values(c));return s.jsx(n.Provider,{value:u,children:o})};r.displayName=t+"Provider";function i(a){const o=v.useContext(n);if(o)return o;if(e!==void 0)return e;throw new Error(`\`${a}\` must be used within \`${t}\``)}return[r,i]}function Sa(t,e=[]){let n=[];function r(a,o){const c=v.createContext(o),u=n.length;n=[...n,o];const h=m=>{var k;const{scope:g,children:y,...w}=m,N=((k=g==null?void 0:g[t])==null?void 0:k[u])||c,b=v.useMemo(()=>w,Object.values(w));return s.jsx(N.Provider,{value:b,children:y})};h.displayName=a+"Provider";function f(m,g){var N;const y=((N=g==null?void 0:g[t])==null?void 0:N[u])||c,w=v.useContext(y);if(w)return w;if(o!==void 0)return o;throw new Error(`\`${m}\` must be used within \`${a}\``)}return[h,f]}const i=()=>{const a=n.map(o=>v.createContext(o));return function(c){const u=(c==null?void 0:c[t])||a;return v.useMemo(()=>({[`__scope${t}`]:{...c,[t]:u}}),[c,u])}};return i.scopeName=t,[r,n5(i,...e)]}function n5(...t){const e=t[0];if(t.length===1)return e;const n=()=>{const r=t.map(i=>({useScope:i(),scopeName:i.scopeName}));return function(a){const o=r.reduce((c,{useScope:u,scopeName:h})=>{const m=u(a)[`__scope${h}`];return{...c,...m}},{});return v.useMemo(()=>({[`__scope${e.scopeName}`]:o}),[o])}};return n.scopeName=e.scopeName,n}var tr=globalThis!=null&&globalThis.document?v.useLayoutEffect:()=>{},r5=lf[" useId ".trim().toString()]||(()=>{}),s5=0;function ha(t){const[e,n]=v.useState(r5());return tr(()=>{n(r=>r??String(s5++))},[t]),e?`radix-${e}`:""}var i5=lf[" useInsertionEffect ".trim().toString()]||tr;function po({prop:t,defaultProp:e,onChange:n=()=>{},caller:r}){const[i,a,o]=a5({defaultProp:e,onChange:n}),c=t!==void 0,u=c?t:i;{const f=v.useRef(t!==void 0);v.useEffect(()=>{const m=f.current;m!==c&&console.warn(`${r} is changing from ${m?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=c},[c,r])}const h=v.useCallback(f=>{var m;if(c){const g=o5(f)?f(t):f;g!==t&&((m=o.current)==null||m.call(o,g))}else a(f)},[c,t,a,o]);return[u,h]}function a5({defaultProp:t,onChange:e}){const[n,r]=v.useState(t),i=v.useRef(n),a=v.useRef(e);return i5(()=>{a.current=e},[e]),v.useEffect(()=>{var o;i.current!==n&&((o=a.current)==null||o.call(a,n),i.current=n)},[n,i]),[n,r,a]}function o5(t){return typeof t=="function"}function Yc(t){const e=l5(t),n=v.forwardRef((r,i)=>{const{children:a,...o}=r,c=v.Children.toArray(a),u=c.find(d5);if(u){const h=u.props.children,f=c.map(m=>m===u?v.Children.count(h)>1?v.Children.only(null):v.isValidElement(h)?h.props.children:null:m);return s.jsx(e,{...o,ref:i,children:v.isValidElement(h)?v.cloneElement(h,void 0,f):null})}return s.jsx(e,{...o,ref:i,children:a})});return n.displayName=`${t}.Slot`,n}function l5(t){const e=v.forwardRef((n,r)=>{const{children:i,...a}=n;if(v.isValidElement(i)){const o=h5(i),c=u5(a,i.props);return i.type!==v.Fragment&&(c.ref=r?Lx(r,o):o),v.cloneElement(i,c)}return v.Children.count(i)>1?v.Children.only(null):null});return e.displayName=`${t}.SlotClone`,e}var c5=Symbol("radix.slottable");function d5(t){return v.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===c5}function u5(t,e){const n={...e};for(const r in e){const i=t[r],a=e[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...c)=>{const u=a(...c);return i(...c),u}:i&&(n[r]=i):r==="style"?n[r]={...i,...a}:r==="className"&&(n[r]=[i,a].filter(Boolean).join(" "))}return{...t,...n}}function h5(t){var r,i;let e=(r=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:r.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}var f5=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],ht=f5.reduce((t,e)=>{const n=Yc(`Primitive.${e}`),r=v.forwardRef((i,a)=>{const{asChild:o,...c}=i,u=o?n:e;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),s.jsx(u,{...c,ref:a})});return r.displayName=`Primitive.${e}`,{...t,[e]:r}},{});function p5(t,e){t&&ud.flushSync(()=>t.dispatchEvent(e))}function xa(t){const e=v.useRef(t);return v.useEffect(()=>{e.current=t}),v.useMemo(()=>(...n)=>{var r;return(r=e.current)==null?void 0:r.call(e,...n)},[])}function m5(t,e=globalThis==null?void 0:globalThis.document){const n=xa(t);v.useEffect(()=>{const r=i=>{i.key==="Escape"&&n(i)};return e.addEventListener("keydown",r,{capture:!0}),()=>e.removeEventListener("keydown",r,{capture:!0})},[n,e])}var g5="DismissableLayer",Ag="dismissableLayer.update",x5="dismissableLayer.pointerDownOutside",y5="dismissableLayer.focusOutside",Gb,gj=v.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),zx=v.forwardRef((t,e)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:i,onFocusOutside:a,onInteractOutside:o,onDismiss:c,...u}=t,h=v.useContext(gj),[f,m]=v.useState(null),g=(f==null?void 0:f.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,y]=v.useState({}),w=Tt(e,D=>m(D)),N=Array.from(h.layers),[b]=[...h.layersWithOutsidePointerEventsDisabled].slice(-1),k=N.indexOf(b),C=f?N.indexOf(f):-1,E=h.layersWithOutsidePointerEventsDisabled.size>0,T=C>=k,I=w5(D=>{const P=D.target,L=[...h.branches].some(_=>_.contains(P));!T||L||(i==null||i(D),o==null||o(D),D.defaultPrevented||c==null||c())},g),O=N5(D=>{const P=D.target;[...h.branches].some(_=>_.contains(P))||(a==null||a(D),o==null||o(D),D.defaultPrevented||c==null||c())},g);return m5(D=>{C===h.layers.size-1&&(r==null||r(D),!D.defaultPrevented&&c&&(D.preventDefault(),c()))},g),v.useEffect(()=>{if(f)return n&&(h.layersWithOutsidePointerEventsDisabled.size===0&&(Gb=g.body.style.pointerEvents,g.body.style.pointerEvents="none"),h.layersWithOutsidePointerEventsDisabled.add(f)),h.layers.add(f),Jb(),()=>{n&&h.layersWithOutsidePointerEventsDisabled.size===1&&(g.body.style.pointerEvents=Gb)}},[f,g,n,h]),v.useEffect(()=>()=>{f&&(h.layers.delete(f),h.layersWithOutsidePointerEventsDisabled.delete(f),Jb())},[f,h]),v.useEffect(()=>{const D=()=>y({});return document.addEventListener(Ag,D),()=>document.removeEventListener(Ag,D)},[]),s.jsx(ht.div,{...u,ref:w,style:{pointerEvents:E?T?"auto":"none":void 0,...t.style},onFocusCapture:ot(t.onFocusCapture,O.onFocusCapture),onBlurCapture:ot(t.onBlurCapture,O.onBlurCapture),onPointerDownCapture:ot(t.onPointerDownCapture,I.onPointerDownCapture)})});zx.displayName=g5;var v5="DismissableLayerBranch",b5=v.forwardRef((t,e)=>{const n=v.useContext(gj),r=v.useRef(null),i=Tt(e,r);return v.useEffect(()=>{const a=r.current;if(a)return n.branches.add(a),()=>{n.branches.delete(a)}},[n.branches]),s.jsx(ht.div,{...t,ref:i})});b5.displayName=v5;function w5(t,e=globalThis==null?void 0:globalThis.document){const n=xa(t),r=v.useRef(!1),i=v.useRef(()=>{});return v.useEffect(()=>{const a=c=>{if(c.target&&!r.current){let u=function(){xj(x5,n,h,{discrete:!0})};const h={originalEvent:c};c.pointerType==="touch"?(e.removeEventListener("click",i.current),i.current=u,e.addEventListener("click",i.current,{once:!0})):u()}else e.removeEventListener("click",i.current);r.current=!1},o=window.setTimeout(()=>{e.addEventListener("pointerdown",a)},0);return()=>{window.clearTimeout(o),e.removeEventListener("pointerdown",a),e.removeEventListener("click",i.current)}},[e,n]),{onPointerDownCapture:()=>r.current=!0}}function N5(t,e=globalThis==null?void 0:globalThis.document){const n=xa(t),r=v.useRef(!1);return v.useEffect(()=>{const i=a=>{a.target&&!r.current&&xj(y5,n,{originalEvent:a},{discrete:!1})};return e.addEventListener("focusin",i),()=>e.removeEventListener("focusin",i)},[e,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function Jb(){const t=new CustomEvent(Ag);document.dispatchEvent(t)}function xj(t,e,n,{discrete:r}){const i=n.originalEvent.target,a=new CustomEvent(t,{bubbles:!1,cancelable:!0,detail:n});e&&i.addEventListener(t,e,{once:!0}),r?p5(i,a):i.dispatchEvent(a)}var Em="focusScope.autoFocusOnMount",Tm="focusScope.autoFocusOnUnmount",Yb={bubbles:!1,cancelable:!0},j5="FocusScope",$x=v.forwardRef((t,e)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=t,[c,u]=v.useState(null),h=xa(i),f=xa(a),m=v.useRef(null),g=Tt(e,N=>u(N)),y=v.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;v.useEffect(()=>{if(r){let N=function(E){if(y.paused||!c)return;const T=E.target;c.contains(T)?m.current=T:Qi(m.current,{select:!0})},b=function(E){if(y.paused||!c)return;const T=E.relatedTarget;T!==null&&(c.contains(T)||Qi(m.current,{select:!0}))},k=function(E){if(document.activeElement===document.body)for(const I of E)I.removedNodes.length>0&&Qi(c)};document.addEventListener("focusin",N),document.addEventListener("focusout",b);const C=new MutationObserver(k);return c&&C.observe(c,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",N),document.removeEventListener("focusout",b),C.disconnect()}}},[r,c,y.paused]),v.useEffect(()=>{if(c){Xb.add(y);const N=document.activeElement;if(!c.contains(N)){const k=new CustomEvent(Em,Yb);c.addEventListener(Em,h),c.dispatchEvent(k),k.defaultPrevented||(k5(M5(yj(c)),{select:!0}),document.activeElement===N&&Qi(c))}return()=>{c.removeEventListener(Em,h),setTimeout(()=>{const k=new CustomEvent(Tm,Yb);c.addEventListener(Tm,f),c.dispatchEvent(k),k.defaultPrevented||Qi(N??document.body,{select:!0}),c.removeEventListener(Tm,f),Xb.remove(y)},0)}}},[c,h,f,y]);const w=v.useCallback(N=>{if(!n&&!r||y.paused)return;const b=N.key==="Tab"&&!N.altKey&&!N.ctrlKey&&!N.metaKey,k=document.activeElement;if(b&&k){const C=N.currentTarget,[E,T]=S5(C);E&&T?!N.shiftKey&&k===T?(N.preventDefault(),n&&Qi(E,{select:!0})):N.shiftKey&&k===E&&(N.preventDefault(),n&&Qi(T,{select:!0})):k===C&&N.preventDefault()}},[n,r,y.paused]);return s.jsx(ht.div,{tabIndex:-1,...o,ref:g,onKeyDown:w})});$x.displayName=j5;function k5(t,{select:e=!1}={}){const n=document.activeElement;for(const r of t)if(Qi(r,{select:e}),document.activeElement!==n)return}function S5(t){const e=yj(t),n=Qb(e,t),r=Qb(e.reverse(),t);return[n,r]}function yj(t){const e=[],n=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const i=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||i?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)e.push(n.currentNode);return e}function Qb(t,e){for(const n of t)if(!C5(n,{upTo:e}))return n}function C5(t,{upTo:e}){if(getComputedStyle(t).visibility==="hidden")return!0;for(;t;){if(e!==void 0&&t===e)return!1;if(getComputedStyle(t).display==="none")return!0;t=t.parentElement}return!1}function E5(t){return t instanceof HTMLInputElement&&"select"in t}function Qi(t,{select:e=!1}={}){if(t&&t.focus){const n=document.activeElement;t.focus({preventScroll:!0}),t!==n&&E5(t)&&e&&t.select()}}var Xb=T5();function T5(){let t=[];return{add(e){const n=t[0];e!==n&&(n==null||n.pause()),t=Zb(t,e),t.unshift(e)},remove(e){var n;t=Zb(t,e),(n=t[0])==null||n.resume()}}}function Zb(t,e){const n=[...t],r=n.indexOf(e);return r!==-1&&n.splice(r,1),n}function M5(t){return t.filter(e=>e.tagName!=="A")}var A5="Portal",Fx=v.forwardRef((t,e)=>{var c;const{container:n,...r}=t,[i,a]=v.useState(!1);tr(()=>a(!0),[]);const o=n||i&&((c=globalThis==null?void 0:globalThis.document)==null?void 0:c.body);return o?AN.createPortal(s.jsx(ht.div,{...r,ref:e}),o):null});Fx.displayName=A5;function I5(t,e){return v.useReducer((n,r)=>e[n][r]??n,t)}var hd=t=>{const{present:e,children:n}=t,r=R5(e),i=typeof n=="function"?n({present:r.isPresent}):v.Children.only(n),a=Tt(r.ref,P5(i));return typeof n=="function"||r.isPresent?v.cloneElement(i,{ref:a}):null};hd.displayName="Presence";function R5(t){const[e,n]=v.useState(),r=v.useRef(null),i=v.useRef(t),a=v.useRef("none"),o=t?"mounted":"unmounted",[c,u]=I5(o,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return v.useEffect(()=>{const h=Su(r.current);a.current=c==="mounted"?h:"none"},[c]),tr(()=>{const h=r.current,f=i.current;if(f!==t){const g=a.current,y=Su(h);t?u("MOUNT"):y==="none"||(h==null?void 0:h.display)==="none"?u("UNMOUNT"):u(f&&g!==y?"ANIMATION_OUT":"UNMOUNT"),i.current=t}},[t,u]),tr(()=>{if(e){let h;const f=e.ownerDocument.defaultView??window,m=y=>{const N=Su(r.current).includes(CSS.escape(y.animationName));if(y.target===e&&N&&(u("ANIMATION_END"),!i.current)){const b=e.style.animationFillMode;e.style.animationFillMode="forwards",h=f.setTimeout(()=>{e.style.animationFillMode==="forwards"&&(e.style.animationFillMode=b)})}},g=y=>{y.target===e&&(a.current=Su(r.current))};return e.addEventListener("animationstart",g),e.addEventListener("animationcancel",m),e.addEventListener("animationend",m),()=>{f.clearTimeout(h),e.removeEventListener("animationstart",g),e.removeEventListener("animationcancel",m),e.removeEventListener("animationend",m)}}else u("ANIMATION_END")},[e,u]),{isPresent:["mounted","unmountSuspended"].includes(c),ref:v.useCallback(h=>{r.current=h?getComputedStyle(h):null,n(h)},[])}}function Su(t){return(t==null?void 0:t.animationName)||"none"}function P5(t){var r,i;let e=(r=Object.getOwnPropertyDescriptor(t.props,"ref"))==null?void 0:r.get,n=e&&"isReactWarning"in e&&e.isReactWarning;return n?t.ref:(e=(i=Object.getOwnPropertyDescriptor(t,"ref"))==null?void 0:i.get,n=e&&"isReactWarning"in e&&e.isReactWarning,n?t.props.ref:t.props.ref||t.ref)}var Mm=0;function vj(){v.useEffect(()=>{const t=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",t[0]??e1()),document.body.insertAdjacentElement("beforeend",t[1]??e1()),Mm++,()=>{Mm===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(e=>e.remove()),Mm--}},[])}function e1(){const t=document.createElement("span");return t.setAttribute("data-radix-focus-guard",""),t.tabIndex=0,t.style.outline="none",t.style.opacity="0",t.style.position="fixed",t.style.pointerEvents="none",t}var Ps=function(){return Ps=Object.assign||function(e){for(var n,r=1,i=arguments.length;r"u")return Y5;var e=Q5(t),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:e[0],top:e[1],right:e[2],gap:Math.max(0,r-n+e[2]-e[0])}},Z5=jj(),xl="data-scroll-locked",eR=function(t,e,n,r){var i=t.left,a=t.top,o=t.right,c=t.gap;return n===void 0&&(n="margin"),` .`.concat(D5,` { overflow: hidden `).concat(r,`; padding-right: `).concat(c,"px ").concat(r,`; diff --git a/soul-admin/dist/index.html b/soul-admin/dist/index.html index c8ca83d1..a7179ba4 100644 --- a/soul-admin/dist/index.html +++ b/soul-admin/dist/index.html @@ -4,7 +4,7 @@ 管理后台 - Soul创业派对 - + diff --git a/soul-admin/deploy_admin.py b/soul-admin/master.py similarity index 99% rename from soul-admin/deploy_admin.py rename to soul-admin/master.py index dc85a64f..c6995820 100644 --- a/soul-admin/deploy_admin.py +++ b/soul-admin/master.py @@ -48,7 +48,7 @@ def get_cfg(): def run_build(root): - """执行本地 pnpm build""" + """执行本地 pnpm build(使用 .env.production 正式环境配置)""" use_shell = sys.platform == "win32" dist_dir = os.path.join(root, "dist") index_html = os.path.join(dist_dir, "index.html") diff --git a/soul-admin/package.json b/soul-admin/package.json index fd81792a..d5ae9e91 100644 --- a/soul-admin/package.json +++ b/soul-admin/package.json @@ -6,6 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", + "build:dev": "tsc -b && vite build --mode development", "preview": "vite preview", "lint": "eslint . --ext ts,tsx" }, diff --git a/soul-admin/src/pages/content/ContentPage.tsx b/soul-admin/src/pages/content/ContentPage.tsx index a0e1f24f..296f8bd6 100644 --- a/soul-admin/src/pages/content/ContentPage.tsx +++ b/soul-admin/src/pages/content/ContentPage.tsx @@ -125,6 +125,11 @@ interface EditingSection { editionPremium?: boolean } +/** 去除名字中的括号及内容,名字不带符号(如 南风(管理) → 南风) */ +function sanitizeNameOrLabel(s: string): string { + return s.replace(/\s*[((][^))]*(\)|))?/g, '').trim() +} + // 在保存前自动把纯文本中的 @用户 / #标签 转成带 token / 配置的节点 function autoLinkContent(html: string, persons: PersonItem[], linkTags: LinkTagItem[]): string { if (!html || (!html.includes('@') && !html.includes('#'))) return html @@ -134,10 +139,10 @@ function autoLinkContent(html: string, persons: PersonItem[], linkTags: LinkTagI container.innerHTML = html const matchPerson = (name: string): PersonItem | undefined => - persons.find((p) => p.name === name) + persons.find((p) => p.name === name || sanitizeNameOrLabel(p.name) === sanitizeNameOrLabel(name)) const matchTag = (label: string): LinkTagItem | undefined => - linkTags.find((t) => t.label === label) + linkTags.find((t) => t.label === label || sanitizeNameOrLabel(t.label) === sanitizeNameOrLabel(label)) const processTextNode = (node: Text) => { const text = node.textContent || '' @@ -147,7 +152,8 @@ function autoLinkContent(html: string, persons: PersonItem[], linkTags: LinkTagI if (!parent) return const frag = document.createDocumentFragment() - const regex = /(@[^\s@#]+|#[^\s@#]+)/g + // 排除 <> 避免把 HTML 标签带入 @/# 匹配(如 @远志 只匹配 @远志) + const regex = /(@[^\s@#<>]+|#[^\s@#<>]+)/g let lastIndex = 0 let match: RegExpExecArray | null @@ -160,8 +166,8 @@ function autoLinkContent(html: string, persons: PersonItem[], linkTags: LinkTagI } if (full.startsWith('@')) { - const name = full.slice(1) - const person = matchPerson(name) + const rawName = full.slice(1) + const person = matchPerson(rawName) if (person) { const span = document.createElement('span') span.setAttribute('data-type', 'mention') @@ -173,8 +179,8 @@ function autoLinkContent(html: string, persons: PersonItem[], linkTags: LinkTagI frag.appendChild(document.createTextNode(full)) } } else if (full.startsWith('#')) { - const label = full.slice(1) - const tag = matchTag(label) + const rawLabel = full.slice(1) + const tag = matchTag(rawLabel) if (tag) { const span = document.createElement('span') span.setAttribute('data-type', 'linkTag') @@ -210,8 +216,17 @@ function autoLinkContent(html: string, persons: PersonItem[], linkTags: LinkTagI if (node.nodeType === Node.ELEMENT_NODE) { const el = node as HTMLElement const dataType = el.getAttribute('data-type') - // 已经是 mention/linkTag 的节点不再解析 - if (dataType === 'mention' || dataType === 'linkTag') return + // mention 节点:若 data-id 为空,按昵称匹配 persons 回填(修复 TipTap 插入时 id 丢失导致小程序 data-user-id 为空) + if (dataType === 'mention') { + const existingId = el.getAttribute('data-id') + const nickname = (el.getAttribute('data-label') || el.textContent || '').replace(/^@/, '').trim() + if ((!existingId || !existingId.trim()) && nickname) { + const person = matchPerson(nickname) + if (person?.id) el.setAttribute('data-id', person.id) + } + return + } + if (dataType === 'linkTag') return node.childNodes.forEach((child) => walk(child)) return } @@ -591,19 +606,20 @@ export function ContentPage() { /** 文章编辑时自动创建不存在的 @人物 和 #标签,返回合并后的列表供 autoLinkContent 使用 */ const ensureMentionsAndTags = useCallback( async (content: string): Promise<{ persons: PersonItem[]; linkTags: LinkTagItem[] }> => { - const regex = /(@[^\s@#]+|#[^\s@#]+)/g + // 排除 <> 避免把 HTML 标签带入 @/# 匹配 + const regex = /(@[^\s@#<>]+|#[^\s@#<>]+)/g const names = new Set() const labels = new Set() let m: RegExpExecArray | null while ((m = regex.exec(content)) !== null) { const full = m[0] - if (full.startsWith('@')) names.add(full.slice(1).trim()) - else if (full.startsWith('#')) labels.add(full.slice(1).trim()) + if (full.startsWith('@')) names.add(sanitizeNameOrLabel(full.slice(1))) + else if (full.startsWith('#')) labels.add(sanitizeNameOrLabel(full.slice(1))) } let personsCopy = [...persons] let linkTagsCopy = [...linkTags] for (const name of names) { - if (!name || personsCopy.some((p) => p.name === name)) continue + if (!name || personsCopy.some((p) => p.name === name || sanitizeNameOrLabel(p.name) === name)) continue try { const res = await post<{ success?: boolean @@ -625,7 +641,7 @@ export function ContentPage() { } } for (const label of labels) { - if (!label || linkTagsCopy.some((t) => t.label === label)) continue + if (!label || linkTagsCopy.some((t) => t.label === label || sanitizeNameOrLabel(t.label) === label)) continue try { const res = await post<{ success?: boolean @@ -2488,6 +2504,7 @@ export function ContentPage() {