@agentunion/kite 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +302 -0
- package/cli.js +119 -4
- package/core/dependency_checker.py +250 -0
- package/core/env_checker.py +490 -0
- package/dependencies_lock.json +128 -0
- package/extensions/agents/assistant/entry.py +111 -1
- package/extensions/agents/assistant/server.py +279 -215
- package/extensions/channels/acp_channel/entry.py +111 -1
- package/extensions/channels/acp_channel/module.md +23 -22
- package/extensions/channels/acp_channel/server.py +279 -215
- package/extensions/event_hub_bench/entry.py +107 -1
- package/extensions/services/backup/entry.py +306 -21
- package/extensions/services/backup/module.md +24 -22
- package/extensions/services/evol/auth_manager.py +443 -0
- package/extensions/services/evol/config.yaml +149 -0
- package/extensions/services/evol/config_loader.py +117 -0
- package/extensions/services/evol/entry.py +406 -0
- package/extensions/services/evol/evol_api.py +173 -0
- package/extensions/services/evol/evol_config.json5 +29 -0
- package/extensions/services/evol/migrate_tokens.py +122 -0
- package/extensions/services/evol/module.md +32 -0
- package/extensions/services/evol/pairing.py +250 -0
- package/extensions/services/evol/pairing_codes.jsonl +1 -0
- package/extensions/services/evol/relay.py +682 -0
- package/extensions/services/evol/relay_config.json5 +67 -0
- package/extensions/services/evol/routes/__init__.py +1 -0
- package/extensions/services/evol/routes/routes_management_ws.py +127 -0
- package/extensions/services/evol/routes/routes_rpc.py +89 -0
- package/extensions/services/evol/routes/routes_test.py +61 -0
- package/extensions/services/evol/server.py +875 -0
- package/extensions/services/evol/static/css/style.css +1200 -0
- package/extensions/services/evol/static/index.html +781 -0
- package/extensions/services/evol/static/index_evol.html +14 -0
- package/extensions/services/evol/static/js/app.js +6304 -0
- package/extensions/services/evol/static/js/auth.js +326 -0
- package/extensions/services/evol/static/js/dialog.js +285 -0
- package/extensions/services/evol/static/js/evol-app-fixed.js +50 -0
- package/extensions/services/evol/static/js/evol-app.js +1949 -0
- package/extensions/services/evol/static/js/evol-app.js.bak +1800 -0
- package/extensions/services/evol/static/js/kernel-client-example.js +228 -0
- package/extensions/services/evol/static/js/kernel-client.js +396 -0
- package/extensions/services/evol/static/js/main.js +141 -0
- package/extensions/services/evol/static/js/registry-tests.js +585 -0
- package/extensions/services/evol/static/js/stats.js +217 -0
- package/extensions/services/evol/static/js/token-manager.js +175 -0
- package/extensions/services/evol/static/pairing.html +248 -0
- package/extensions/services/evol/static/test_registry.html +262 -0
- package/extensions/services/evol/static/test_relay.html +462 -0
- package/extensions/services/evol/stats_manager.py +240 -0
- package/extensions/services/model_service/entry.py +167 -19
- package/extensions/services/model_service/module.md +21 -22
- package/extensions/services/proxy/.claude/settings.local.json +13 -0
- package/extensions/services/proxy/CHANGELOG_20260308.md +258 -0
- package/extensions/services/proxy/_fix_prints.py +133 -0
- package/extensions/services/proxy/_fix_prints2.py +87 -0
- package/extensions/services/proxy/agentcp/LICENCE +178 -0
- package/extensions/services/proxy/agentcp/README copy.md +85 -0
- package/extensions/services/proxy/agentcp/README.md +260 -0
- package/extensions/services/proxy/agentcp/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/agent.py +4 -0
- package/extensions/services/proxy/agentcp/agentcp.py +2494 -0
- package/extensions/services/proxy/agentcp/agentprofile.json +89 -0
- package/extensions/services/proxy/agentcp/ap/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/ap/ap_client.py +316 -0
- package/extensions/services/proxy/agentcp/assets/images/wechat_qr.png +0 -0
- package/extensions/services/proxy/agentcp/backup/metrics.json +31 -0
- package/extensions/services/proxy/agentcp/base/__init__.py +20 -0
- package/extensions/services/proxy/agentcp/base/auth_client.py +257 -0
- package/extensions/services/proxy/agentcp/base/client.py +112 -0
- package/extensions/services/proxy/agentcp/base/env.py +34 -0
- package/extensions/services/proxy/agentcp/base/html_util.py +336 -0
- package/extensions/services/proxy/agentcp/base/log.py +98 -0
- package/extensions/services/proxy/agentcp/ca/__init__.py +17 -0
- package/extensions/services/proxy/agentcp/ca/ca_client.py +414 -0
- package/extensions/services/proxy/agentcp/ca/ca_root.py +74 -0
- package/extensions/services/proxy/agentcp/context/__init__.py +20 -0
- package/extensions/services/proxy/agentcp/context/context.py +73 -0
- package/extensions/services/proxy/agentcp/context/exceptions.py +114 -0
- package/extensions/services/proxy/agentcp/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/create_profile_weather.py +125 -0
- package/extensions/services/proxy/agentcp/db/__init__.py +15 -0
- package/extensions/services/proxy/agentcp/db/db_mananger.py +550 -0
- package/extensions/services/proxy/agentcp/docs/UDP_HEARTBEAT_FIX_REPORT.md +265 -0
- package/extensions/services/proxy/agentcp/docs/heartbeat_issue_analysis.md +291 -0
- package/extensions/services/proxy/agentcp/file/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/file/file_client.py +141 -0
- package/extensions/services/proxy/agentcp/file/wss_binary_message.py +137 -0
- package/extensions/services/proxy/agentcp/hcp.py +299 -0
- package/extensions/services/proxy/agentcp/heartbeat/__init__.py +16 -0
- package/extensions/services/proxy/agentcp/heartbeat/heartbeat_client.py +360 -0
- package/extensions/services/proxy/agentcp/improved_scheduler.py +498 -0
- package/extensions/services/proxy/agentcp/llm_agent_utils.py +249 -0
- package/extensions/services/proxy/agentcp/llm_server.py +172 -0
- package/extensions/services/proxy/agentcp/mermaid.py +210 -0
- package/extensions/services/proxy/agentcp/message.py +149 -0
- package/extensions/services/proxy/agentcp/metrics.py +256 -0
- package/extensions/services/proxy/agentcp/monitoring/__init__.py +20 -0
- package/extensions/services/proxy/agentcp/monitoring/global_monitor.py +27 -0
- package/extensions/services/proxy/agentcp/monitoring/metrics_store.py +325 -0
- package/extensions/services/proxy/agentcp/monitoring/monitoring_service.py +269 -0
- package/extensions/services/proxy/agentcp/monitoring/sliding_window.py +222 -0
- package/extensions/services/proxy/agentcp/monitoring/standalone_reader.py +224 -0
- package/extensions/services/proxy/agentcp/msg/__init__.py +21 -0
- package/extensions/services/proxy/agentcp/msg/connection_manager.py +456 -0
- package/extensions/services/proxy/agentcp/msg/message_client.py +2058 -0
- package/extensions/services/proxy/agentcp/msg/message_serialize.py +263 -0
- package/extensions/services/proxy/agentcp/msg/open_ai_message.py +88 -0
- package/extensions/services/proxy/agentcp/msg/session_manager.py +1062 -0
- package/extensions/services/proxy/agentcp/msg/stream_client.py +267 -0
- package/extensions/services/proxy/agentcp/msg/websocket_file_receiver.py +89 -0
- package/extensions/services/proxy/agentcp/msg/ws_logger.py +685 -0
- package/extensions/services/proxy/agentcp/msg/wss_binary_message.py +137 -0
- package/extensions/services/proxy/agentcp/requirements.txt +7 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/README.md +37 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/agentprofile.json +89 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/create_profile.py +138 -0
- package/extensions/services/proxy/agentcp/samples/agent_graph/main.py +164 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/create_profile.py +123 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/llm/create_profile.py +129 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/llm/env.json +5 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/llm/main.py +146 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/main.py +123 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/readme.md +379 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/search/create_profile.py +129 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/search/main.py +28 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/tool/create_profile.py +129 -0
- package/extensions/services/proxy/agentcp/samples/agent_use/tool/main.py +20 -0
- package/extensions/services/proxy/agentcp/samples/ali_amap/README.md +97 -0
- package/extensions/services/proxy/agentcp/samples/ali_amap/amap_agent.py +88 -0
- package/extensions/services/proxy/agentcp/samples/ali_amap/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/agent/powershell.py +228 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/agent/software.py +63 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/agent/tools.py +36 -0
- package/extensions/services/proxy/agentcp/samples/compute_agent/browser_user.py +41 -0
- package/extensions/services/proxy/agentcp/samples/deepseek/README.md +79 -0
- package/extensions/services/proxy/agentcp/samples/deepseek/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/deepseek/deepseek.py +42 -0
- package/extensions/services/proxy/agentcp/samples/dify_chat/README.md +78 -0
- package/extensions/services/proxy/agentcp/samples/dify_chat/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/dify_chat/dify_chat.py +47 -0
- package/extensions/services/proxy/agentcp/samples/dify_workflow/README.md +78 -0
- package/extensions/services/proxy/agentcp/samples/dify_workflow/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/dify_workflow/dify_workflow.py +46 -0
- package/extensions/services/proxy/agentcp/samples/executor/README.md +44 -0
- package/extensions/services/proxy/agentcp/samples/executor/agentprofile.json +89 -0
- package/extensions/services/proxy/agentcp/samples/executor/create_profile.py +139 -0
- package/extensions/services/proxy/agentcp/samples/executor/main.py +160 -0
- package/extensions/services/proxy/agentcp/samples/filereader/README.md +45 -0
- package/extensions/services/proxy/agentcp/samples/filereader/agentprofile.json +90 -0
- package/extensions/services/proxy/agentcp/samples/filereader/create_profile.py +137 -0
- package/extensions/services/proxy/agentcp/samples/filereader/main.py +253 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/README.md +38 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/agentprofile.json +91 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/create_profile.py +138 -0
- package/extensions/services/proxy/agentcp/samples/filewriter/main.py +289 -0
- package/extensions/services/proxy/agentcp/samples/hcp/README.md +85 -0
- package/extensions/services/proxy/agentcp/samples/hcp/acp_weather_agent.zip +0 -0
- package/extensions/services/proxy/agentcp/samples/hcp/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/hcp/hcp.py +237 -0
- package/extensions/services/proxy/agentcp/samples/helloworld/README.md +68 -0
- package/extensions/services/proxy/agentcp/samples/helloworld/hello_world.py +40 -0
- package/extensions/services/proxy/agentcp/samples/llm_agent/MEADME.md +117 -0
- package/extensions/services/proxy/agentcp/samples/llm_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/llm_agent/qwen_agent.py +136 -0
- package/extensions/services/proxy/agentcp/samples/local_llm_agent/README.md +90 -0
- package/extensions/services/proxy/agentcp/samples/local_llm_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/local_llm_agent/main.py +49 -0
- package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/README.md +55 -0
- package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/main.py +23 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/README.md +103 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/main.py +69 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/README.md +58 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/main.py +25 -0
- package/extensions/services/proxy/agentcp/samples/qwen3/README.md +71 -0
- package/extensions/services/proxy/agentcp/samples/qwen3/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/qwen3/qwen3.py +37 -0
- package/extensions/services/proxy/agentcp/samples/qwen3_tools/README.md +133 -0
- package/extensions/services/proxy/agentcp/samples/qwen3_tools/create_profile.py +126 -0
- package/extensions/services/proxy/agentcp/samples/qwen3_tools/qwen3_tools.py +98 -0
- package/extensions/services/proxy/agentcp/samples/search/create_profile_qwen.py +125 -0
- package/extensions/services/proxy/agentcp/samples/search/create_profile_search.py +125 -0
- package/extensions/services/proxy/agentcp/samples/search/qwen_agent.py +136 -0
- package/extensions/services/proxy/agentcp/samples/search/search_agent.py +170 -0
- package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/README.md +89 -0
- package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/create_profile.py +125 -0
- package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/main.py +44 -0
- package/extensions/services/proxy/agentcp/utils/__init__.py +15 -0
- package/extensions/services/proxy/agentcp/utils/file_util.py +117 -0
- package/extensions/services/proxy/agentcp/utils/proxy_bypass.py +99 -0
- package/extensions/services/proxy/agentcp/workflow.py +203 -0
- package/extensions/services/proxy/console_auth.py +109 -0
- package/extensions/services/proxy/evol/__init__.py +1 -0
- package/extensions/services/proxy/evol/config.py +37 -0
- package/extensions/services/proxy/evol/http/__init__.py +1 -0
- package/extensions/services/proxy/evol/http/async_http.py +551 -0
- package/extensions/services/proxy/evol/log.py +28 -0
- package/extensions/services/proxy/evol/presenter/__init__.py +2 -0
- package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +1031 -0
- package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +106 -0
- package/extensions/services/proxy/evol/presenter/configPresenter.py +1281 -0
- package/extensions/services/proxy/evol/presenter/userPresenter.py +477 -0
- package/extensions/services/proxy/evol/server/__init__.py +1 -0
- package/extensions/services/proxy/evol/server/claude_proxy_async.py +3430 -0
- package/extensions/services/proxy/evol/server/openclaw_proxy.py +1861 -0
- package/extensions/services/proxy/evol/server/proxy_config.py +15 -0
- package/extensions/services/proxy/evol/server/proxy_engine.py +501 -0
- package/extensions/services/proxy/evol/version.py +24 -0
- package/extensions/services/proxy/logs/websocket.log +260 -0
- package/extensions/services/proxy/main.py +240 -0
- package/extensions/services/proxy/requirements.txt +13 -0
- package/extensions/services/proxy/server.py +271 -0
- package/extensions/services/watchdog/entry.py +215 -26
- package/extensions/services/watchdog/module.md +1 -0
- package/extensions/services/watchdog/monitor.py +178 -38
- package/extensions/services/web/WEBSOCKET_STATUS.md +143 -0
- package/extensions/services/web/config_example.py +35 -0
- package/extensions/services/web/config_loader.py +110 -0
- package/extensions/services/web/entry.py +114 -26
- package/extensions/services/web/module.md +35 -24
- package/extensions/services/web/pairing.py +250 -0
- package/extensions/services/web/pairing_codes.jsonl +16 -0
- package/extensions/services/web/relay.py +643 -0
- package/extensions/services/web/relay_config.json5 +67 -0
- package/extensions/services/web/routes/routes_management_ws.py +127 -0
- package/extensions/services/web/routes/routes_rpc.py +89 -0
- package/extensions/services/web/routes/routes_test.py +61 -0
- package/extensions/services/web/routes/schemas.py +0 -22
- package/extensions/services/web/server.py +434 -99
- package/extensions/services/web/static/css/style.css +67 -28
- package/extensions/services/web/static/index.html +234 -44
- package/extensions/services/web/static/js/app.js +1335 -48
- package/extensions/services/web/static/js/kernel-client-example.js +161 -0
- package/extensions/services/web/static/js/kernel-client.js +383 -0
- package/extensions/services/web/static/js/registry-tests.js +558 -0
- package/extensions/services/web/static/js/token-manager.js +175 -0
- package/extensions/services/web/static/pairing.html +248 -0
- package/extensions/services/web/static/test_registry.html +262 -0
- package/extensions/services/web/web_config.json5 +29 -0
- package/kernel/entry.py +120 -32
- package/kernel/event_hub.py +141 -16
- package/kernel/module.md +60 -33
- package/kernel/registry_store.py +45 -36
- package/kernel/rpc_router.py +152 -59
- package/kernel/server.py +322 -26
- package/kite_cli/__init__.py +3 -0
- package/kite_cli/__main__.py +5 -0
- package/kite_cli/commands/__init__.py +1 -0
- package/kite_cli/commands/clean.py +101 -0
- package/kite_cli/commands/deps_install.py +67 -0
- package/kite_cli/commands/doctor.py +35 -0
- package/kite_cli/commands/env_check.py +45 -0
- package/kite_cli/commands/history.py +111 -0
- package/kite_cli/commands/info.py +96 -0
- package/kite_cli/commands/install.py +313 -0
- package/kite_cli/commands/list.py +143 -0
- package/kite_cli/commands/log.py +81 -0
- package/kite_cli/commands/prepare.py +49 -0
- package/kite_cli/commands/rollback.py +88 -0
- package/kite_cli/commands/search.py +73 -0
- package/kite_cli/commands/uninstall.py +85 -0
- package/kite_cli/commands/update.py +118 -0
- package/kite_cli/commands/venv_setup.py +56 -0
- package/kite_cli/core/__init__.py +1 -0
- package/kite_cli/core/checker.py +142 -0
- package/kite_cli/core/dependency.py +229 -0
- package/kite_cli/core/downloader.py +209 -0
- package/kite_cli/core/install_info.py +40 -0
- package/kite_cli/core/tool_installer.py +397 -0
- package/kite_cli/core/validator.py +78 -0
- package/kite_cli/main.py +317 -0
- package/kite_cli/utils/__init__.py +1 -0
- package/kite_cli/utils/i18n.py +252 -0
- package/kite_cli/utils/interactive.py +63 -0
- package/kite_cli/utils/operation_log.py +77 -0
- package/kite_cli/utils/paths.py +34 -0
- package/kite_cli/utils/version.py +308 -0
- package/launcher/entry.py +1124 -178
- package/launcher/logging_setup.py +104 -0
- package/launcher/module.md +46 -37
- package/launcher/module_scanner.py +11 -1
- package/main.py +4 -1
- package/package.json +9 -1
- package/python_version.json +4 -0
- package/requirements.txt +38 -0
- package/scripts/env-manager.js +328 -0
- package/scripts/plan_manager.py +315 -0
- package/scripts/python-env.js +79 -0
- package/scripts/scan_dependencies.py +461 -0
- package/scripts/setup-python-env.js +191 -0
- package/extensions/services/web/routes/routes_modules.py +0 -249
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// Auth functions
|
|
2
|
+
|
|
3
|
+
let countdown = 0;
|
|
4
|
+
let countdownTimer = null;
|
|
5
|
+
|
|
6
|
+
async function sendSMS() {
|
|
7
|
+
const phone = document.getElementById('phone').value.trim();
|
|
8
|
+
const errorMsg = document.getElementById('error-msg');
|
|
9
|
+
const sendBtn = document.getElementById('send-code-btn');
|
|
10
|
+
|
|
11
|
+
if (!phone || !/^1[3-9]\d{9}$/.test(phone)) {
|
|
12
|
+
errorMsg.textContent = '请输入正确的手机号';
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
errorMsg.textContent = '';
|
|
17
|
+
sendBtn.disabled = true;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const response = await fetch('/api/send_sms', {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23
|
+
body: JSON.stringify({ phone })
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const result = await response.json();
|
|
27
|
+
|
|
28
|
+
if (result.success) {
|
|
29
|
+
startCountdown();
|
|
30
|
+
} else {
|
|
31
|
+
errorMsg.textContent = result.msg || '发送失败';
|
|
32
|
+
sendBtn.disabled = false;
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
errorMsg.textContent = '网络错误';
|
|
36
|
+
sendBtn.disabled = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function startCountdown() {
|
|
41
|
+
countdown = 60;
|
|
42
|
+
const sendBtn = document.getElementById('send-code-btn');
|
|
43
|
+
|
|
44
|
+
countdownTimer = setInterval(() => {
|
|
45
|
+
countdown--;
|
|
46
|
+
sendBtn.textContent = `${countdown}秒后重试`;
|
|
47
|
+
|
|
48
|
+
if (countdown <= 0) {
|
|
49
|
+
clearInterval(countdownTimer);
|
|
50
|
+
sendBtn.textContent = '发送验证码';
|
|
51
|
+
sendBtn.disabled = false;
|
|
52
|
+
}
|
|
53
|
+
}, 1000);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function verifyLogin() {
|
|
57
|
+
const phone = document.getElementById('phone').value.trim();
|
|
58
|
+
const code = document.getElementById('code').value.trim();
|
|
59
|
+
const errorMsg = document.getElementById('error-msg');
|
|
60
|
+
const loginBtn = document.getElementById('login-btn');
|
|
61
|
+
|
|
62
|
+
if (!phone || !code) {
|
|
63
|
+
errorMsg.textContent = '请输入手机号和验证码';
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!/^\d{6}$/.test(code)) {
|
|
68
|
+
errorMsg.textContent = '验证码格式不正确';
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
errorMsg.textContent = '';
|
|
73
|
+
loginBtn.disabled = true;
|
|
74
|
+
loginBtn.textContent = '登录中...';
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const deviceInfo = {
|
|
78
|
+
deviceId: getDeviceId(),
|
|
79
|
+
deviceName: getDeviceName()
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const response = await fetch('/api/verify_sms', {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
headers: { 'Content-Type': 'application/json' },
|
|
85
|
+
body: JSON.stringify({ phone, code, deviceInfo })
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const result = await response.json();
|
|
89
|
+
|
|
90
|
+
if (result.success) {
|
|
91
|
+
localStorage.setItem('evol_kite_token', result.kiteToken);
|
|
92
|
+
showUserInfo(result.userInfo);
|
|
93
|
+
} else {
|
|
94
|
+
errorMsg.textContent = result.msg || '登录失败';
|
|
95
|
+
loginBtn.disabled = false;
|
|
96
|
+
loginBtn.textContent = '登录';
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
errorMsg.textContent = '网络错误';
|
|
100
|
+
loginBtn.disabled = false;
|
|
101
|
+
loginBtn.textContent = '登录';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function loadUserInfo() {
|
|
106
|
+
const kiteToken = localStorage.getItem('evol_kite_token');
|
|
107
|
+
if (!kiteToken) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const response = await fetch('/api/get_user_info', {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: { 'Content-Type': 'application/json' },
|
|
115
|
+
body: JSON.stringify({ kiteToken })
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const result = await response.json();
|
|
119
|
+
|
|
120
|
+
if (result.success) {
|
|
121
|
+
showUserInfo(result.data);
|
|
122
|
+
} else if (result.code === 'INVALID_TOKEN') {
|
|
123
|
+
// Token 失效,但不自动清除,让用户看到提示
|
|
124
|
+
console.warn('Evol token invalid, but kiteToken still valid');
|
|
125
|
+
// 抛出错误让调用方处理
|
|
126
|
+
throw new Error('EVOL_TOKEN_INVALID');
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('Failed to load user info:', error);
|
|
130
|
+
// 重新抛出错误让调用方处理
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function refreshUserInfo() {
|
|
136
|
+
const btn = event.target;
|
|
137
|
+
btn.disabled = true;
|
|
138
|
+
btn.textContent = '刷新中...';
|
|
139
|
+
|
|
140
|
+
await loadUserInfo();
|
|
141
|
+
|
|
142
|
+
btn.disabled = false;
|
|
143
|
+
btn.textContent = '刷新';
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function showUserInfo(data) {
|
|
147
|
+
document.getElementById('login-form').classList.add('hidden');
|
|
148
|
+
document.getElementById('user-info').classList.remove('hidden');
|
|
149
|
+
|
|
150
|
+
const userInfo = data.userInfo || data;
|
|
151
|
+
const accountInfo = data.accountInfo || {};
|
|
152
|
+
const teamInfo = data.teamInfo || {};
|
|
153
|
+
const gatewayInfo = data.gatewayInfo || {};
|
|
154
|
+
const creditsPackage = accountInfo.creditsPackageSummary || {};
|
|
155
|
+
|
|
156
|
+
// 计算积分百分比
|
|
157
|
+
const creditsPercent = accountInfo.creditsLimit > 0
|
|
158
|
+
? ((accountInfo.credits / accountInfo.creditsLimit) * 100).toFixed(1)
|
|
159
|
+
: 0;
|
|
160
|
+
|
|
161
|
+
// 计算预计恢复时间
|
|
162
|
+
const remainingCredits = accountInfo.creditsLimit - accountInfo.credits;
|
|
163
|
+
const recoveryHours = accountInfo.creditsRecoveryRate > 0
|
|
164
|
+
? (remainingCredits / accountInfo.creditsRecoveryRate).toFixed(1)
|
|
165
|
+
: 0;
|
|
166
|
+
|
|
167
|
+
const html = `
|
|
168
|
+
<div class="panel">
|
|
169
|
+
<h3 class="panel-title">👤 用户信息</h3>
|
|
170
|
+
<div class="breakdown-list">
|
|
171
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
|
|
172
|
+
<div>
|
|
173
|
+
<div class="info-label">昵称</div>
|
|
174
|
+
<div class="info-value">${userInfo.nickName || '未设置'}</div>
|
|
175
|
+
</div>
|
|
176
|
+
<div>
|
|
177
|
+
<div class="info-label">手机</div>
|
|
178
|
+
<div class="info-value">${userInfo.phone}</div>
|
|
179
|
+
</div>
|
|
180
|
+
<div>
|
|
181
|
+
<div class="info-label">用户ID</div>
|
|
182
|
+
<div class="info-value">${userInfo.userId || '-'}</div>
|
|
183
|
+
</div>
|
|
184
|
+
<div>
|
|
185
|
+
<div class="info-label">AID</div>
|
|
186
|
+
<div class="info-value" style="font-size: 12px;">${userInfo.aid || '-'}</div>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div class="panel">
|
|
193
|
+
<h3 class="panel-title">💎 账户信息</h3>
|
|
194
|
+
<div class="breakdown-list">
|
|
195
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
|
|
196
|
+
<div>
|
|
197
|
+
<div class="info-label">VIP类型</div>
|
|
198
|
+
<div class="info-value">${accountInfo.vipTypeName || '-'}</div>
|
|
199
|
+
</div>
|
|
200
|
+
<div>
|
|
201
|
+
<div class="info-label">VIP到期</div>
|
|
202
|
+
<div class="info-value">${accountInfo.vipExpireTime ? new Date(accountInfo.vipExpireTime).toLocaleDateString() : '-'}</div>
|
|
203
|
+
</div>
|
|
204
|
+
<div>
|
|
205
|
+
<div class="info-label">剩余天数</div>
|
|
206
|
+
<div class="info-value">${accountInfo.vipRemainingDays || 0} 天</div>
|
|
207
|
+
</div>
|
|
208
|
+
<div>
|
|
209
|
+
<div class="info-label">账户余额</div>
|
|
210
|
+
<div class="info-value">¥${accountInfo.balance || 0}</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div class="panel">
|
|
217
|
+
<h3 class="panel-title">⚡ 积分信息</h3>
|
|
218
|
+
<div style="margin-bottom: 16px;">
|
|
219
|
+
<div class="info-label" style="margin-bottom: 8px;">当前积分: ${accountInfo.credits || 0} / ${accountInfo.creditsLimit || 0} (${creditsPercent}%)</div>
|
|
220
|
+
<div style="width: 100%; height: 20px; background: var(--gray-200); border-radius: 10px; overflow: hidden;">
|
|
221
|
+
<div style="height: 100%; width: ${creditsPercent}%; background: linear-gradient(90deg, #1890ff, #40a9ff); transition: width 0.3s;"></div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
<div class="breakdown-list">
|
|
225
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
|
|
226
|
+
<div>
|
|
227
|
+
<div class="info-label">恢复速率</div>
|
|
228
|
+
<div class="info-value">${accountInfo.creditsRecoveryRate || 0} 积分/小时</div>
|
|
229
|
+
</div>
|
|
230
|
+
<div>
|
|
231
|
+
<div class="info-label">预计恢复满</div>
|
|
232
|
+
<div class="info-value">${recoveryHours} 小时</div>
|
|
233
|
+
</div>
|
|
234
|
+
<div>
|
|
235
|
+
<div class="info-label">最后恢复</div>
|
|
236
|
+
<div class="info-value" style="font-size: 12px;">${accountInfo.lastRecoveryTime ? new Date(accountInfo.lastRecoveryTime).toLocaleString() : '-'}</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<div class="panel">
|
|
243
|
+
<h3 class="panel-title">📦 积分包详情</h3>
|
|
244
|
+
<div class="breakdown-list">
|
|
245
|
+
<ul class="breakdown-list">
|
|
246
|
+
<li><span class="breakdown-label">总包数</span><span class="breakdown-value">${creditsPackage.totalPackageCount || 0}</span></li>
|
|
247
|
+
<li><span class="breakdown-label">通用积分</span><span class="breakdown-value">${creditsPackage.generalCredits || 0}</span></li>
|
|
248
|
+
<li><span class="breakdown-label">Chatbot</span><span class="breakdown-value">${creditsPackage.chatbotCredits || 0}</span></li>
|
|
249
|
+
<li><span class="breakdown-label">Codex</span><span class="breakdown-value">${creditsPackage.codexCredits || 0}</span></li>
|
|
250
|
+
<li><span class="breakdown-label">Claude Code</span><span class="breakdown-value">${creditsPackage.claudeCodeCredits || 0}</span></li>
|
|
251
|
+
<li><span class="breakdown-label">Gemini</span><span class="breakdown-value">${creditsPackage.geminiCredits || 0}</span></li>
|
|
252
|
+
<li><span class="breakdown-label">OpenClaw</span><span class="breakdown-value">${creditsPackage.openclawCredits || 0}</span></li>
|
|
253
|
+
</ul>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
|
|
257
|
+
<div class="panel">
|
|
258
|
+
<h3 class="panel-title">👥 团队信息</h3>
|
|
259
|
+
<div class="breakdown-list">
|
|
260
|
+
<ul class="breakdown-list">
|
|
261
|
+
<li><span class="breakdown-label">当前团队</span><span class="breakdown-value">${teamInfo.currentTeamName || '个人账户'}</span></li>
|
|
262
|
+
<li><span class="breakdown-label">角色</span><span class="breakdown-value">${getRoleName(teamInfo.currentTeamRole)}</span></li>
|
|
263
|
+
<li><span class="breakdown-label">所属团队数</span><span class="breakdown-value">${teamInfo.teams ? teamInfo.teams.length : 0}</span></li>
|
|
264
|
+
</ul>
|
|
265
|
+
${teamInfo.teams && teamInfo.teams.length > 0 ? `
|
|
266
|
+
<details style="margin-top: 12px;">
|
|
267
|
+
<summary style="cursor: pointer; color: var(--primary); font-size: 13px;">查看所有团队</summary>
|
|
268
|
+
<ul style="margin-top: 8px; list-style: none;">
|
|
269
|
+
${teamInfo.teams.map(t => `
|
|
270
|
+
<li style="padding: 4px 0; font-size: 13px; color: var(--gray-600);">
|
|
271
|
+
${t.teamName} - ${getRoleName(t.memberRole)} (${t.memberCount}人)
|
|
272
|
+
</li>
|
|
273
|
+
`).join('')}
|
|
274
|
+
</ul>
|
|
275
|
+
</details>
|
|
276
|
+
` : ''}
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
|
|
280
|
+
<div class="panel">
|
|
281
|
+
<h3 class="panel-title">🔌 网关信息</h3>
|
|
282
|
+
<div class="breakdown-list">
|
|
283
|
+
<ul class="breakdown-list">
|
|
284
|
+
<li><span class="breakdown-label">网关名称</span><span class="breakdown-value">${gatewayInfo.gatewayName || '-'}</span></li>
|
|
285
|
+
<li><span class="breakdown-label">API Key</span><span class="breakdown-value" style="font-family: monospace; font-size: 12px;">${gatewayInfo.apiKey || '-'}</span></li>
|
|
286
|
+
<li><span class="breakdown-label">Base URL</span><span class="breakdown-value" style="font-family: monospace; font-size: 12px;">${gatewayInfo.modelBaseUrl || '-'}</span></li>
|
|
287
|
+
<li><span class="breakdown-label">状态</span><span class="breakdown-value">${gatewayInfo.apiKeyEnabled ? '<span class="badge-success">✅ 已启用</span>' : '<span class="badge-error">❌ 已禁用</span>'}</span></li>
|
|
288
|
+
</ul>
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
`;
|
|
292
|
+
|
|
293
|
+
document.getElementById('user-details').innerHTML = html;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function getRoleName(role) {
|
|
297
|
+
const roles = {
|
|
298
|
+
'0': '创建者',
|
|
299
|
+
'1': '管理员',
|
|
300
|
+
'2': '普通成员'
|
|
301
|
+
};
|
|
302
|
+
return roles[role] || '未知';
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function logout() {
|
|
306
|
+
localStorage.removeItem('evol_kite_token');
|
|
307
|
+
document.getElementById('login-form').classList.remove('hidden');
|
|
308
|
+
document.getElementById('user-info').classList.add('hidden');
|
|
309
|
+
document.getElementById('phone').value = '';
|
|
310
|
+
document.getElementById('code').value = '';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function getDeviceId() {
|
|
314
|
+
let deviceId = localStorage.getItem('evol_device_id');
|
|
315
|
+
if (!deviceId) {
|
|
316
|
+
deviceId = 'device_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
|
|
317
|
+
localStorage.setItem('evol_device_id', deviceId);
|
|
318
|
+
}
|
|
319
|
+
return deviceId;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function getDeviceName() {
|
|
323
|
+
return navigator.userAgent.includes('Windows') ? 'Windows PC' :
|
|
324
|
+
navigator.userAgent.includes('Mac') ? 'Mac' :
|
|
325
|
+
navigator.userAgent.includes('Linux') ? 'Linux' : 'Unknown';
|
|
326
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自定义对话框组件
|
|
3
|
+
* 替代系统的 alert() 和 confirm()
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class Dialog {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.container = null;
|
|
9
|
+
this.tipContainer = null;
|
|
10
|
+
this.init();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
init() {
|
|
14
|
+
// 创建对话框容器
|
|
15
|
+
this.container = document.createElement('div');
|
|
16
|
+
this.container.id = 'custom-dialog-container';
|
|
17
|
+
this.container.style.cssText = `
|
|
18
|
+
position: fixed;
|
|
19
|
+
top: 0;
|
|
20
|
+
left: 0;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 100%;
|
|
23
|
+
background: rgba(0, 0, 0, 0.5);
|
|
24
|
+
display: none;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
z-index: 10000;
|
|
28
|
+
`;
|
|
29
|
+
document.body.appendChild(this.container);
|
|
30
|
+
|
|
31
|
+
// 创建 tip 提示容器
|
|
32
|
+
this.tipContainer = document.createElement('div');
|
|
33
|
+
this.tipContainer.id = 'custom-tip-container';
|
|
34
|
+
this.tipContainer.style.cssText = `
|
|
35
|
+
position: fixed;
|
|
36
|
+
top: 80px;
|
|
37
|
+
left: 50%;
|
|
38
|
+
transform: translateX(-50%);
|
|
39
|
+
z-index: 10001;
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
`;
|
|
42
|
+
document.body.appendChild(this.tipContainer);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
show(options) {
|
|
46
|
+
const {
|
|
47
|
+
title = '提示',
|
|
48
|
+
message = '',
|
|
49
|
+
type = 'alert', // 'alert' or 'confirm'
|
|
50
|
+
confirmText = '确定',
|
|
51
|
+
cancelText = '取消',
|
|
52
|
+
onConfirm = () => {},
|
|
53
|
+
onCancel = () => {}
|
|
54
|
+
} = options;
|
|
55
|
+
|
|
56
|
+
// 创建对话框内容
|
|
57
|
+
const dialog = document.createElement('div');
|
|
58
|
+
dialog.style.cssText = `
|
|
59
|
+
background: white;
|
|
60
|
+
border-radius: 8px;
|
|
61
|
+
padding: 24px;
|
|
62
|
+
min-width: 320px;
|
|
63
|
+
max-width: 480px;
|
|
64
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
// 标题
|
|
68
|
+
const titleEl = document.createElement('h3');
|
|
69
|
+
titleEl.textContent = title;
|
|
70
|
+
titleEl.style.cssText = `
|
|
71
|
+
margin: 0 0 16px 0;
|
|
72
|
+
font-size: 18px;
|
|
73
|
+
font-weight: 600;
|
|
74
|
+
color: #333;
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
// 消息
|
|
78
|
+
const messageEl = document.createElement('p');
|
|
79
|
+
messageEl.textContent = message;
|
|
80
|
+
messageEl.style.cssText = `
|
|
81
|
+
margin: 0 0 24px 0;
|
|
82
|
+
font-size: 14px;
|
|
83
|
+
color: #666;
|
|
84
|
+
line-height: 1.5;
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
// 按钮容器
|
|
88
|
+
const buttonsEl = document.createElement('div');
|
|
89
|
+
buttonsEl.style.cssText = `
|
|
90
|
+
display: flex;
|
|
91
|
+
justify-content: flex-end;
|
|
92
|
+
gap: 12px;
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
// 取消按钮(仅 confirm 类型显示)
|
|
96
|
+
if (type === 'confirm') {
|
|
97
|
+
const cancelBtn = document.createElement('button');
|
|
98
|
+
cancelBtn.textContent = cancelText;
|
|
99
|
+
cancelBtn.style.cssText = `
|
|
100
|
+
padding: 8px 16px;
|
|
101
|
+
border: 1px solid #ddd;
|
|
102
|
+
border-radius: 4px;
|
|
103
|
+
background: white;
|
|
104
|
+
color: #666;
|
|
105
|
+
font-size: 14px;
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
transition: all 0.2s;
|
|
108
|
+
`;
|
|
109
|
+
cancelBtn.onmouseover = () => {
|
|
110
|
+
cancelBtn.style.background = '#f5f5f5';
|
|
111
|
+
};
|
|
112
|
+
cancelBtn.onmouseout = () => {
|
|
113
|
+
cancelBtn.style.background = 'white';
|
|
114
|
+
};
|
|
115
|
+
cancelBtn.onclick = () => {
|
|
116
|
+
this.hide();
|
|
117
|
+
onCancel();
|
|
118
|
+
};
|
|
119
|
+
buttonsEl.appendChild(cancelBtn);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 确定按钮
|
|
123
|
+
const confirmBtn = document.createElement('button');
|
|
124
|
+
confirmBtn.textContent = confirmText;
|
|
125
|
+
confirmBtn.style.cssText = `
|
|
126
|
+
padding: 8px 16px;
|
|
127
|
+
border: none;
|
|
128
|
+
border-radius: 4px;
|
|
129
|
+
background: #007bff;
|
|
130
|
+
color: white;
|
|
131
|
+
font-size: 14px;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
transition: all 0.2s;
|
|
134
|
+
`;
|
|
135
|
+
confirmBtn.onmouseover = () => {
|
|
136
|
+
confirmBtn.style.background = '#0056b3';
|
|
137
|
+
};
|
|
138
|
+
confirmBtn.onmouseout = () => {
|
|
139
|
+
confirmBtn.style.background = '#007bff';
|
|
140
|
+
};
|
|
141
|
+
confirmBtn.onclick = () => {
|
|
142
|
+
this.hide();
|
|
143
|
+
onConfirm();
|
|
144
|
+
};
|
|
145
|
+
buttonsEl.appendChild(confirmBtn);
|
|
146
|
+
|
|
147
|
+
// 组装对话框
|
|
148
|
+
dialog.appendChild(titleEl);
|
|
149
|
+
dialog.appendChild(messageEl);
|
|
150
|
+
dialog.appendChild(buttonsEl);
|
|
151
|
+
|
|
152
|
+
// 清空容器并添加新对话框
|
|
153
|
+
this.container.innerHTML = '';
|
|
154
|
+
this.container.appendChild(dialog);
|
|
155
|
+
this.container.style.display = 'flex';
|
|
156
|
+
|
|
157
|
+
// 点击背景关闭(仅 alert 类型)
|
|
158
|
+
if (type === 'alert') {
|
|
159
|
+
this.container.onclick = (e) => {
|
|
160
|
+
if (e.target === this.container) {
|
|
161
|
+
this.hide();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
hide() {
|
|
168
|
+
this.container.style.display = 'none';
|
|
169
|
+
this.container.innerHTML = '';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
alert(message, title = '提示') {
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
this.show({
|
|
175
|
+
title,
|
|
176
|
+
message,
|
|
177
|
+
type: 'alert',
|
|
178
|
+
onConfirm: resolve
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
confirm(message, title = '确认') {
|
|
184
|
+
return new Promise((resolve) => {
|
|
185
|
+
this.show({
|
|
186
|
+
title,
|
|
187
|
+
message,
|
|
188
|
+
type: 'confirm',
|
|
189
|
+
onConfirm: () => resolve(true),
|
|
190
|
+
onCancel: () => resolve(false)
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
tip(message, type = 'success', duration = 2000) {
|
|
196
|
+
const tip = document.createElement('div');
|
|
197
|
+
|
|
198
|
+
// 根据类型设置颜色
|
|
199
|
+
const colors = {
|
|
200
|
+
success: { bg: '#52c41a', icon: '✓' },
|
|
201
|
+
error: { bg: '#ff4d4f', icon: '✗' },
|
|
202
|
+
warning: { bg: '#faad14', icon: '⚠' },
|
|
203
|
+
info: { bg: '#1890ff', icon: 'ℹ' }
|
|
204
|
+
};
|
|
205
|
+
const color = colors[type] || colors.info;
|
|
206
|
+
|
|
207
|
+
tip.style.cssText = `
|
|
208
|
+
background: ${color.bg};
|
|
209
|
+
color: white;
|
|
210
|
+
padding: 12px 20px;
|
|
211
|
+
border-radius: 4px;
|
|
212
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
213
|
+
margin-bottom: 12px;
|
|
214
|
+
display: flex;
|
|
215
|
+
align-items: center;
|
|
216
|
+
gap: 8px;
|
|
217
|
+
font-size: 14px;
|
|
218
|
+
pointer-events: auto;
|
|
219
|
+
animation: tipSlideIn 0.3s ease-out;
|
|
220
|
+
`;
|
|
221
|
+
|
|
222
|
+
tip.innerHTML = `
|
|
223
|
+
<span style="font-size: 16px; font-weight: bold;">${color.icon}</span>
|
|
224
|
+
<span>${message}</span>
|
|
225
|
+
`;
|
|
226
|
+
|
|
227
|
+
// 添加动画样式
|
|
228
|
+
if (!document.getElementById('tip-animation-style')) {
|
|
229
|
+
const style = document.createElement('style');
|
|
230
|
+
style.id = 'tip-animation-style';
|
|
231
|
+
style.textContent = `
|
|
232
|
+
@keyframes tipSlideIn {
|
|
233
|
+
from {
|
|
234
|
+
opacity: 0;
|
|
235
|
+
transform: translateY(-20px);
|
|
236
|
+
}
|
|
237
|
+
to {
|
|
238
|
+
opacity: 1;
|
|
239
|
+
transform: translateY(0);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
@keyframes tipSlideOut {
|
|
243
|
+
from {
|
|
244
|
+
opacity: 1;
|
|
245
|
+
transform: translateY(0);
|
|
246
|
+
}
|
|
247
|
+
to {
|
|
248
|
+
opacity: 0;
|
|
249
|
+
transform: translateY(-20px);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
document.head.appendChild(style);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
this.tipContainer.appendChild(tip);
|
|
257
|
+
|
|
258
|
+
// 自动移除
|
|
259
|
+
setTimeout(() => {
|
|
260
|
+
tip.style.animation = 'tipSlideOut 0.3s ease-out';
|
|
261
|
+
setTimeout(() => {
|
|
262
|
+
tip.remove();
|
|
263
|
+
}, 300);
|
|
264
|
+
}, duration);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
success(message, duration = 2000) {
|
|
268
|
+
this.tip(message, 'success', duration);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
error(message, duration = 3000) {
|
|
272
|
+
this.tip(message, 'error', duration);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
warning(message, duration = 2500) {
|
|
276
|
+
this.tip(message, 'warning', duration);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
info(message, duration = 2000) {
|
|
280
|
+
this.tip(message, 'info', duration);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// 全局实例
|
|
285
|
+
window.dialog = new Dialog();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// 在 sendSMS 按钮事件监听器中添加更详细的错误处理
|
|
2
|
+
document.getElementById('btn-send-code').addEventListener('click', async () => {
|
|
3
|
+
const phone = document.getElementById('login-phone').value.trim();
|
|
4
|
+
|
|
5
|
+
// 验证手机号格式
|
|
6
|
+
if (!phone) {
|
|
7
|
+
showMessage('请输入手机号', 'error');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!/^1[3-9]\d{9}$/.test(phone)) {
|
|
12
|
+
showMessage('请输入有效的中国大陆手机号(11位,以1开头)', 'error');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const btn = document.getElementById('btn-send-code');
|
|
17
|
+
btn.disabled = true;
|
|
18
|
+
btn.textContent = '发送中...';
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const data = await app.sendSMS(phone);
|
|
22
|
+
console.log('SMS response:', data); // 调试日志
|
|
23
|
+
|
|
24
|
+
if (data.success) {
|
|
25
|
+
showMessage('验证码已发送,请查收短信', 'success');
|
|
26
|
+
let countdown = 60;
|
|
27
|
+
const timer = setInterval(() => {
|
|
28
|
+
countdown--;
|
|
29
|
+
btn.textContent = countdown + '秒后重试';
|
|
30
|
+
if (countdown <= 0) {
|
|
31
|
+
clearInterval(timer);
|
|
32
|
+
btn.disabled = false;
|
|
33
|
+
btn.textContent = '发送验证码';
|
|
34
|
+
}
|
|
35
|
+
}, 1000);
|
|
36
|
+
} else {
|
|
37
|
+
// 显示详细的错误信息
|
|
38
|
+
const errorMsg = data.msg || data.message || '发送失败,请稍后重试';
|
|
39
|
+
showMessage('发送失败: ' + errorMsg, 'error');
|
|
40
|
+
console.error('SMS error:', data);
|
|
41
|
+
btn.disabled = false;
|
|
42
|
+
btn.textContent = '发送验证码';
|
|
43
|
+
}
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error('SMS request error:', err);
|
|
46
|
+
showMessage('网络错误: ' + err.message, 'error');
|
|
47
|
+
btn.disabled = false;
|
|
48
|
+
btn.textContent = '发送验证码';
|
|
49
|
+
}
|
|
50
|
+
});
|