deepv-code 1.0.182

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.
Files changed (223) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +3 -0
  3. package/bundle/assets/help/README.md +113 -0
  4. package/bundle/assets/help/cli-help-knowledge.md +1382 -0
  5. package/bundle/assets/sounds/README.md +74 -0
  6. package/bundle/assets/sounds/confirmation-required.wav +0 -0
  7. package/bundle/assets/sounds/response-complete.wav +0 -0
  8. package/bundle/assets/sounds/selection-made.wav +0 -0
  9. package/bundle/dvcode.js +4442 -0
  10. package/bundle/fix-binary-permissions.js +215 -0
  11. package/bundle/login/templates/authSelectPage.html +870 -0
  12. package/bundle/login/templates/deepv.ico +0 -0
  13. package/bundle/login/templates/feishu.ico +0 -0
  14. package/bundle/node_modules/@vscode/ripgrep/bin/darwin-arm64-rg +0 -0
  15. package/bundle/node_modules/@vscode/ripgrep/bin/darwin-x64-rg +0 -0
  16. package/bundle/node_modules/@vscode/ripgrep/bin/linux-arm-rg +0 -0
  17. package/bundle/node_modules/@vscode/ripgrep/bin/linux-arm64-rg +0 -0
  18. package/bundle/node_modules/@vscode/ripgrep/bin/linux-x64-rg +0 -0
  19. package/bundle/node_modules/@vscode/ripgrep/bin/rg.exe +0 -0
  20. package/bundle/node_modules/@vscode/ripgrep/bin/win32-arm64-rg.exe +0 -0
  21. package/bundle/node_modules/@vscode/ripgrep/bin/win32-ia32-rg.exe +0 -0
  22. package/bundle/node_modules/@vscode/ripgrep/bin/win32-x64-rg.exe +0 -0
  23. package/bundle/node_modules/@vscode/ripgrep/lib/download.js +357 -0
  24. package/bundle/node_modules/@vscode/ripgrep/lib/index.d.ts +1 -0
  25. package/bundle/node_modules/@vscode/ripgrep/lib/index.js +42 -0
  26. package/bundle/node_modules/@vscode/ripgrep/lib/postinstall.js +121 -0
  27. package/bundle/node_modules/@vscode/ripgrep/package.json +24 -0
  28. package/bundle/node_modules/undici/LICENSE +21 -0
  29. package/bundle/node_modules/undici/README.md +472 -0
  30. package/bundle/node_modules/undici/docs/docs/api/Agent.md +83 -0
  31. package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  32. package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  33. package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +151 -0
  34. package/bundle/node_modules/undici/docs/docs/api/Client.md +281 -0
  35. package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  36. package/bundle/node_modules/undici/docs/docs/api/Connector.md +115 -0
  37. package/bundle/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  38. package/bundle/node_modules/undici/docs/docs/api/Cookies.md +101 -0
  39. package/bundle/node_modules/undici/docs/docs/api/Debug.md +62 -0
  40. package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +204 -0
  41. package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +1200 -0
  42. package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  43. package/bundle/node_modules/undici/docs/docs/api/Errors.md +49 -0
  44. package/bundle/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  45. package/bundle/node_modules/undici/docs/docs/api/Fetch.md +52 -0
  46. package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +262 -0
  47. package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  48. package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  49. package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  50. package/bundle/node_modules/undici/docs/docs/api/MockClient.md +77 -0
  51. package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  52. package/bundle/node_modules/undici/docs/docs/api/MockPool.md +548 -0
  53. package/bundle/node_modules/undici/docs/docs/api/Pool.md +84 -0
  54. package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  55. package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +227 -0
  56. package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +96 -0
  57. package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +45 -0
  58. package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +117 -0
  59. package/bundle/node_modules/undici/docs/docs/api/Util.md +25 -0
  60. package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +85 -0
  61. package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  62. package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  63. package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  64. package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  65. package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +20 -0
  66. package/bundle/node_modules/undici/index-fetch.js +35 -0
  67. package/bundle/node_modules/undici/index.d.ts +3 -0
  68. package/bundle/node_modules/undici/index.js +183 -0
  69. package/bundle/node_modules/undici/lib/api/abort-signal.js +59 -0
  70. package/bundle/node_modules/undici/lib/api/api-connect.js +110 -0
  71. package/bundle/node_modules/undici/lib/api/api-pipeline.js +252 -0
  72. package/bundle/node_modules/undici/lib/api/api-request.js +199 -0
  73. package/bundle/node_modules/undici/lib/api/api-stream.js +209 -0
  74. package/bundle/node_modules/undici/lib/api/api-upgrade.js +110 -0
  75. package/bundle/node_modules/undici/lib/api/index.js +7 -0
  76. package/bundle/node_modules/undici/lib/api/readable.js +558 -0
  77. package/bundle/node_modules/undici/lib/api/util.js +95 -0
  78. package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
  79. package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
  80. package/bundle/node_modules/undici/lib/core/connect.js +164 -0
  81. package/bundle/node_modules/undici/lib/core/constants.js +143 -0
  82. package/bundle/node_modules/undici/lib/core/diagnostics.js +196 -0
  83. package/bundle/node_modules/undici/lib/core/errors.js +244 -0
  84. package/bundle/node_modules/undici/lib/core/request.js +397 -0
  85. package/bundle/node_modules/undici/lib/core/symbols.js +68 -0
  86. package/bundle/node_modules/undici/lib/core/tree.js +160 -0
  87. package/bundle/node_modules/undici/lib/core/util.js +988 -0
  88. package/bundle/node_modules/undici/lib/dispatcher/agent.js +135 -0
  89. package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +206 -0
  90. package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +1615 -0
  91. package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +798 -0
  92. package/bundle/node_modules/undici/lib/dispatcher/client.js +614 -0
  93. package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +161 -0
  94. package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  95. package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +151 -0
  96. package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +159 -0
  97. package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +122 -0
  98. package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +191 -0
  99. package/bundle/node_modules/undici/lib/dispatcher/pool.js +118 -0
  100. package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +275 -0
  101. package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  102. package/bundle/node_modules/undici/lib/global.js +32 -0
  103. package/bundle/node_modules/undici/lib/handler/cache-handler.js +448 -0
  104. package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  105. package/bundle/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  106. package/bundle/node_modules/undici/lib/handler/redirect-handler.js +227 -0
  107. package/bundle/node_modules/undici/lib/handler/retry-handler.js +342 -0
  108. package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +96 -0
  109. package/bundle/node_modules/undici/lib/handler/wrap-handler.js +95 -0
  110. package/bundle/node_modules/undici/lib/interceptor/cache.js +372 -0
  111. package/bundle/node_modules/undici/lib/interceptor/dns.js +432 -0
  112. package/bundle/node_modules/undici/lib/interceptor/dump.js +111 -0
  113. package/bundle/node_modules/undici/lib/interceptor/redirect.js +21 -0
  114. package/bundle/node_modules/undici/lib/interceptor/response-error.js +95 -0
  115. package/bundle/node_modules/undici/lib/interceptor/retry.js +19 -0
  116. package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  117. package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +97 -0
  118. package/bundle/node_modules/undici/lib/llhttp/constants.js +498 -0
  119. package/bundle/node_modules/undici/lib/llhttp/constants.js.map +1 -0
  120. package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  121. package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  122. package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  123. package/bundle/node_modules/undici/lib/llhttp/utils.js +15 -0
  124. package/bundle/node_modules/undici/lib/llhttp/utils.js.map +1 -0
  125. package/bundle/node_modules/undici/lib/mock/mock-agent.js +224 -0
  126. package/bundle/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  127. package/bundle/node_modules/undici/lib/mock/mock-client.js +64 -0
  128. package/bundle/node_modules/undici/lib/mock/mock-errors.js +19 -0
  129. package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  130. package/bundle/node_modules/undici/lib/mock/mock-pool.js +64 -0
  131. package/bundle/node_modules/undici/lib/mock/mock-symbols.js +31 -0
  132. package/bundle/node_modules/undici/lib/mock/mock-utils.js +433 -0
  133. package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  134. package/bundle/node_modules/undici/lib/util/cache.js +368 -0
  135. package/bundle/node_modules/undici/lib/util/date.js +259 -0
  136. package/bundle/node_modules/undici/lib/util/stats.js +32 -0
  137. package/bundle/node_modules/undici/lib/util/timers.js +423 -0
  138. package/bundle/node_modules/undici/lib/web/cache/cache.js +862 -0
  139. package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  140. package/bundle/node_modules/undici/lib/web/cache/util.js +45 -0
  141. package/bundle/node_modules/undici/lib/web/cookies/constants.js +12 -0
  142. package/bundle/node_modules/undici/lib/web/cookies/index.js +199 -0
  143. package/bundle/node_modules/undici/lib/web/cookies/parse.js +322 -0
  144. package/bundle/node_modules/undici/lib/web/cookies/util.js +282 -0
  145. package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
  146. package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +484 -0
  147. package/bundle/node_modules/undici/lib/web/eventsource/util.js +37 -0
  148. package/bundle/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  149. package/bundle/node_modules/undici/lib/web/fetch/body.js +532 -0
  150. package/bundle/node_modules/undici/lib/web/fetch/constants.js +131 -0
  151. package/bundle/node_modules/undici/lib/web/fetch/data-url.js +744 -0
  152. package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +46 -0
  153. package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +501 -0
  154. package/bundle/node_modules/undici/lib/web/fetch/formdata.js +263 -0
  155. package/bundle/node_modules/undici/lib/web/fetch/global.js +40 -0
  156. package/bundle/node_modules/undici/lib/web/fetch/headers.js +719 -0
  157. package/bundle/node_modules/undici/lib/web/fetch/index.js +2258 -0
  158. package/bundle/node_modules/undici/lib/web/fetch/request.js +1099 -0
  159. package/bundle/node_modules/undici/lib/web/fetch/response.js +636 -0
  160. package/bundle/node_modules/undici/lib/web/fetch/util.js +1782 -0
  161. package/bundle/node_modules/undici/lib/web/fetch/webidl.js +740 -0
  162. package/bundle/node_modules/undici/lib/web/websocket/connection.js +325 -0
  163. package/bundle/node_modules/undici/lib/web/websocket/constants.js +126 -0
  164. package/bundle/node_modules/undici/lib/web/websocket/events.js +331 -0
  165. package/bundle/node_modules/undici/lib/web/websocket/frame.js +138 -0
  166. package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +70 -0
  167. package/bundle/node_modules/undici/lib/web/websocket/receiver.js +454 -0
  168. package/bundle/node_modules/undici/lib/web/websocket/sender.js +109 -0
  169. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +83 -0
  170. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +485 -0
  171. package/bundle/node_modules/undici/lib/web/websocket/util.js +338 -0
  172. package/bundle/node_modules/undici/lib/web/websocket/websocket.js +686 -0
  173. package/bundle/node_modules/undici/package.json +149 -0
  174. package/bundle/node_modules/undici/scripts/strip-comments.js +10 -0
  175. package/bundle/node_modules/undici/types/README.md +6 -0
  176. package/bundle/node_modules/undici/types/agent.d.ts +35 -0
  177. package/bundle/node_modules/undici/types/api.d.ts +43 -0
  178. package/bundle/node_modules/undici/types/balanced-pool.d.ts +29 -0
  179. package/bundle/node_modules/undici/types/cache-interceptor.d.ts +172 -0
  180. package/bundle/node_modules/undici/types/cache.d.ts +36 -0
  181. package/bundle/node_modules/undici/types/client-stats.d.ts +15 -0
  182. package/bundle/node_modules/undici/types/client.d.ts +110 -0
  183. package/bundle/node_modules/undici/types/connector.d.ts +34 -0
  184. package/bundle/node_modules/undici/types/content-type.d.ts +21 -0
  185. package/bundle/node_modules/undici/types/cookies.d.ts +30 -0
  186. package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +66 -0
  187. package/bundle/node_modules/undici/types/dispatcher.d.ts +281 -0
  188. package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +21 -0
  189. package/bundle/node_modules/undici/types/errors.d.ts +171 -0
  190. package/bundle/node_modules/undici/types/eventsource.d.ts +61 -0
  191. package/bundle/node_modules/undici/types/fetch.d.ts +210 -0
  192. package/bundle/node_modules/undici/types/formdata.d.ts +108 -0
  193. package/bundle/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  194. package/bundle/node_modules/undici/types/global-origin.d.ts +7 -0
  195. package/bundle/node_modules/undici/types/h2c-client.d.ts +75 -0
  196. package/bundle/node_modules/undici/types/handlers.d.ts +15 -0
  197. package/bundle/node_modules/undici/types/header.d.ts +160 -0
  198. package/bundle/node_modules/undici/types/index.d.ts +75 -0
  199. package/bundle/node_modules/undici/types/interceptors.d.ts +34 -0
  200. package/bundle/node_modules/undici/types/mock-agent.d.ts +68 -0
  201. package/bundle/node_modules/undici/types/mock-call-history.d.ts +111 -0
  202. package/bundle/node_modules/undici/types/mock-client.d.ts +25 -0
  203. package/bundle/node_modules/undici/types/mock-errors.d.ts +12 -0
  204. package/bundle/node_modules/undici/types/mock-interceptor.d.ts +93 -0
  205. package/bundle/node_modules/undici/types/mock-pool.d.ts +25 -0
  206. package/bundle/node_modules/undici/types/patch.d.ts +29 -0
  207. package/bundle/node_modules/undici/types/pool-stats.d.ts +19 -0
  208. package/bundle/node_modules/undici/types/pool.d.ts +41 -0
  209. package/bundle/node_modules/undici/types/proxy-agent.d.ts +29 -0
  210. package/bundle/node_modules/undici/types/readable.d.ts +68 -0
  211. package/bundle/node_modules/undici/types/retry-agent.d.ts +8 -0
  212. package/bundle/node_modules/undici/types/retry-handler.d.ts +116 -0
  213. package/bundle/node_modules/undici/types/util.d.ts +18 -0
  214. package/bundle/node_modules/undici/types/utility.d.ts +7 -0
  215. package/bundle/node_modules/undici/types/webidl.d.ts +266 -0
  216. package/bundle/node_modules/undici/types/websocket.d.ts +184 -0
  217. package/bundle/sandbox-macos-permissive-closed.sb +26 -0
  218. package/bundle/sandbox-macos-permissive-open.sb +19 -0
  219. package/bundle/sandbox-macos-permissive-proxied.sb +31 -0
  220. package/bundle/sandbox-macos-restrictive-closed.sb +87 -0
  221. package/bundle/sandbox-macos-restrictive-open.sb +90 -0
  222. package/bundle/sandbox-macos-restrictive-proxied.sb +92 -0
  223. package/package.json +137 -0
@@ -0,0 +1,870 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title data-i18n="auth.page.title">Choose Authentication Method</title>
5
+ <meta charset="utf-8">
6
+ <style>
7
+ * {
8
+ margin: 0;
9
+ padding: 0;
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ body {
14
+ font-family: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
15
+ background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
16
+ min-height: 100vh;
17
+ display: flex;
18
+ align-items: center;
19
+ justify-content: center;
20
+ padding: 40px 20px;
21
+ color: #1e293b;
22
+ line-height: 1.6;
23
+ }
24
+
25
+ .container {
26
+ background: #ffffff;
27
+ border-radius: 20px;
28
+ padding: 64px 48px;
29
+ max-width: 480px;
30
+ width: 100%;
31
+ box-shadow:
32
+ 0 4px 6px -1px rgba(0, 0, 0, 0.05),
33
+ 0 2px 4px -1px rgba(0, 0, 0, 0.03);
34
+ border: 1px solid #f1f5f9;
35
+ text-align: center;
36
+ }
37
+
38
+ .title {
39
+ font-size: 36px;
40
+ font-weight: 800;
41
+ color: #0f172a;
42
+ margin-bottom: 16px;
43
+ letter-spacing: -0.025em;
44
+ line-height: 1.2;
45
+ }
46
+
47
+ .subtitle {
48
+ color: #64748b;
49
+ font-size: 18px;
50
+ font-weight: 400;
51
+ margin-bottom: 48px;
52
+ line-height: 1.5;
53
+ }
54
+
55
+ .auth-button {
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: flex-start;
59
+ gap: 16px;
60
+ width: 100%;
61
+ padding: 20px 32px;
62
+ margin: 20px 0;
63
+ border: none;
64
+ border-radius: 12px;
65
+ font-size: 17px;
66
+ font-weight: 600;
67
+ cursor: pointer;
68
+ text-decoration: none;
69
+ transition: all 0.15s ease;
70
+ position: relative;
71
+ font-family: inherit;
72
+ }
73
+
74
+ .feishu-btn {
75
+ background: #ffffff;
76
+ color: #374151;
77
+ border: 2px solid #e5e7eb;
78
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
79
+ }
80
+
81
+ .feishu-btn:hover {
82
+ background: #f9fafb;
83
+ border-color: #0ea5e9;
84
+ color: #0ea5e9;
85
+ transform: translateY(-1px);
86
+ box-shadow: 0 4px 12px rgba(14, 165, 233, 0.15);
87
+ }
88
+
89
+ .feishu-btn:active {
90
+ transform: translateY(0);
91
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
92
+ }
93
+
94
+ .deepvlab-btn {
95
+ background: #ffffff;
96
+ color: #374151;
97
+ border: 2px solid #e5e7eb;
98
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
99
+ }
100
+
101
+ .deepvlab-btn:hover {
102
+ background: #f9fafb;
103
+ border-color: #1e293b;
104
+ color: #1e293b;
105
+ transform: translateY(-1px);
106
+ box-shadow: 0 4px 12px rgba(30, 41, 59, 0.15);
107
+ }
108
+
109
+ .deepvlab-btn:active {
110
+ transform: translateY(0);
111
+ box-shadow: 0 2px 4px rgba(30, 41, 59, 0.1);
112
+ }
113
+
114
+ .cheetah-btn {
115
+ background: #ffffff;
116
+ color: #374151;
117
+ border: 2px solid #e5e7eb;
118
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
119
+ }
120
+
121
+ .cheetah-btn:hover {
122
+ background: #f9fafb;
123
+ border-color: #ff6b35;
124
+ color: #ff6b35;
125
+ transform: translateY(-1px);
126
+ box-shadow: 0 4px 12px rgba(255, 107, 53, 0.15);
127
+ }
128
+
129
+ .cheetah-btn:active {
130
+ transform: translateY(0);
131
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
132
+ }
133
+
134
+ .icon {
135
+ width: 22px;
136
+ height: 22px;
137
+ display: inline-block;
138
+ }
139
+
140
+ .description {
141
+ color: #94a3b8;
142
+ font-size: 15px;
143
+ line-height: 1.6;
144
+ margin-top: 40px;
145
+ padding: 24px;
146
+ background: #f8fafc;
147
+ border-radius: 12px;
148
+ border: 1px solid #e2e8f0;
149
+ }
150
+
151
+ .hidden {
152
+ display: none !important;
153
+ }
154
+
155
+ /* 消息提示样式 */
156
+ .message-overlay {
157
+ position: fixed;
158
+ top: 0;
159
+ left: 0;
160
+ width: 100%;
161
+ height: 100%;
162
+ background: rgba(0, 0, 0, 0.5);
163
+ display: flex;
164
+ justify-content: center;
165
+ align-items: center;
166
+ z-index: 1000;
167
+ }
168
+
169
+ .message-box {
170
+ background: white;
171
+ border-radius: 12px;
172
+ padding: 32px;
173
+ max-width: 400px;
174
+ width: 90%;
175
+ text-align: center;
176
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
177
+ animation: messageSlideIn 0.3s ease-out;
178
+ }
179
+
180
+ @keyframes messageSlideIn {
181
+ from {
182
+ opacity: 0;
183
+ transform: translateY(-20px) scale(0.95);
184
+ }
185
+ to {
186
+ opacity: 1;
187
+ transform: translateY(0) scale(1);
188
+ }
189
+ }
190
+
191
+ .message-icon {
192
+ width: 64px;
193
+ height: 64px;
194
+ margin: 0 auto 16px;
195
+ border-radius: 50%;
196
+ display: flex;
197
+ align-items: center;
198
+ justify-content: center;
199
+ font-size: 32px;
200
+ }
201
+
202
+ .message-icon.success {
203
+ background: #dcfce7;
204
+ color: #16a34a;
205
+ }
206
+
207
+ .message-icon.error {
208
+ background: #fef2f2;
209
+ color: #dc2626;
210
+ }
211
+
212
+ .message-title {
213
+ font-size: 20px;
214
+ font-weight: 600;
215
+ margin-bottom: 8px;
216
+ color: #1f2937;
217
+ }
218
+
219
+ .message-content {
220
+ font-size: 14px;
221
+ color: #6b7280;
222
+ margin-bottom: 24px;
223
+ line-height: 1.5;
224
+ }
225
+
226
+ .message-button {
227
+ background: #3b82f6;
228
+ color: white;
229
+ border: none;
230
+ border-radius: 8px;
231
+ padding: 12px 24px;
232
+ font-size: 14px;
233
+ font-weight: 500;
234
+ cursor: pointer;
235
+ transition: all 0.2s ease;
236
+ }
237
+
238
+ .message-button:hover {
239
+ background: #2563eb;
240
+ transform: translateY(-1px);
241
+ }
242
+
243
+ .message-button:active {
244
+ transform: translateY(0);
245
+ }
246
+
247
+ /* 中国IP限制消息样式 */
248
+ .china-message {
249
+ background: #fef2f2;
250
+ border: 2px solid #fecaca;
251
+ border-radius: 12px;
252
+ padding: 24px;
253
+ margin: 20px 0;
254
+ text-align: center;
255
+ }
256
+
257
+ .china-message-icon {
258
+ width: 48px;
259
+ height: 48px;
260
+ margin: 0 auto 16px;
261
+ background: #dc2626;
262
+ border-radius: 50%;
263
+ display: flex;
264
+ align-items: center;
265
+ justify-content: center;
266
+ color: white;
267
+ font-size: 24px;
268
+ }
269
+
270
+ .china-message-title {
271
+ font-size: 20px;
272
+ font-weight: 600;
273
+ color: #dc2626;
274
+ margin-bottom: 12px;
275
+ }
276
+
277
+ .china-message-content {
278
+ color: #7f1d1d;
279
+ font-size: 14px;
280
+ line-height: 1.6;
281
+ margin-bottom: 8px;
282
+ }
283
+
284
+ .auth-buttons-container {
285
+ /* 用于控制所有登录按钮的显示/隐藏 */
286
+ }
287
+
288
+ /* 加载中样式 */
289
+ .loading-container {
290
+ display: flex;
291
+ flex-direction: column;
292
+ align-items: center;
293
+ padding: 40px 20px;
294
+ }
295
+
296
+ .loading-spinner {
297
+ width: 40px;
298
+ height: 40px;
299
+ border: 3px solid #e2e8f0;
300
+ border-top: 3px solid #3b82f6;
301
+ border-radius: 50%;
302
+ animation: spin 1s linear infinite;
303
+ margin-bottom: 16px;
304
+ }
305
+
306
+ @keyframes spin {
307
+ 0% { transform: rotate(0deg); }
308
+ 100% { transform: rotate(360deg); }
309
+ }
310
+
311
+ .loading-text {
312
+ color: #64748b;
313
+ font-size: 16px;
314
+ font-weight: 500;
315
+ }
316
+
317
+ /* 猎豹OA表单样式 */
318
+ .cheetah-form {
319
+ margin-top: 24px;
320
+ padding: 24px;
321
+ background: #f8fafc;
322
+ border-radius: 12px;
323
+ border: 1px solid #e2e8f0;
324
+ }
325
+
326
+ .cheetah-form h3 {
327
+ margin: 0 0 20px 0;
328
+ color: #1e293b;
329
+ font-size: 18px;
330
+ font-weight: 600;
331
+ }
332
+
333
+ .form-group {
334
+ margin-bottom: 16px;
335
+ }
336
+
337
+ .form-group label {
338
+ display: block;
339
+ margin-bottom: 6px;
340
+ color: #374151;
341
+ font-weight: 500;
342
+ font-size: 14px;
343
+ }
344
+
345
+ .form-group input {
346
+ width: 100%;
347
+ padding: 12px 16px;
348
+ border: 1px solid #d1d5db;
349
+ border-radius: 8px;
350
+ font-size: 14px;
351
+ transition: all 0.2s ease;
352
+ background: white;
353
+ box-sizing: border-box;
354
+ }
355
+
356
+ .form-group input:focus {
357
+ outline: none;
358
+ border-color: #ff6b35;
359
+ box-shadow: 0 0 0 3px rgba(255, 107, 53, 0.1);
360
+ }
361
+
362
+ .form-actions {
363
+ display: flex;
364
+ gap: 12px;
365
+ margin-top: 20px;
366
+ }
367
+
368
+ .btn-primary, .btn-secondary {
369
+ flex: 1;
370
+ padding: 12px 20px;
371
+ border-radius: 8px;
372
+ font-size: 14px;
373
+ font-weight: 500;
374
+ cursor: pointer;
375
+ transition: all 0.2s ease;
376
+ border: none;
377
+ }
378
+
379
+ .btn-primary {
380
+ background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);
381
+ color: white;
382
+ }
383
+
384
+ .btn-primary:hover {
385
+ background: linear-gradient(135deg, #e55a2b 0%, #de831a 100%);
386
+ transform: translateY(-1px);
387
+ }
388
+
389
+ .btn-secondary {
390
+ background: #f1f5f9;
391
+ color: #64748b;
392
+ border: 1px solid #e2e8f0;
393
+ }
394
+
395
+ .btn-secondary:hover {
396
+ background: #e2e8f0;
397
+ color: #475569;
398
+ }
399
+
400
+ @media (max-width: 480px) {
401
+ body {
402
+ padding: 20px 16px;
403
+ }
404
+
405
+ .container {
406
+ padding: 40px 32px;
407
+ }
408
+
409
+ .title {
410
+ font-size: 32px;
411
+ }
412
+
413
+ .subtitle {
414
+ font-size: 16px;
415
+ margin-bottom: 36px;
416
+ }
417
+
418
+ .auth-button {
419
+ padding: 18px 24px;
420
+ font-size: 16px;
421
+ gap: 12px;
422
+ }
423
+
424
+ .description {
425
+ margin-top: 32px;
426
+ padding: 20px;
427
+ font-size: 14px;
428
+ }
429
+ }
430
+
431
+ /* 加载动画 */
432
+ @keyframes fadeInUp {
433
+ from {
434
+ opacity: 0;
435
+ transform: translateY(20px);
436
+ }
437
+ to {
438
+ opacity: 1;
439
+ transform: translateY(0);
440
+ }
441
+ }
442
+
443
+ .container {
444
+ animation: fadeInUp 0.4s ease;
445
+ }
446
+ </style>
447
+ </head>
448
+ <body>
449
+ <div class="container">
450
+ <h1 class="title" data-i18n="auth.page.title">Choose Authentication</h1>
451
+ <p class="subtitle" data-i18n="auth.page.description">Select your preferred login method to continue</p>
452
+
453
+ <!-- 加载中效果 -->
454
+ <div id="loading-container" class="loading-container">
455
+ <div class="loading-spinner"></div>
456
+ <div class="loading-text" data-i18n="auth.loading.text">Checking access permissions...</div>
457
+ </div>
458
+
459
+ <!-- 中国IP限制消息 -->
460
+ <div id="china-message" class="china-message hidden">
461
+ <div class="china-message-icon">⚠️</div>
462
+ <div class="china-message-title" data-i18n="auth.china.restriction.title">Access Restricted</div>
463
+ <div id="china-message-content" class="china-message-content">
464
+ <!-- 动态加载后台消息 -->
465
+ </div>
466
+ </div>
467
+
468
+ <!-- 登录按钮容器 -->
469
+ <div id="auth-buttons-container" class="auth-buttons-container hidden">
470
+ <button id="feishu-btn" class="auth-button feishu-btn hidden" onclick="startFeishuAuth()">
471
+ <img class="icon" src="https://res.ainirobot.com/orics/down/v2_k005_20250904_c768e6a4/feishu.ico" alt="Feishu" />
472
+ <span data-i18n="auth.feishu.button">Feishu Login</span>
473
+ </button>
474
+
475
+ <button class="auth-button deepvlab-btn" onclick="startDeepvlabAuth()">
476
+ <img class="icon" src="https://res.ainirobot.com/orics/down/v2_k005_20250904_52ad718e/deepv.ico" alt="DeepV" />
477
+ <span data-i18n="auth.deepvlab.button">DeepVlab Unified Login</span>
478
+ </button>
479
+
480
+ <button id="cheetah-btn" class="auth-button cheetah-btn hidden" onclick="startCheetahAuth()">
481
+ <img class="icon" src="https://www.cmcm.com/favicon.ico" alt="Cheetah" />
482
+ <span data-i18n="auth.cheetah.button">Cheetah OA Login</span>
483
+ </button>
484
+
485
+ <!-- 猎豹OA登录表单 -->
486
+ <div id="cheetah-form" class="cheetah-form hidden">
487
+ <h3 data-i18n="auth.cheetah.form.title">Cheetah OA Login</h3>
488
+ <form id="cheetah-login-form" onsubmit="submitCheetahAuth(event)">
489
+ <div class="form-group">
490
+ <label for="cheetah-email" data-i18n="auth.cheetah.form.email">Email:</label>
491
+ <input type="email" id="cheetah-email" name="email" required placeholder="user@cmcm.com" />
492
+ </div>
493
+ <div class="form-group">
494
+ <label for="cheetah-password" data-i18n="auth.cheetah.form.password">Password:</label>
495
+ <input type="password" id="cheetah-password" name="password" required />
496
+ </div>
497
+ <div class="form-actions">
498
+ <button type="button" class="btn-secondary" onclick="cancelCheetahAuth()" data-i18n="auth.cheetah.form.cancel">Cancel</button>
499
+ <button type="submit" class="btn-primary" data-i18n="auth.cheetah.form.submit">Login</button>
500
+ </div>
501
+ </form>
502
+ </div>
503
+ </div>
504
+
505
+ <div class="description" data-i18n="auth.page.instruction">
506
+ Choose your authentication method and we will guide you through the secure login process
507
+ </div>
508
+ </div>
509
+
510
+ <script>
511
+ // 国际化翻译对象
512
+ const translations = {
513
+ en: {
514
+ 'auth.page.title': 'Choose Authentication',
515
+ 'auth.page.description': 'Select your preferred login method to continue',
516
+ 'auth.feishu.button': 'Feishu Login',
517
+ 'auth.deepvlab.button': 'DeepVlab Unified Login',
518
+ 'auth.cheetah.button': 'Cheetah OA Login',
519
+ 'auth.cheetah.form.title': 'Cheetah OA Login',
520
+ 'auth.cheetah.form.email': 'Email',
521
+ 'auth.cheetah.form.password': 'Password',
522
+ 'auth.cheetah.form.cancel': 'Cancel',
523
+ 'auth.cheetah.form.submit': 'Login',
524
+ 'auth.page.instruction': 'Choose your authentication method and we will guide you through the secure login process',
525
+ 'auth.loading.text': 'Checking access permissions...',
526
+ 'auth.china.restriction.title': 'Access Restricted',
527
+ 'auth.feishu.start.error': 'Failed to start Feishu authentication, please try again',
528
+ 'auth.deepvlab.start.error': 'Failed to start DeepVlab authentication, please try again',
529
+ 'auth.cheetah.start.error': 'Failed to login with Cheetah OA, please check your credentials'
530
+ },
531
+ zh: {
532
+ 'auth.page.title': '选择认证方式',
533
+ 'auth.page.description': '选择您偏好的登录方式以继续',
534
+ 'auth.feishu.button': '飞书登录',
535
+ 'auth.deepvlab.button': 'DeepVlab统一登录',
536
+ 'auth.cheetah.button': '猎豹OA登录',
537
+ 'auth.cheetah.form.title': '猎豹OA登录',
538
+ 'auth.cheetah.form.email': '邮箱',
539
+ 'auth.cheetah.form.password': '密码',
540
+ 'auth.cheetah.form.cancel': '取消',
541
+ 'auth.cheetah.form.submit': '登录',
542
+ 'auth.page.instruction': '选择您的认证方式,我们将引导您完成安全的登录流程',
543
+ 'auth.loading.text': '正在检查访问权限...',
544
+ 'auth.china.restriction.title': '访问受限',
545
+ 'auth.feishu.start.error': '飞书认证启动失败,请重试',
546
+ 'auth.deepvlab.start.error': 'DeepVlab认证启动失败,请重试',
547
+ 'auth.cheetah.start.error': '猎豹OA登录失败,请检查您的凭据'
548
+ }
549
+ };
550
+
551
+ // 获取浏览器语言
552
+ function getBrowserLanguage() {
553
+ const lang = navigator.language || navigator.userLanguage;
554
+ return lang.startsWith('zh') ? 'zh' : 'en';
555
+ }
556
+
557
+ // 翻译函数
558
+ function t(key) {
559
+ const locale = getBrowserLanguage();
560
+ return translations[locale][key] || translations.en[key] || key;
561
+ }
562
+
563
+ // 初始化页面文本
564
+ function initI18n() {
565
+ document.querySelectorAll('[data-i18n]').forEach(element => {
566
+ const key = element.getAttribute('data-i18n');
567
+ element.textContent = t(key);
568
+ // 同时更新title属性(如果是title标签)
569
+ if (element.tagName === 'TITLE') {
570
+ document.title = t(key);
571
+ }
572
+ });
573
+ }
574
+
575
+ // 消息提示函数
576
+ function showMessage(type, title, content, buttonText = 'OK') {
577
+ // 创建消息覆盖层
578
+ const overlay = document.createElement('div');
579
+ overlay.className = 'message-overlay';
580
+
581
+ // 创建消息框
582
+ const messageBox = document.createElement('div');
583
+ messageBox.className = 'message-box';
584
+
585
+ // 图标
586
+ const icon = document.createElement('div');
587
+ icon.className = `message-icon ${type}`;
588
+ icon.innerHTML = type === 'success' ? '✓' : '✕';
589
+
590
+ // 标题
591
+ const titleEl = document.createElement('div');
592
+ titleEl.className = 'message-title';
593
+ titleEl.textContent = title;
594
+
595
+ // 内容
596
+ const contentEl = document.createElement('div');
597
+ contentEl.className = 'message-content';
598
+ contentEl.textContent = content;
599
+
600
+ // 按钮
601
+ const button = document.createElement('button');
602
+ button.className = 'message-button';
603
+ button.textContent = buttonText;
604
+ button.onclick = () => {
605
+ document.body.removeChild(overlay);
606
+ };
607
+
608
+ // 组装消息框
609
+ messageBox.appendChild(icon);
610
+ messageBox.appendChild(titleEl);
611
+ messageBox.appendChild(contentEl);
612
+ messageBox.appendChild(button);
613
+ overlay.appendChild(messageBox);
614
+
615
+ // 添加到页面
616
+ document.body.appendChild(overlay);
617
+
618
+ // 点击覆盖层关闭
619
+ overlay.onclick = (e) => {
620
+ if (e.target === overlay) {
621
+ document.body.removeChild(overlay);
622
+ }
623
+ };
624
+ }
625
+
626
+ // 页面加载时初始化i18n和检查登录权限
627
+ document.addEventListener('DOMContentLoaded', function() {
628
+ initI18n();
629
+ checkFeishuAllowed(); // 这个函数会自动调用checkCheetahAllowed
630
+ });
631
+
632
+ function checkFeishuAllowed() {
633
+ console.log('🔍 开始检查飞书登录权限...');
634
+ console.log('📡 调用API: /api/backend/feishu-allowed');
635
+
636
+ // Call the backend server to check if Feishu login is allowed
637
+ fetch('/api/backend/feishu-allowed')
638
+ .then(response => {
639
+ console.log('🌐 接口响应状态:', response.status);
640
+ console.log('✅ 进入第一个then块');
641
+ return response.json();
642
+ })
643
+ .then(data => {
644
+ console.log('✅ 进入第二个then块 - 开始处理数据');
645
+ console.log('📋 后台接口返回完整数据:', JSON.stringify(data, null, 2));
646
+
647
+ // 隐藏加载中效果
648
+ console.log('🔄 开始隐藏loading效果...');
649
+ const loadingContainer = document.getElementById('loading-container');
650
+ console.log('🔍 loading容器元素:', loadingContainer);
651
+ if (loadingContainer) {
652
+ console.log('⏳ loading容器存在,添加hidden类');
653
+ loadingContainer.classList.add('hidden');
654
+ // 双重保险:直接设置display样式
655
+ loadingContainer.style.display = 'none';
656
+ console.log('✅ loading hidden类已添加,display设置为none');
657
+ console.log('🎨 loading容器当前className:', loadingContainer.className);
658
+ console.log('🎨 loading容器当前style.display:', loadingContainer.style.display);
659
+ } else {
660
+ console.error('❌ 未找到loading容器元素!');
661
+ }
662
+
663
+ // 检查是否是中国IP且不允许登录
664
+ if (data.isChina && !data.feishuLoginAllowed && data.messages && data.messages.length > 0) {
665
+ console.log('🇨🇳 检测到中国IP且不允许登录,显示限制消息');
666
+
667
+ // 显示中国IP限制消息
668
+ const chinaMessage = document.getElementById('china-message');
669
+ const chinaMessageContent = document.getElementById('china-message-content');
670
+
671
+ if (chinaMessage && chinaMessageContent) {
672
+ // 填充消息内容
673
+ chinaMessageContent.innerHTML = data.messages.map(msg => `<p>${msg}</p>`).join('');
674
+
675
+ // 显示消息框
676
+ chinaMessage.classList.remove('hidden');
677
+ console.log('✅ 已显示中国IP限制消息');
678
+ }
679
+
680
+ // 登录按钮保持隐藏状态(默认就是隐藏的)
681
+ } else {
682
+ console.log('✅ 非中国IP,显示登录选项');
683
+
684
+ // 显示登录按钮容器
685
+ const authButtonsContainer = document.getElementById('auth-buttons-container');
686
+ if (authButtonsContainer) {
687
+ authButtonsContainer.classList.remove('hidden');
688
+ console.log('✅ 已显示登录按钮容器');
689
+ }
690
+
691
+ // DeepVlab登录始终可用(没有hidden类,会自动显示)
692
+ console.log('✅ DeepVlab登录始终可用');
693
+
694
+ // 根据权限显示飞书登录按钮
695
+ if (data.feishuLoginAllowed) {
696
+ console.log('✅ 飞书登录已允许,显示飞书登录按钮');
697
+ const feishuBtn = document.getElementById('feishu-btn');
698
+ if (feishuBtn) {
699
+ feishuBtn.classList.remove('hidden');
700
+ console.log('✅ 飞书登录按钮已显示');
701
+ }
702
+ } else {
703
+ console.log('🚫 飞书登录被禁用,保持飞书按钮隐藏');
704
+ }
705
+
706
+ // 检查猎豹OA登录权限(使用相同的数据)
707
+ checkCheetahAllowed(data);
708
+ }
709
+ })
710
+ .catch(error => {
711
+ console.error('❌ 检查飞书登录权限失败:', error);
712
+ console.log('🔄 进入catch块 - API调用失败');
713
+
714
+ // 隐藏加载中效果
715
+ console.log('🔄 catch块中开始隐藏loading效果...');
716
+ const loadingContainer = document.getElementById('loading-container');
717
+ console.log('🔍 catch块中loading容器元素:', loadingContainer);
718
+ if (loadingContainer) {
719
+ console.log('⏳ catch块中loading容器存在,添加hidden类');
720
+ loadingContainer.classList.add('hidden');
721
+ // 双重保险:直接设置display样式
722
+ loadingContainer.style.display = 'none';
723
+ console.log('✅ catch块中loading hidden类已添加,display设置为none');
724
+ } else {
725
+ console.error('❌ catch块中未找到loading容器元素!');
726
+ }
727
+
728
+ // 出错时显示登录按钮容器(保守处理)
729
+ const authButtonsContainer = document.getElementById('auth-buttons-container');
730
+ if (authButtonsContainer) {
731
+ authButtonsContainer.classList.remove('hidden');
732
+ }
733
+
734
+ console.log('🔄 失败时显示所有登录选项');
735
+ });
736
+ }
737
+
738
+ function checkCheetahAllowed(data) {
739
+ console.log('🔍 开始检查猎豹OA登录权限...');
740
+
741
+ // 使用与飞书相同的权限检查逻辑
742
+ if (data && !data.isChina && data.feishuLoginAllowed) {
743
+ console.log('✅ 猎豹OA登录已允许,显示登录按钮');
744
+ // 显示猎豹OA登录按钮
745
+ const cheetahBtn = document.getElementById('cheetah-btn');
746
+ if (cheetahBtn) {
747
+ cheetahBtn.classList.remove('hidden');
748
+ console.log('✅ 猎豹OA登录按钮已显示');
749
+ } else {
750
+ console.warn('⚠️ 未找到猎豹OA登录按钮元素');
751
+ }
752
+ } else {
753
+ console.log('🚫 猎豹OA登录被禁用,保持按钮隐藏');
754
+ }
755
+ }
756
+
757
+ function startFeishuAuth() {
758
+ console.log('启动飞书认证...');
759
+ // 这里会调用飞书认证逻辑
760
+ fetch('/start-feishu-auth', { method: 'POST' })
761
+ .then(response => response.json())
762
+ .then(data => {
763
+ if (data.authUrl) {
764
+ // 修复方案:直接替换当前页面到认证URL,避免产生额外的空白页面
765
+ // 这样认证完成后只需要关闭一个页面,不会留下空白的中间页
766
+ window.location.replace(data.authUrl);
767
+ }
768
+ })
769
+ .catch(error => {
770
+ console.error('飞书认证启动失败:', error);
771
+ showMessage('error', 'Connection Error', 'Unable to start Feishu authentication. Please check your network connection and try again.', 'Retry');
772
+ });
773
+ }
774
+
775
+ function startDeepvlabAuth() {
776
+ console.log('启动DeepVlab认证...');
777
+ // 这里会调用DeepVlab认证逻辑
778
+ fetch('/start-deepvlab-auth', { method: 'POST' })
779
+ .then(response => response.json())
780
+ .then(data => {
781
+ if (data.authUrl) {
782
+ // 修复方案:直接替换当前页面到认证URL,避免产生额外的空白页面
783
+ // 这样认证完成后只需要关闭一个页面,不会留下空白的中间页
784
+ window.location.replace(data.authUrl);
785
+ }
786
+ })
787
+ .catch(error => {
788
+ console.error('DeepVlab认证启动失败:', error);
789
+ showMessage('error', 'Connection Error', 'Unable to start DeepVlab authentication. Please check your network connection and try again.', 'Retry');
790
+ });
791
+ }
792
+
793
+ function startCheetahAuth() {
794
+ console.log('显示猎豹OA登录表单...');
795
+ // 隐藏所有认证按钮
796
+ const buttons = document.querySelectorAll('.auth-button');
797
+ buttons.forEach(btn => btn.style.display = 'none');
798
+
799
+ // 显示猎豹OA表单
800
+ const form = document.getElementById('cheetah-form');
801
+ if (form) {
802
+ form.classList.remove('hidden');
803
+ }
804
+ }
805
+
806
+ function cancelCheetahAuth() {
807
+ console.log('取消猎豹OA登录...');
808
+ // 隐藏表单
809
+ const form = document.getElementById('cheetah-form');
810
+ if (form) {
811
+ form.classList.add('hidden');
812
+ }
813
+
814
+ // 显示所有认证按钮
815
+ const buttons = document.querySelectorAll('.auth-button');
816
+ buttons.forEach(btn => btn.style.display = 'flex');
817
+ }
818
+
819
+ function submitCheetahAuth(event) {
820
+ event.preventDefault();
821
+ console.log('提交猎豹OA登录...');
822
+
823
+ const email = document.getElementById('cheetah-email').value;
824
+ const password = document.getElementById('cheetah-password').value;
825
+
826
+ if (!email || !password) {
827
+ showMessage('error', 'Input Required', 'Please fill in both email and password fields.', 'OK');
828
+ return;
829
+ }
830
+
831
+ // 禁用提交按钮
832
+ const submitBtn = event.target.querySelector('button[type="submit"]');
833
+ if (submitBtn) {
834
+ submitBtn.disabled = true;
835
+ submitBtn.textContent = '登录中...';
836
+ }
837
+
838
+ fetch('/start-cheetah-auth', {
839
+ method: 'POST',
840
+ headers: {
841
+ 'Content-Type': 'application/json',
842
+ },
843
+ body: JSON.stringify({ email, password })
844
+ })
845
+ .then(response => response.json())
846
+ .then(data => {
847
+ if (data.success) {
848
+ // 登录成功,显示成功消息
849
+ showMessage('success', 'Login Successful!', 'You have successfully logged in with Cheetah OA. You can now close this window and continue using DeepCode.', 'Close');
850
+ // 隐藏表单,显示按钮
851
+ cancelCheetahAuth();
852
+ } else {
853
+ showMessage('error', 'Login Failed', data.message || 'Cheetah OA authentication failed. Please check your credentials and try again.', 'Try Again');
854
+ }
855
+ })
856
+ .catch(error => {
857
+ console.error('猎豹OA登录失败:', error);
858
+ showMessage('error', 'Connection Error', 'Unable to connect to authentication server. Please check your network connection and try again.', 'Retry');
859
+ })
860
+ .finally(() => {
861
+ // 恢复提交按钮
862
+ if (submitBtn) {
863
+ submitBtn.disabled = false;
864
+ submitBtn.textContent = t('auth.cheetah.form.submit');
865
+ }
866
+ });
867
+ }
868
+ </script>
869
+ </body>
870
+ </html>