smart-admin-web 10.14.0 → 10.15.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.
Files changed (194) hide show
  1. package/README.md +5 -5
  2. package/dist/api/index.d.ts +37 -0
  3. package/dist/api/index.js +35 -14
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/schema.d.ts +381 -3
  6. package/dist/assets/icons/ph-subset.json.js +3 -3
  7. package/dist/assets/smart-logo.svg.js +5 -0
  8. package/dist/assets/smart-logo.svg.js.map +1 -0
  9. package/dist/components/SmartLogo.vue.d.ts +3 -0
  10. package/dist/components/SmartLogo.vue.js +1 -1
  11. package/dist/components/SmartLogo2.vue.js +22 -64
  12. package/dist/components/SmartLogo2.vue.js.map +1 -1
  13. package/dist/composables/useLoginHero.d.ts +2 -0
  14. package/dist/composables/useLoginHero.js +22 -0
  15. package/dist/composables/useLoginHero.js.map +1 -0
  16. package/dist/composables/usePageTitle.js +16 -14
  17. package/dist/composables/usePageTitle.js.map +1 -1
  18. package/dist/composables/useSite.d.ts +5 -0
  19. package/dist/composables/useSite.js +16 -13
  20. package/dist/composables/useSite.js.map +1 -1
  21. package/dist/index.js +92 -91
  22. package/dist/lib/favicon.d.ts +1 -0
  23. package/dist/lib/favicon.js +12 -0
  24. package/dist/lib/favicon.js.map +1 -0
  25. package/dist/lib/loginHero.d.ts +16 -0
  26. package/dist/lib/loginHero.js +33 -0
  27. package/dist/lib/loginHero.js.map +1 -0
  28. package/dist/lib/logoCrop.d.ts +25 -0
  29. package/dist/lib/logoCrop.js +22 -0
  30. package/dist/lib/logoCrop.js.map +1 -0
  31. package/dist/lib/runtime.d.ts +2 -0
  32. package/dist/lib/runtime.js +1 -1
  33. package/dist/lib/runtime.js.map +1 -1
  34. package/dist/lib/securityRules.d.ts +26 -0
  35. package/dist/lib/securityRules.js +86 -0
  36. package/dist/lib/securityRules.js.map +1 -0
  37. package/dist/locales/en-US.d.ts +242 -28
  38. package/dist/locales/en-US.js +262 -58
  39. package/dist/locales/en-US.js.map +1 -1
  40. package/dist/locales/zh-CN.d.ts +242 -28
  41. package/dist/locales/zh-CN.js +257 -58
  42. package/dist/locales/zh-CN.js.map +1 -1
  43. package/dist/router/viewRegistry.js +10 -10
  44. package/dist/router/viewRegistry.js.map +1 -1
  45. package/dist/style.css +1 -1
  46. package/dist/utils/oauthBrand.d.ts +34 -9
  47. package/dist/utils/oauthBrand.js +70 -74
  48. package/dist/utils/oauthBrand.js.map +1 -1
  49. package/dist/views/login/components/LoginHeroPanel.vue.d.ts +18 -0
  50. package/dist/views/login/components/LoginHeroPanel.vue.js +8 -0
  51. package/dist/views/login/components/LoginHeroPanel.vue.js.map +1 -0
  52. package/dist/views/login/components/LoginHeroPanel2.vue.js +66 -0
  53. package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -0
  54. package/dist/views/login/skins/SplitPanel.vue.js +1 -1
  55. package/dist/views/login/skins/SplitPanel2.vue.js +39 -59
  56. package/dist/views/login/skins/SplitPanel2.vue.js.map +1 -1
  57. package/dist/views/system/config/components/AdminMock.vue.js +8 -0
  58. package/dist/views/system/config/components/AdminMock.vue.js.map +1 -0
  59. package/dist/views/system/config/components/AdminMock2.vue.js +76 -0
  60. package/dist/views/system/config/components/AdminMock2.vue.js.map +1 -0
  61. package/dist/views/system/config/components/AdvancedSection.vue.js +5 -0
  62. package/dist/views/system/config/components/AdvancedSection.vue.js.map +1 -0
  63. package/dist/views/system/config/components/AdvancedSection2.vue.js +135 -0
  64. package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -0
  65. package/dist/views/system/config/components/BrandSection.vue.d.ts +7 -0
  66. package/dist/views/system/config/components/BrandSection.vue.js +8 -0
  67. package/dist/views/system/config/components/BrandSection.vue.js.map +1 -0
  68. package/dist/views/system/config/components/BrandSection2.vue.js +264 -0
  69. package/dist/views/system/config/components/BrandSection2.vue.js.map +1 -0
  70. package/dist/views/system/config/components/CfgGroup.vue.d.ts +18 -0
  71. package/dist/views/system/config/components/CfgGroup.vue.js +8 -0
  72. package/dist/views/system/config/components/CfgGroup.vue.js.map +1 -0
  73. package/dist/views/system/config/components/CfgGroup2.vue.js +22 -0
  74. package/dist/views/system/config/components/CfgGroup2.vue.js.map +1 -0
  75. package/dist/views/system/config/components/CfgRow.vue.d.ts +26 -0
  76. package/dist/views/system/config/components/CfgRow.vue.js +9 -0
  77. package/dist/views/system/config/components/CfgRow.vue.js.map +1 -0
  78. package/dist/views/system/config/components/CfgRow2.vue.js +53 -0
  79. package/dist/views/system/config/components/CfgRow2.vue.js.map +1 -0
  80. package/dist/views/system/config/components/CfgSegment.vue.d.ts +28 -0
  81. package/dist/views/system/config/components/CfgSegment.vue.js +8 -0
  82. package/dist/views/system/config/components/CfgSegment.vue.js.map +1 -0
  83. package/dist/views/system/config/components/CfgSegment2.vue.js +44 -0
  84. package/dist/views/system/config/components/CfgSegment2.vue.js.map +1 -0
  85. package/dist/views/system/config/components/ConfigFormModal.vue.js +5 -2
  86. package/dist/views/system/config/components/ConfigFormModal.vue.js.map +1 -1
  87. package/dist/views/system/config/components/ConfigFormModal2.vue.js +66 -56
  88. package/dist/views/system/config/components/ConfigFormModal2.vue.js.map +1 -1
  89. package/dist/views/system/config/components/JobSection.vue.js +8 -0
  90. package/dist/views/system/config/components/JobSection.vue.js.map +1 -0
  91. package/dist/views/system/config/components/JobSection2.vue.js +138 -0
  92. package/dist/views/system/config/components/JobSection2.vue.js.map +1 -0
  93. package/dist/views/system/config/components/{GroupExtraConfig.vue.d.ts → LoginMock.vue.d.ts} +3 -4
  94. package/dist/views/system/config/components/LoginMock.vue.js +8 -0
  95. package/dist/views/system/config/components/LoginMock.vue.js.map +1 -0
  96. package/dist/views/system/config/components/LoginMock2.vue.js +121 -0
  97. package/dist/views/system/config/components/LoginMock2.vue.js.map +1 -0
  98. package/dist/views/system/config/components/LogoCropper.vue.d.ts +10 -0
  99. package/dist/views/system/config/components/LogoCropper.vue.js +8 -0
  100. package/dist/views/system/config/components/LogoCropper.vue.js.map +1 -0
  101. package/dist/views/system/config/components/LogoCropper2.vue.js +122 -0
  102. package/dist/views/system/config/components/LogoCropper2.vue.js.map +1 -0
  103. package/dist/views/system/config/components/LogoEditor.vue.js +8 -0
  104. package/dist/views/system/config/components/LogoEditor.vue.js.map +1 -0
  105. package/dist/views/system/config/components/LogoEditor2.vue.js +163 -0
  106. package/dist/views/system/config/components/LogoEditor2.vue.js.map +1 -0
  107. package/dist/views/system/config/components/ProviderSheet.vue.d.ts +17 -0
  108. package/dist/views/system/config/components/ProviderSheet.vue.js +8 -0
  109. package/dist/views/system/config/components/ProviderSheet.vue.js.map +1 -0
  110. package/dist/views/system/config/components/ProviderSheet2.vue.js +343 -0
  111. package/dist/views/system/config/components/ProviderSheet2.vue.js.map +1 -0
  112. package/dist/views/system/config/components/ScaleToFit.vue.d.ts +17 -0
  113. package/dist/views/system/config/components/ScaleToFit.vue.js +8 -0
  114. package/dist/views/system/config/components/ScaleToFit.vue.js.map +1 -0
  115. package/dist/views/system/config/components/ScaleToFit2.vue.js +41 -0
  116. package/dist/views/system/config/components/ScaleToFit2.vue.js.map +1 -0
  117. package/dist/views/system/config/components/SectionLayout.vue.d.ts +28 -0
  118. package/dist/views/system/config/components/SectionLayout.vue.js +8 -0
  119. package/dist/views/system/config/components/SectionLayout.vue.js.map +1 -0
  120. package/dist/views/system/config/components/SectionLayout2.vue.js +45 -0
  121. package/dist/views/system/config/components/SectionLayout2.vue.js.map +1 -0
  122. package/dist/views/system/config/components/SecuritySection.vue.js +8 -0
  123. package/dist/views/system/config/components/SecuritySection.vue.js.map +1 -0
  124. package/dist/views/system/config/components/SecuritySection2.vue.js +416 -0
  125. package/dist/views/system/config/components/SecuritySection2.vue.js.map +1 -0
  126. package/dist/views/system/config/components/SensitiveSection.vue.js +8 -0
  127. package/dist/views/system/config/components/SensitiveSection.vue.js.map +1 -0
  128. package/dist/views/system/config/components/SensitiveSection2.vue.js +209 -0
  129. package/dist/views/system/config/components/SensitiveSection2.vue.js.map +1 -0
  130. package/dist/views/system/config/components/SigninSection.vue.js +8 -0
  131. package/dist/views/system/config/components/SigninSection.vue.js.map +1 -0
  132. package/dist/views/system/config/components/SigninSection2.vue.js +201 -0
  133. package/dist/views/system/config/components/SigninSection2.vue.js.map +1 -0
  134. package/dist/views/system/config/components/UploadSection.vue.d.ts +3 -0
  135. package/dist/views/system/config/components/UploadSection.vue.js +8 -0
  136. package/dist/views/system/config/components/UploadSection.vue.js.map +1 -0
  137. package/dist/views/system/config/components/UploadSection2.vue.js +167 -0
  138. package/dist/views/system/config/components/UploadSection2.vue.js.map +1 -0
  139. package/dist/views/system/config/draft.d.ts +148 -0
  140. package/dist/views/system/config/draft.js +170 -0
  141. package/dist/views/system/config/draft.js.map +1 -0
  142. package/dist/views/system/config/flash.d.ts +2 -0
  143. package/dist/views/system/config/flash.js +9 -0
  144. package/dist/views/system/config/flash.js.map +1 -0
  145. package/dist/views/system/config/groups.d.ts +35 -7
  146. package/dist/views/system/config/groups.js +99 -14
  147. package/dist/views/system/config/groups.js.map +1 -1
  148. package/dist/views/system/config/index.vue.js +4 -1
  149. package/dist/views/system/config/index.vue.js.map +1 -1
  150. package/dist/views/system/config/index2.vue.js +180 -115
  151. package/dist/views/system/config/index2.vue.js.map +1 -1
  152. package/dist/views/system/config/providerForm.d.ts +33 -0
  153. package/dist/views/system/config/providerForm.js +63 -0
  154. package/dist/views/system/config/providerForm.js.map +1 -0
  155. package/package.json +4 -4
  156. package/dist/views/system/config/components/ExternalAuthConfig.vue.js +0 -8
  157. package/dist/views/system/config/components/ExternalAuthConfig.vue.js.map +0 -1
  158. package/dist/views/system/config/components/ExternalAuthConfig2.vue.js +0 -218
  159. package/dist/views/system/config/components/ExternalAuthConfig2.vue.js.map +0 -1
  160. package/dist/views/system/config/components/GroupExtraConfig.vue.js +0 -8
  161. package/dist/views/system/config/components/GroupExtraConfig.vue.js.map +0 -1
  162. package/dist/views/system/config/components/GroupExtraConfig2.vue.js +0 -108
  163. package/dist/views/system/config/components/GroupExtraConfig2.vue.js.map +0 -1
  164. package/dist/views/system/config/components/HighSensConfig.vue.js +0 -5
  165. package/dist/views/system/config/components/HighSensConfig.vue.js.map +0 -1
  166. package/dist/views/system/config/components/HighSensConfig2.vue.js +0 -134
  167. package/dist/views/system/config/components/HighSensConfig2.vue.js.map +0 -1
  168. package/dist/views/system/config/components/JobConfig.vue.js +0 -5
  169. package/dist/views/system/config/components/JobConfig.vue.js.map +0 -1
  170. package/dist/views/system/config/components/JobConfig2.vue.js +0 -116
  171. package/dist/views/system/config/components/JobConfig2.vue.js.map +0 -1
  172. package/dist/views/system/config/components/OtherConfig.vue.js +0 -5
  173. package/dist/views/system/config/components/OtherConfig.vue.js.map +0 -1
  174. package/dist/views/system/config/components/OtherConfig2.vue.js +0 -121
  175. package/dist/views/system/config/components/OtherConfig2.vue.js.map +0 -1
  176. package/dist/views/system/config/components/SecurityConfig.vue.js +0 -8
  177. package/dist/views/system/config/components/SecurityConfig.vue.js.map +0 -1
  178. package/dist/views/system/config/components/SecurityConfig2.vue.js +0 -456
  179. package/dist/views/system/config/components/SecurityConfig2.vue.js.map +0 -1
  180. package/dist/views/system/config/components/SysBaseConfig.vue.js +0 -5
  181. package/dist/views/system/config/components/SysBaseConfig.vue.js.map +0 -1
  182. package/dist/views/system/config/components/SysBaseConfig2.vue.js +0 -107
  183. package/dist/views/system/config/components/SysBaseConfig2.vue.js.map +0 -1
  184. package/dist/views/system/config/components/UploadConfig.vue.js +0 -5
  185. package/dist/views/system/config/components/UploadConfig.vue.js.map +0 -1
  186. package/dist/views/system/config/components/UploadConfig2.vue.js +0 -135
  187. package/dist/views/system/config/components/UploadConfig2.vue.js.map +0 -1
  188. /package/dist/views/system/config/components/{ExternalAuthConfig.vue.d.ts → AdminMock.vue.d.ts} +0 -0
  189. /package/dist/views/system/config/components/{HighSensConfig.vue.d.ts → AdvancedSection.vue.d.ts} +0 -0
  190. /package/dist/views/system/config/components/{JobConfig.vue.d.ts → JobSection.vue.d.ts} +0 -0
  191. /package/dist/views/system/config/components/{OtherConfig.vue.d.ts → LogoEditor.vue.d.ts} +0 -0
  192. /package/dist/views/system/config/components/{SecurityConfig.vue.d.ts → SecuritySection.vue.d.ts} +0 -0
  193. /package/dist/views/system/config/components/{SysBaseConfig.vue.d.ts → SensitiveSection.vue.d.ts} +0 -0
  194. /package/dist/views/system/config/components/{UploadConfig.vue.d.ts → SigninSection.vue.d.ts} +0 -0
@@ -1,97 +1,93 @@
1
- import { t as d } from "../locales/index.js";
2
- const l = 4, s = ["github", "wechat", "wecom", "dingtalk", "gitee", "qq"], u = new Set(s), w = !1;
3
- function c(n) {
4
- return d(`oauth.brand.${n}`);
1
+ import { t as v } from "../locales/index.js";
2
+ const b = 4, w = ["github", "wechat", "wecom", "dingtalk", "gitee", "qq"], N = new Set(w), S = !1;
3
+ function y(e) {
4
+ return v(`oauth.brand.${e}`);
5
5
  }
6
- function y() {
7
- return s.map((n) => ({ code: n, displayName: c(n) }));
6
+ function B() {
7
+ return w.map((e) => ({ code: e, displayName: y(e) }));
8
8
  }
9
- const g = ["wecom"];
10
- function N(n) {
11
- const t = new Map(n.map((o) => [o.code, o])), r = [], i = /* @__PURE__ */ new Set();
12
- for (const o of s) {
13
- i.add(o);
14
- const e = t.get(o);
15
- r.push({
16
- code: o,
17
- displayName: (e == null ? void 0 : e.displayName) || c(o),
18
- icon: (e == null ? void 0 : e.icon) ?? null,
19
- registered: !!e,
20
- enabled: e ? e.enabled : !1,
21
- linkByAccount: (e == null ? void 0 : e.linkByAccount) ?? !1
9
+ const L = ["wecom"], A = ["wecom", "dingtalk", "github", "wechat"];
10
+ function E(e, n) {
11
+ const s = new Set(e.types.map((t) => t.type)), i = new Map(n.map((t) => [t.code, t])), a = new Map(e.providers.map((t) => [t.code, t])), o = [], l = /* @__PURE__ */ new Set(), u = (t, h) => {
12
+ l.add(t);
13
+ const r = a.get(t), f = (r == null ? void 0 : r.source) === "code", m = f || (r ? s.has(r.type) : s.has(t)) ? r != null && r.configured ? "configured" : "unconfigured" : "notInstalled", c = i.get(t), d = m === "configured";
14
+ o.push({
15
+ code: t,
16
+ type: (r == null ? void 0 : r.type) ?? (h ? t : ""),
17
+ displayName: (r == null ? void 0 : r.displayName) || (g(t) ? y(t) : t),
18
+ icon: (r == null ? void 0 : r.icon) ?? null,
19
+ state: m,
20
+ source: f ? "code" : r ? "db" : "none",
21
+ registered: d,
22
+ enabled: d && !!(c != null && c.enabled),
23
+ linkByAccount: d && !!(c != null && c.linkByAccount)
22
24
  });
23
- }
24
- for (const o of n)
25
- i.has(o.code) || (i.add(o.code), r.push({
26
- code: o.code,
27
- displayName: o.displayName,
28
- icon: o.icon,
29
- registered: !0,
30
- enabled: o.enabled,
31
- linkByAccount: o.linkByAccount ?? !1
32
- }));
33
- return r;
25
+ };
26
+ for (const t of A) u(t, !0);
27
+ for (const t of e.providers) l.has(t.code) || u(t.code, !1);
28
+ return o;
34
29
  }
35
- function f(n) {
36
- if (n == null) return !1;
37
- const t = n.trim();
38
- return !t || /^https?:\/\//i.test(t) || t.startsWith("//") || /^data:/i.test(t) ? !1 : /^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9._-]*$/i.test(t);
30
+ function C(e) {
31
+ if (e == null) return !1;
32
+ const n = e.trim();
33
+ return !n || /^https?:\/\//i.test(n) || n.startsWith("//") || /^data:/i.test(n) ? !1 : /^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9._-]*$/i.test(n);
39
34
  }
40
- function m(n) {
41
- return !!n && u.has(n.toLowerCase());
35
+ function g(e) {
36
+ return !!e && N.has(e.toLowerCase());
42
37
  }
43
- function b(n, t) {
44
- const r = (n ?? "").trim().toLowerCase();
45
- return m(r) ? { kind: "brand", code: r } : f(t) ? { kind: "iconify", name: t.trim() } : { kind: "letter", letter: (n ?? "?").trim().charAt(0).toUpperCase() || "?" };
38
+ function O(e, n) {
39
+ const s = (e ?? "").trim().toLowerCase();
40
+ return g(s) ? { kind: "brand", code: s } : C(n) ? { kind: "iconify", name: n.trim() } : { kind: "letter", letter: (e ?? "?").trim().charAt(0).toUpperCase() || "?" };
46
41
  }
47
- const a = "smart.sso.wecomAutoLogin";
48
- function v(n) {
49
- if (!/wxwork/i.test(n.userAgent) || !n.providers.some((t) => t.code === "wecom")) return !1;
42
+ const p = "smart.sso.wecomAutoLogin";
43
+ function k(e) {
44
+ if (!/wxwork/i.test(e.userAgent) || !e.providers.some((n) => n.code === "wecom")) return !1;
50
45
  try {
51
- return n.storage.getItem(a) ? !1 : (n.storage.setItem(a, "1"), !0);
46
+ return e.storage.getItem(p) ? !1 : (e.storage.setItem(p, "1"), !0);
52
47
  } catch {
53
48
  return !1;
54
49
  }
55
50
  }
56
- function A(n, t = l) {
57
- const r = n.slice();
58
- return r.length <= t ? { visible: r, overflow: [] } : { visible: r.slice(0, t), overflow: r.slice(t) };
51
+ function P(e, n = b) {
52
+ const s = e.slice();
53
+ return s.length <= n ? { visible: s, overflow: [] } : { visible: s.slice(0, n), overflow: s.slice(n) };
59
54
  }
60
- function h(n, t) {
61
- const r = /* @__PURE__ */ new Map();
62
- for (const e of t) r.set(e.provider, e);
63
- const i = [], o = /* @__PURE__ */ new Set();
64
- for (const e of n)
65
- o.add(e.code), i.push({
66
- code: e.code,
67
- displayName: e.displayName,
68
- icon: e.icon,
55
+ function D(e, n) {
56
+ const s = /* @__PURE__ */ new Map();
57
+ for (const o of n) s.set(o.provider, o);
58
+ const i = [], a = /* @__PURE__ */ new Set();
59
+ for (const o of e)
60
+ a.add(o.code), i.push({
61
+ code: o.code,
62
+ displayName: o.displayName,
63
+ icon: o.icon,
69
64
  enabled: !0,
70
- binding: r.get(e.code)
65
+ binding: s.get(o.code)
71
66
  });
72
- for (const e of t)
73
- o.has(e.provider) || i.push({
74
- code: e.provider,
75
- displayName: e.displayName && e.displayName.trim() || e.provider,
67
+ for (const o of n)
68
+ a.has(o.provider) || i.push({
69
+ code: o.provider,
70
+ displayName: o.displayName && o.displayName.trim() || o.provider,
76
71
  icon: null,
77
72
  enabled: !1,
78
- binding: e
73
+ binding: o
79
74
  });
80
75
  return i;
81
76
  }
82
77
  export {
83
- s as BRAND_CODES,
84
- g as LINK_BY_ACCOUNT_CODES,
85
- w as PREVIEW_ALL_SSO_BRANDS,
86
- l as SSO_VISIBLE_MAX,
87
- c as brandDisplayName,
88
- N as buildConfigProviderRows,
89
- v as claimWeComAutoLogin,
90
- m as isBrandCode,
91
- f as isIconifyName,
92
- h as mergeBindingRows,
93
- y as previewAllBrandProviders,
94
- b as resolveProviderIcon,
95
- A as splitLoginProviders
78
+ w as BRAND_CODES,
79
+ L as LINK_BY_ACCOUNT_CODES,
80
+ A as OFFICIAL_TYPES,
81
+ S as PREVIEW_ALL_SSO_BRANDS,
82
+ b as SSO_VISIBLE_MAX,
83
+ y as brandDisplayName,
84
+ E as buildConfigProviderRows,
85
+ k as claimWeComAutoLogin,
86
+ g as isBrandCode,
87
+ C as isIconifyName,
88
+ D as mergeBindingRows,
89
+ B as previewAllBrandProviders,
90
+ O as resolveProviderIcon,
91
+ P as splitLoginProviders
96
92
  };
97
93
  //# sourceMappingURL=oauthBrand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauthBrand.js","sources":["../../src/utils/oauthBrand.ts"],"sourcesContent":["// 外部登录品牌 UI 纯逻辑:可被 vitest 直接驱动,不依赖浏览器。\n// 契约见 docs/adr/0007-external-login-brand-ui-and-providers.md。\nimport { t } from '#/locales'\n\n/** 登录页最多平铺的品牌圆钮数;超出进「…」菜单。 */\nexport const SSO_VISIBLE_MAX = 4\n\n/** 预置精修品牌标的 provider code(大小写不敏感)。 */\nexport const BRAND_CODES = ['github', 'wechat', 'wecom', 'dingtalk', 'gitee', 'qq'] as const\nexport type BrandCode = (typeof BRAND_CODES)[number]\n\nconst BRAND_SET = new Set<string>(BRAND_CODES)\n\n/**\n * 登录页临时展示全部品牌圆标(图标验收用)。\n * true:铺全 6 个,不做 N=4 溢出;false:恢复仅后端 enabled providers。\n * 图标验收时在本地把 false 改成 true,验收完改回来,不要带着 true 提交。\n */\nexport const PREVIEW_ALL_SSO_BRANDS = false\n\n/**\n * 内置品牌显示名。走 i18n 而非硬编码中文常量表 —— 硬编码在英文界面下会露出「微信/企业微信/钉钉」。\n * 调用方须在 computed 里取值,切语言才会重算。\n */\nexport function brandDisplayName(code: BrandCode): string {\n return t(`oauth.brand.${code}`)\n}\n\n/** 图标预览用的假 provider 列表(与后端是否启用无关)。 */\nexport function previewAllBrandProviders(): SsoProviderLike[] {\n return BRAND_CODES.map(code => ({ code, displayName: brandDisplayName(code) }))\n}\n\n/**\n * 配置页卡片上给出「按账号自动关联」开关的 provider。只有企业微信的外部标识是企业统一分配的账号(userid),\n * 钉钉 / 微信 / GitHub 的标识是 unionid 或数字 id,按账号名对不上本地账号;\n * 自定义 provider 真要开(如 sub 就是工号的 OIDC),到「其他配置」加 sys.externalauth.{code}.linkByAccount。\n */\nexport const LINK_BY_ACCOUNT_CODES: readonly string[] = ['wecom']\n\n/** 配置页一行:内置品牌全展示;registered=后端已装包/已配密钥。 */\nexport type ConfigProviderRow = {\n code: string\n displayName: string\n icon?: string | null\n registered: boolean\n enabled: boolean\n /** 未绑定的外部身份按账号名关联同名本地账号(sys.externalauth.{code}.linkByAccount) */\n linkByAccount: boolean\n}\n\n/**\n * 配置页列表 = 预置品牌(全量) + 其它已注册 code(如 oidc-demo)。\n * 未注册项 registered=false、两个开关强制 false(未部署的方式开了也没用)。\n */\nexport function buildConfigProviderRows(\n registered: readonly {\n code: string\n displayName: string\n icon?: string | null\n enabled: boolean\n linkByAccount?: boolean\n }[],\n): ConfigProviderRow[] {\n const byCode = new Map(registered.map(p => [p.code, p]))\n const rows: ConfigProviderRow[] = []\n const seen = new Set<string>()\n\n for (const code of BRAND_CODES) {\n seen.add(code)\n const r = byCode.get(code)\n rows.push({\n code,\n displayName: r?.displayName || brandDisplayName(code),\n icon: r?.icon ?? null,\n registered: !!r,\n enabled: r ? r.enabled : false,\n linkByAccount: r?.linkByAccount ?? false,\n })\n }\n for (const p of registered) {\n if (seen.has(p.code)) continue\n seen.add(p.code)\n rows.push({\n code: p.code,\n displayName: p.displayName,\n icon: p.icon,\n registered: true,\n enabled: p.enabled,\n linkByAccount: p.linkByAccount ?? false,\n })\n }\n return rows\n}\n\nexport type SsoProviderLike = {\n code: string\n displayName: string\n icon?: string | null\n}\n\nexport type BindingLike = {\n provider: string\n displayName?: string | null\n boundAt: string\n}\n\nexport type IconResolve =\n | { kind: 'brand'; code: BrandCode }\n | { kind: 'iconify'; name: string }\n | { kind: 'letter'; letter: string }\n\nexport type BindingRow = {\n code: string\n displayName: string\n icon?: string | null\n /** false = 运营已关但仍有绑定 */\n enabled: boolean\n binding?: BindingLike\n}\n\n/** 是否为可渲染的 Iconify 名称;拒绝 URL / data URI。 */\nexport function isIconifyName(icon: string | null | undefined): boolean {\n if (icon == null) return false\n const s = icon.trim()\n if (!s) return false\n if (/^https?:\\/\\//i.test(s) || s.startsWith('//') || /^data:/i.test(s)) return false\n // collection:name(离线 Iconify 常见形态)\n return /^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9._-]*$/i.test(s)\n}\n\nexport function isBrandCode(code: string | null | undefined): code is BrandCode {\n return !!code && BRAND_SET.has(code.toLowerCase())\n}\n\n/** brand map → Iconify 名 → 首字母。 */\nexport function resolveProviderIcon(code: string, icon?: string | null): IconResolve {\n const c = (code ?? '').trim().toLowerCase()\n if (isBrandCode(c)) return { kind: 'brand', code: c }\n if (isIconifyName(icon)) return { kind: 'iconify', name: icon!.trim() }\n const letter = (code ?? '?').trim().charAt(0).toUpperCase() || '?'\n return { kind: 'letter', letter }\n}\n\nconst WECOM_AUTO_LOGIN_KEY = 'smart.sso.wecomAutoLogin'\n\n/**\n * 在企业微信客户端里打开登录页时,是否直接发起企业微信登录(客户端内走网页授权,静默、不用点)。\n * 企业微信的 UA 带 wxwork(同时也带微信的 MicroMessenger,不能拿它判断)。\n * 每个浏览器会话只返回一次 true:登录失败或主动退出后再回到登录页就停下,让人自己选登录方式,不会来回跳。\n */\nexport function claimWeComAutoLogin(opts: {\n userAgent: string\n providers: readonly { code: string }[]\n storage: Pick<Storage, 'getItem' | 'setItem'>\n}): boolean {\n if (!/wxwork/i.test(opts.userAgent)) return false\n if (!opts.providers.some(p => p.code === 'wecom')) return false\n try {\n if (opts.storage.getItem(WECOM_AUTO_LOGIN_KEY)) return false\n opts.storage.setItem(WECOM_AUTO_LOGIN_KEY, '1')\n return true\n } catch {\n // 存储不可用时记不住「已经跳过一次」,宁可不自动跳\n return false\n }\n}\n\n/** 严格保序切分:前 max 平铺,其余进溢出。 */\nexport function splitLoginProviders<T>(\n providers: readonly T[],\n maxVisible = SSO_VISIBLE_MAX,\n): {\n visible: T[]\n overflow: T[]\n} {\n const list = providers.slice()\n if (list.length <= maxVisible) return { visible: list, overflow: [] }\n return { visible: list.slice(0, maxVisible), overflow: list.slice(maxVisible) }\n}\n\n/**\n * 绑定页行:已启用 providers(API 序) ∪ 仅存在于 bindings 的已停用项(接在后面)。\n * 不做 N=4 截断。\n */\nexport function mergeBindingRows(\n providers: readonly SsoProviderLike[],\n bindings: readonly BindingLike[],\n): BindingRow[] {\n const bindByProvider = new Map<string, BindingLike>()\n for (const b of bindings) bindByProvider.set(b.provider, b)\n\n const rows: BindingRow[] = []\n const seen = new Set<string>()\n\n for (const p of providers) {\n seen.add(p.code)\n rows.push({\n code: p.code,\n displayName: p.displayName,\n icon: p.icon,\n enabled: true,\n binding: bindByProvider.get(p.code),\n })\n }\n\n for (const b of bindings) {\n if (seen.has(b.provider)) continue\n rows.push({\n code: b.provider,\n displayName: (b.displayName && b.displayName.trim()) || b.provider,\n icon: null,\n enabled: false,\n binding: b,\n })\n }\n\n return rows\n}\n"],"names":["SSO_VISIBLE_MAX","BRAND_CODES","BRAND_SET","PREVIEW_ALL_SSO_BRANDS","brandDisplayName","code","t","previewAllBrandProviders","LINK_BY_ACCOUNT_CODES","buildConfigProviderRows","registered","byCode","p","rows","seen","r","isIconifyName","icon","s","isBrandCode","resolveProviderIcon","c","WECOM_AUTO_LOGIN_KEY","claimWeComAutoLogin","opts","splitLoginProviders","providers","maxVisible","list","mergeBindingRows","bindings","bindByProvider","b"],"mappings":"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"}
1
+ {"version":3,"file":"oauthBrand.js","sources":["../../src/utils/oauthBrand.ts"],"sourcesContent":["// 外部登录品牌 UI 纯逻辑:可被 vitest 直接驱动,不依赖浏览器。\n// 契约见 docs/adr/0007-external-login-brand-ui-and-providers.md。\nimport { t } from '#/locales'\n\n/** 登录页最多平铺的品牌圆钮数;超出进「…」菜单。 */\nexport const SSO_VISIBLE_MAX = 4\n\n/** 预置精修品牌标的 provider code(大小写不敏感)。 */\nexport const BRAND_CODES = ['github', 'wechat', 'wecom', 'dingtalk', 'gitee', 'qq'] as const\nexport type BrandCode = (typeof BRAND_CODES)[number]\n\nconst BRAND_SET = new Set<string>(BRAND_CODES)\n\n/**\n * 登录页临时展示全部品牌圆标(图标验收用)。\n * true:铺全 6 个,不做 N=4 溢出;false:恢复仅后端 enabled providers。\n * 图标验收时在本地把 false 改成 true,验收完改回来,不要带着 true 提交。\n */\nexport const PREVIEW_ALL_SSO_BRANDS = false\n\n/**\n * 内置品牌显示名。走 i18n 而非硬编码中文常量表 —— 硬编码在英文界面下会露出「微信/企业微信/钉钉」。\n * 调用方须在 computed 里取值,切语言才会重算。\n */\nexport function brandDisplayName(code: BrandCode): string {\n return t(`oauth.brand.${code}`)\n}\n\n/** 图标预览用的假 provider 列表(与后端是否启用无关)。 */\nexport function previewAllBrandProviders(): SsoProviderLike[] {\n return BRAND_CODES.map(code => ({ code, displayName: brandDisplayName(code) }))\n}\n\n/**\n * 配置页卡片上给出「按账号自动关联」开关的 provider。只有企业微信的外部标识是企业统一分配的账号(userid),\n * 钉钉 / 微信 / GitHub 的标识是 unionid 或数字 id,按账号名对不上本地账号;\n * 自定义 provider 真要开(如 sub 就是工号的 OIDC),到「其他配置」加 sys.externalauth.{code}.linkByAccount。\n */\nexport const LINK_BY_ACCOUNT_CODES: readonly string[] = ['wecom']\n\n/** 服务器上有对应扩展包的官方厂商类型,按「登录方式」页的展示顺序。 */\nexport const OFFICIAL_TYPES = ['wecom', 'dingtalk', 'github', 'wechat'] as const\n\n/** 一行的状态:类型没装 / 已装未配 / 已配可用。 */\nexport type ProviderState = 'notInstalled' | 'unconfigured' | 'configured'\n\n/** 配置页一行:后端目录里有的类型与 provider,不是预置品牌全量。 */\nexport type ConfigProviderRow = {\n code: string\n /** 类型码;代码注册的 provider 没有类型,为空串 */\n type: string\n displayName: string\n icon?: string | null\n state: ProviderState\n /** db = 在本页配置;code = 消费者用代码注册(只读);none = 没有配置 */\n source: 'db' | 'code' | 'none'\n /** 已配置且可用:开关可操作,预览与登录页才会出现它 */\n registered: boolean\n enabled: boolean\n /** 未绑定的外部身份按账号名关联同名本地账号(sys.externalauth.{code}.linkByAccount) */\n linkByAccount: boolean\n}\n\ntype CatalogLike = {\n types: readonly { type: string }[]\n providers: readonly {\n code: string\n type: string\n displayName: string\n icon?: string | null\n source: string\n installed: boolean\n configured: boolean\n }[]\n}\n\ntype AdminLike = { code: string; enabled: boolean; linkByAccount?: boolean }\n\n/**\n * 配置页列表 = 四个官方厂商(按固定顺序,没装的也列出并标「未安装」)\n * + 目录里其余的 provider(OIDC 条目、代码注册的)。\n * 未配置或未安装的行开关强制关:没配好的方式开了也没用,也不写库。\n */\nexport function buildConfigProviderRows(\n catalog: CatalogLike,\n admin: readonly AdminLike[],\n): ConfigProviderRow[] {\n const installed = new Set(catalog.types.map(x => x.type))\n const adminByCode = new Map(admin.map(a => [a.code, a]))\n const byCode = new Map(catalog.providers.map(p => [p.code, p]))\n const rows: ConfigProviderRow[] = []\n const seen = new Set<string>()\n\n const push = (code: string, official: boolean) => {\n seen.add(code)\n const p = byCode.get(code)\n const fromCode = p?.source === 'code'\n const typeInstalled = fromCode || (p ? installed.has(p.type) : installed.has(code))\n const state: ProviderState = !typeInstalled\n ? 'notInstalled'\n : p?.configured\n ? 'configured'\n : 'unconfigured'\n const a = adminByCode.get(code)\n const registered = state === 'configured'\n rows.push({\n code,\n type: p?.type ?? (official ? code : ''),\n displayName: p?.displayName || (isBrandCode(code) ? brandDisplayName(code) : code),\n icon: p?.icon ?? null,\n state,\n source: fromCode ? 'code' : p ? 'db' : 'none',\n registered,\n enabled: registered && !!a?.enabled,\n linkByAccount: registered && !!a?.linkByAccount,\n })\n }\n\n for (const code of OFFICIAL_TYPES) push(code, true)\n for (const p of catalog.providers) if (!seen.has(p.code)) push(p.code, false)\n return rows\n}\n\nexport type SsoProviderLike = {\n code: string\n displayName: string\n icon?: string | null\n}\n\nexport type BindingLike = {\n provider: string\n displayName?: string | null\n boundAt: string\n}\n\nexport type IconResolve =\n | { kind: 'brand'; code: BrandCode }\n | { kind: 'iconify'; name: string }\n | { kind: 'letter'; letter: string }\n\nexport type BindingRow = {\n code: string\n displayName: string\n icon?: string | null\n /** false = 运营已关但仍有绑定 */\n enabled: boolean\n binding?: BindingLike\n}\n\n/** 是否为可渲染的 Iconify 名称;拒绝 URL / data URI。 */\nexport function isIconifyName(icon: string | null | undefined): boolean {\n if (icon == null) return false\n const s = icon.trim()\n if (!s) return false\n if (/^https?:\\/\\//i.test(s) || s.startsWith('//') || /^data:/i.test(s)) return false\n // collection:name(离线 Iconify 常见形态)\n return /^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9._-]*$/i.test(s)\n}\n\nexport function isBrandCode(code: string | null | undefined): code is BrandCode {\n return !!code && BRAND_SET.has(code.toLowerCase())\n}\n\n/** brand map → Iconify 名 → 首字母。 */\nexport function resolveProviderIcon(code: string, icon?: string | null): IconResolve {\n const c = (code ?? '').trim().toLowerCase()\n if (isBrandCode(c)) return { kind: 'brand', code: c }\n if (isIconifyName(icon)) return { kind: 'iconify', name: icon!.trim() }\n const letter = (code ?? '?').trim().charAt(0).toUpperCase() || '?'\n return { kind: 'letter', letter }\n}\n\nconst WECOM_AUTO_LOGIN_KEY = 'smart.sso.wecomAutoLogin'\n\n/**\n * 在企业微信客户端里打开登录页时,是否直接发起企业微信登录(客户端内走网页授权,静默、不用点)。\n * 企业微信的 UA 带 wxwork(同时也带微信的 MicroMessenger,不能拿它判断)。\n * 每个浏览器会话只返回一次 true:登录失败或主动退出后再回到登录页就停下,让人自己选登录方式,不会来回跳。\n */\nexport function claimWeComAutoLogin(opts: {\n userAgent: string\n providers: readonly { code: string }[]\n storage: Pick<Storage, 'getItem' | 'setItem'>\n}): boolean {\n if (!/wxwork/i.test(opts.userAgent)) return false\n if (!opts.providers.some(p => p.code === 'wecom')) return false\n try {\n if (opts.storage.getItem(WECOM_AUTO_LOGIN_KEY)) return false\n opts.storage.setItem(WECOM_AUTO_LOGIN_KEY, '1')\n return true\n } catch {\n // 存储不可用时记不住「已经跳过一次」,宁可不自动跳\n return false\n }\n}\n\n/** 严格保序切分:前 max 平铺,其余进溢出。 */\nexport function splitLoginProviders<T>(\n providers: readonly T[],\n maxVisible = SSO_VISIBLE_MAX,\n): {\n visible: T[]\n overflow: T[]\n} {\n const list = providers.slice()\n if (list.length <= maxVisible) return { visible: list, overflow: [] }\n return { visible: list.slice(0, maxVisible), overflow: list.slice(maxVisible) }\n}\n\n/**\n * 绑定页行:已启用 providers(API 序) ∪ 仅存在于 bindings 的已停用项(接在后面)。\n * 不做 N=4 截断。\n */\nexport function mergeBindingRows(\n providers: readonly SsoProviderLike[],\n bindings: readonly BindingLike[],\n): BindingRow[] {\n const bindByProvider = new Map<string, BindingLike>()\n for (const b of bindings) bindByProvider.set(b.provider, b)\n\n const rows: BindingRow[] = []\n const seen = new Set<string>()\n\n for (const p of providers) {\n seen.add(p.code)\n rows.push({\n code: p.code,\n displayName: p.displayName,\n icon: p.icon,\n enabled: true,\n binding: bindByProvider.get(p.code),\n })\n }\n\n for (const b of bindings) {\n if (seen.has(b.provider)) continue\n rows.push({\n code: b.provider,\n displayName: (b.displayName && b.displayName.trim()) || b.provider,\n icon: null,\n enabled: false,\n binding: b,\n })\n }\n\n return rows\n}\n"],"names":["SSO_VISIBLE_MAX","BRAND_CODES","BRAND_SET","PREVIEW_ALL_SSO_BRANDS","brandDisplayName","code","t","previewAllBrandProviders","LINK_BY_ACCOUNT_CODES","OFFICIAL_TYPES","buildConfigProviderRows","catalog","admin","installed","x","adminByCode","a","byCode","p","rows","seen","push","official","fromCode","state","registered","isBrandCode","isIconifyName","icon","s","resolveProviderIcon","c","WECOM_AUTO_LOGIN_KEY","claimWeComAutoLogin","opts","splitLoginProviders","providers","maxVisible","list","mergeBindingRows","bindings","bindByProvider","b"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ type __VLS_Props = {
2
+ headline: string;
3
+ highlight?: string;
4
+ subtitle?: string;
5
+ features?: string[];
6
+ /** 以下两项供配置中心预览未保存的草稿;不传则取当前站点信息 */
7
+ title?: string;
8
+ logo?: string;
9
+ };
10
+ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
11
+ title: string;
12
+ subtitle: string;
13
+ logo: string;
14
+ highlight: string;
15
+ features: string[];
16
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import o from "./LoginHeroPanel2.vue.js";
2
+ /* empty css */
3
+ import e from "../../../_virtual/_plugin-vue_export-helper.js";
4
+ const c = /* @__PURE__ */ e(o, [["__scopeId", "data-v-a4cecbe6"]]);
5
+ export {
6
+ c as default
7
+ };
8
+ //# sourceMappingURL=LoginHeroPanel.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginHeroPanel.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,66 @@
1
+ import { defineComponent as k, computed as v, openBlock as l, createElementBlock as n, createElementVNode as s, createVNode as h, toDisplayString as a, unref as i, normalizeStyle as u, Fragment as f, renderList as g, createCommentVNode as m, createTextVNode as b } from "vue";
2
+ import { Icon as S } from "@iconify/vue";
3
+ import { useAppStore as N } from "../../../stores/app.js";
4
+ import { useSite as V } from "../../../composables/useSite.js";
5
+ import _ from "../../../components/SmartLogo.vue.js";
6
+ const L = { class: "login-hero-panel" }, z = { class: "logo" }, B = { class: "headline" }, C = {
7
+ key: 0,
8
+ class: "sub"
9
+ }, E = {
10
+ key: 1,
11
+ class: "points"
12
+ }, H = /* @__PURE__ */ k({
13
+ __name: "LoginHeroPanel",
14
+ props: {
15
+ headline: {},
16
+ highlight: { default: "" },
17
+ subtitle: { default: "" },
18
+ features: { default: () => [] },
19
+ title: { default: void 0 },
20
+ logo: { default: void 0 }
21
+ },
22
+ setup(t) {
23
+ const e = t, r = N(), { site: p } = V(), x = v(() => {
24
+ const c = e.highlight ? e.headline.indexOf(e.highlight) : -1;
25
+ return c < 0 ? [{ text: e.headline, accent: !1 }] : [
26
+ { text: e.headline.slice(0, c), accent: !1 },
27
+ { text: e.highlight, accent: !0 },
28
+ { text: e.headline.slice(c + e.highlight.length), accent: !1 }
29
+ ].filter((d) => d.text);
30
+ });
31
+ return (c, d) => (l(), n("div", L, [
32
+ s("div", z, [
33
+ h(_, {
34
+ size: 34,
35
+ src: t.logo
36
+ }, null, 8, ["src"]),
37
+ s("span", null, a(t.title ?? i(p).title), 1)
38
+ ]),
39
+ s("div", {
40
+ class: "bar",
41
+ style: u({ background: i(r).accent })
42
+ }, null, 4),
43
+ s("h1", B, [
44
+ (l(!0), n(f, null, g(x.value, (o, y) => (l(), n("span", {
45
+ key: y,
46
+ style: u(o.accent ? { color: i(r).accent } : void 0)
47
+ }, a(o.text), 5))), 128))
48
+ ]),
49
+ t.subtitle ? (l(), n("p", C, a(t.subtitle), 1)) : m("", !0),
50
+ t.features.length ? (l(), n("ul", E, [
51
+ (l(!0), n(f, null, g(t.features, (o) => (l(), n("li", { key: o }, [
52
+ h(i(S), {
53
+ icon: "ph:check-circle-duotone",
54
+ width: 18,
55
+ style: u({ color: i(r).accent })
56
+ }, null, 8, ["style"]),
57
+ b(" " + a(o), 1)
58
+ ]))), 128))
59
+ ])) : m("", !0)
60
+ ]));
61
+ }
62
+ });
63
+ export {
64
+ H as default
65
+ };
66
+ //# sourceMappingURL=LoginHeroPanel2.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginHeroPanel2.vue.js","sources":["../../../../src/views/login/components/LoginHeroPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useAppStore } from '#/stores/app'\nimport { useSite } from '#/composables/useSite'\nimport SmartLogo from '#/components/SmartLogo.vue'\n\nconst props = withDefaults(\n defineProps<{\n headline: string\n highlight?: string\n subtitle?: string\n features?: string[]\n /** 以下两项供配置中心预览未保存的草稿;不传则取当前站点信息 */\n title?: string\n logo?: string\n }>(),\n {\n highlight: '',\n subtitle: '',\n features: () => [],\n title: undefined,\n logo: undefined,\n },\n)\n\nconst app = useAppStore()\nconst { site } = useSite()\n\n// 只做纯文本切片,不用 v-html;强调词只会成为一个普通 span。\nconst headlineParts = computed(() => {\n const index = props.highlight ? props.headline.indexOf(props.highlight) : -1\n if (index < 0) return [{ text: props.headline, accent: false }]\n return [\n { text: props.headline.slice(0, index), accent: false },\n { text: props.highlight, accent: true },\n { text: props.headline.slice(index + props.highlight.length), accent: false },\n ].filter(part => part.text)\n})\n</script>\n\n<template>\n <div class=\"login-hero-panel\">\n <div class=\"logo\">\n <SmartLogo :size=\"34\" :src=\"logo\" />\n <span>{{ title ?? site.title }}</span>\n </div>\n <div class=\"bar\" :style=\"{ background: app.accent }\" />\n <h1 class=\"headline\">\n <span\n v-for=\"(part, index) in headlineParts\"\n :key=\"index\"\n :style=\"part.accent ? { color: app.accent } : undefined\"\n >\n {{ part.text }}\n </span>\n </h1>\n <p v-if=\"subtitle\" class=\"sub\">{{ subtitle }}</p>\n <ul v-if=\"features.length\" class=\"points\">\n <li v-for=\"feature in features\" :key=\"feature\">\n <Icon icon=\"ph:check-circle-duotone\" :width=\"18\" :style=\"{ color: app.accent }\" />\n {{ feature }}\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.login-hero-panel {\n min-width: 0;\n}\n.logo {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 22px;\n font-weight: 700;\n color: #2a3c82;\n}\n.bar {\n width: 40px;\n height: 3px;\n border-radius: 2px;\n margin: 28px 0 20px;\n}\n.headline {\n font-size: 42px;\n line-height: 1.2;\n font-weight: 800;\n color: var(--color-text-primary);\n margin: 0;\n}\n.sub {\n color: var(--color-text-secondary);\n margin: 16px 0 28px;\n}\n.points {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.points li {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--color-text-secondary);\n}\n</style>\n"],"names":["props","__props","app","useAppStore","site","useSite","headlineParts","computed","index","part","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","SmartLogo","_toDisplayString","_unref","_normalizeStyle","_hoisted_3","_Fragment","_renderList","_hoisted_4","_hoisted_5","feature","Icon","_createTextVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAOA,UAAMA,IAAQC,GAmBRC,IAAMC,EAAA,GACN,EAAE,MAAAC,EAAA,IAASC,EAAA,GAGXC,IAAgBC,EAAS,MAAM;AACnC,YAAMC,IAAQR,EAAM,YAAYA,EAAM,SAAS,QAAQA,EAAM,SAAS,IAAI;AAC1E,aAAIQ,IAAQ,IAAU,CAAC,EAAE,MAAMR,EAAM,UAAU,QAAQ,IAAO,IACvD;AAAA,QACL,EAAE,MAAMA,EAAM,SAAS,MAAM,GAAGQ,CAAK,GAAG,QAAQ,GAAA;AAAA,QAChD,EAAE,MAAMR,EAAM,WAAW,QAAQ,GAAA;AAAA,QACjC,EAAE,MAAMA,EAAM,SAAS,MAAMQ,IAAQR,EAAM,UAAU,MAAM,GAAG,QAAQ,GAAA;AAAA,MAAM,EAC5E,OAAO,CAAAS,MAAQA,EAAK,IAAI;AAAA,IAC5B,CAAC;sBAICC,EAAA,GAAAC,EAsBM,OAtBNC,GAsBM;AAAA,MArBJC,EAGM,OAHNC,GAGM;AAAA,QAFJC,EAAoCC,GAAA;AAAA,UAAxB,MAAM;AAAA,UAAK,KAAKf,EAAA;AAAA,QAAA;QAC5BY,EAAsC,QAAA,MAAAI,EAA7BhB,EAAA,SAASiB,EAAAd,CAAA,EAAK,KAAK,GAAA,CAAA;AAAA,MAAA;MAE9BS,EAAuD,OAAA;AAAA,QAAlD,OAAM;AAAA,QAAO,OAAKM,EAAA,EAAA,YAAgBD,EAAAhB,CAAA,EAAI,QAAM;AAAA,MAAA;MACjDW,EAQK,MARLO,GAQK;AAAA,SAPHV,EAAA,EAAA,GAAAC,EAMOU,GAAA,MAAAC,EALmBhB,EAAA,OAAa,CAA7BG,GAAMD,YADhBG,EAMO,QAAA;AAAA,UAJJ,KAAKH;AAAA,UACL,OAAKW,EAAEV,EAAK,kBAAkBS,EAAAhB,CAAA,EAAI,OAAA,IAAW,MAAS;AAAA,QAAA,GAEpDe,EAAAR,EAAK,IAAI,GAAA,CAAA;;MAGPR,EAAA,iBAATU,EAAiD,KAAjDY,GAAiDN,EAAfhB,EAAA,QAAQ,GAAA,CAAA;MAChCA,EAAA,SAAS,UAAnBS,KAAAC,EAKK,MALLa,GAKK;AAAA,gBAJHb,EAGKU,GAAA,MAAAC,EAHiBrB,EAAA,UAAQ,CAAnBwB,YAAXd,EAGK,MAAA,EAH4B,KAAKc,KAAO;AAAA,UAC3CV,EAAkFG,EAAAQ,CAAA,GAAA;AAAA,YAA5E,MAAK;AAAA,YAA2B,OAAO;AAAA,YAAK,OAAKP,EAAA,EAAA,OAAWD,EAAAhB,CAAA,EAAI,QAAM;AAAA,UAAA;UAAMyB,EAAA,QAC/EF,CAAO,GAAA,CAAA;AAAA,QAAA;;;;;"}
@@ -1,7 +1,7 @@
1
1
  import o from "./SplitPanel2.vue.js";
2
2
  /* empty css */
3
3
  import t from "../../../_virtual/_plugin-vue_export-helper.js";
4
- const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-75743368"]]);
4
+ const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-b4c7728a"]]);
5
5
  export {
6
6
  m as default
7
7
  };
@@ -1,85 +1,65 @@
1
- import { defineComponent as b, computed as h, openBlock as l, createElementBlock as i, normalizeStyle as a, createElementVNode as t, createVNode as p, toDisplayString as o, unref as e, createTextVNode as r, Fragment as u, renderList as k, createCommentVNode as w } from "vue";
2
- import { Icon as S } from "@iconify/vue";
3
- import { useI18n as V } from "vue-i18n";
4
- import { useAppStore as x } from "../../../stores/app.js";
5
- import { useSite as F } from "../../../composables/useSite.js";
6
- import { rgba as f, mix as N } from "../../../theme/mix.js";
7
- import P from "../../../components/SmartLogo.vue.js";
8
- import B from "../LoginForm.vue.js";
9
- const C = { class: "panel" }, L = { class: "panel-inner" }, z = { class: "logo" }, A = { class: "headline" }, D = { class: "sub" }, E = { class: "points" }, I = { class: "form-wrap" }, U = { class: "mid" }, R = { class: "form-inner" }, T = { class: "greet" }, Y = { class: "greet-sub" }, j = { class: "foot" }, q = ["href"], G = {
1
+ import { defineComponent as u, computed as g, openBlock as r, createElementBlock as i, normalizeStyle as v, createElementVNode as t, createVNode as m, unref as e, toDisplayString as s, createTextVNode as h, Fragment as y, createCommentVNode as b } from "vue";
2
+ import { useI18n as w } from "vue-i18n";
3
+ import { useLoginHero as k } from "../../../composables/useLoginHero.js";
4
+ import { useAppStore as S } from "../../../stores/app.js";
5
+ import { useSite as V } from "../../../composables/useSite.js";
6
+ import { rgba as d, mix as x } from "../../../theme/mix.js";
7
+ import F from "../LoginForm.vue.js";
8
+ import N from "../components/LoginHeroPanel.vue.js";
9
+ const B = { class: "panel" }, C = { class: "panel-inner" }, L = { class: "form-wrap" }, D = { class: "mid" }, E = { class: "form-inner" }, H = { class: "greet" }, P = { class: "greet-sub" }, U = { class: "foot" }, z = ["href"], A = {
10
10
  key: 2,
11
11
  class: "foot-ver"
12
- }, ee = /* @__PURE__ */ b({
12
+ }, Q = /* @__PURE__ */ u({
13
13
  __name: "SplitPanel",
14
- setup(H) {
15
- const { t: s } = V(), c = x(), { site: n, appVersion: d } = F(), g = (/* @__PURE__ */ new Date()).getFullYear(), y = h(() => [s("login.featRbac"), s("login.featScope"), s("login.featPortal")]), v = h(() => ({
16
- "--a1": f(c.accent, 0.5),
17
- "--a2": f(N(c.accent, "#8B5CF6", 0.6), 0.4)
14
+ setup(I) {
15
+ const { t: n } = w(), a = S(), { site: o, appVersion: c } = V(), l = k(), _ = (/* @__PURE__ */ new Date()).getFullYear(), f = g(() => ({
16
+ "--a1": d(a.accent, 0.5),
17
+ "--a2": d(x(a.accent, "#8B5CF6", 0.6), 0.4)
18
18
  }));
19
- return (J, _) => (l(), i("div", {
19
+ return (T, p) => (r(), i("div", {
20
20
  class: "split",
21
- style: a(v.value)
21
+ style: v(f.value)
22
22
  }, [
23
- t("div", C, [
24
- _[0] || (_[0] = t("div", { class: "panel-aurora" }, null, -1)),
25
- t("div", L, [
26
- t("div", z, [
27
- p(P, { size: 34 }),
28
- t("span", null, o(e(n).title), 1)
29
- ]),
30
- t("div", {
31
- class: "bar",
32
- style: a({ background: e(c).accent })
33
- }, null, 4),
34
- t("h1", A, [
35
- r(o(e(s)("login.headlinePre")) + " ", 1),
36
- t("span", {
37
- style: a({ color: e(c).accent })
38
- }, o(e(s)("login.headlineAccent")), 5),
39
- r(" " + o(e(s)("login.headlinePost")), 1)
40
- ]),
41
- t("p", D, o(e(n).subtitle || e(s)("login.subtitle")), 1),
42
- t("ul", E, [
43
- (l(!0), i(u, null, k(y.value, (m) => (l(), i("li", { key: m }, [
44
- p(e(S), {
45
- icon: "ph:check-circle-duotone",
46
- width: 18,
47
- style: a({ color: e(c).accent })
48
- }, null, 8, ["style"]),
49
- r(" " + o(m), 1)
50
- ]))), 128))
51
- ])
23
+ t("div", B, [
24
+ p[0] || (p[0] = t("div", { class: "panel-aurora" }, null, -1)),
25
+ t("div", C, [
26
+ m(N, {
27
+ headline: e(l).headline,
28
+ highlight: e(l).highlight,
29
+ subtitle: e(o).subtitle || e(n)("login.subtitle"),
30
+ features: e(l).features
31
+ }, null, 8, ["headline", "highlight", "subtitle", "features"])
52
32
  ])
53
33
  ]),
54
- t("div", I, [
55
- t("div", U, [
56
- t("div", R, [
57
- t("p", T, o(e(s)("login.welcome")), 1),
58
- t("p", Y, o(e(s)("login.welcomeSub")), 1),
59
- p(B, {
34
+ t("div", L, [
35
+ t("div", D, [
36
+ t("div", E, [
37
+ t("p", H, s(e(n)("login.welcome")), 1),
38
+ t("p", P, s(e(n)("login.welcomeSub")), 1),
39
+ m(F, {
60
40
  "show-logo": !1,
61
41
  "show-title": !1,
62
42
  "show-footer": !1
63
43
  })
64
44
  ])
65
45
  ]),
66
- t("p", j, [
67
- r(" © " + o(e(g)) + " ", 1),
68
- e(n).copyrightUrl ? (l(), i("a", {
46
+ t("p", U, [
47
+ h(" © " + s(e(_)) + " ", 1),
48
+ e(o).copyrightUrl ? (r(), i("a", {
69
49
  key: 0,
70
- href: e(n).copyrightUrl,
50
+ href: e(o).copyrightUrl,
71
51
  target: "_blank",
72
52
  rel: "noopener"
73
- }, o(e(n).copyright || e(n).title), 9, q)) : (l(), i(u, { key: 1 }, [
74
- r(o(e(n).copyright || e(n).title), 1)
53
+ }, s(e(o).copyright || e(o).title), 9, z)) : (r(), i(y, { key: 1 }, [
54
+ h(s(e(o).copyright || e(o).title), 1)
75
55
  ], 64)),
76
- e(d) ? (l(), i("span", G, "v" + o(e(d)), 1)) : w("", !0)
56
+ e(c) ? (r(), i("span", A, "v" + s(e(c)), 1)) : b("", !0)
77
57
  ])
78
58
  ])
79
59
  ], 4));
80
60
  }
81
61
  });
82
62
  export {
83
- ee as default
63
+ Q as default
84
64
  };
85
65
  //# sourceMappingURL=SplitPanel2.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SplitPanel2.vue.js","sources":["../../../../src/views/login/skins/SplitPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore } from '#/stores/app'\nimport { useSite } from '#/composables/useSite'\nimport { mix, rgba } from '#/theme/mix'\nimport SmartLogo from '#/components/SmartLogo.vue'\nimport LoginForm from '../LoginForm.vue'\n\nconst { t } = useI18n()\nconst app = useAppStore()\nconst { site, appVersion } = useSite()\nconst year = new Date().getFullYear()\n\n// 卖点随语言切换(t 在 computed 内对 locale 响应)。\nconst points = computed(() => [t('login.featRbac'), t('login.featScope'), t('login.featPortal')])\n\nconst vars = computed(() => ({\n '--a1': rgba(app.accent, 0.5),\n '--a2': rgba(mix(app.accent, '#8B5CF6', 0.6), 0.4),\n}))\n</script>\n\n<template>\n <div class=\"split\" :style=\"vars\">\n <!-- 左:品牌面板(窄屏隐藏)-->\n <div class=\"panel\">\n <div class=\"panel-aurora\" />\n <div class=\"panel-inner\">\n <div class=\"logo\">\n <!-- 站点 logo 的取值顺序(配置 → brand 选项 → 内置矢量标)统一在 SmartLogo 里 -->\n <SmartLogo :size=\"34\" />\n <span>{{ site.title }}</span>\n </div>\n <div class=\"bar\" :style=\"{ background: app.accent }\" />\n <!-- 标题拆 pre/accent/post 三段以支持 i18n,中间词染 accent 色(整句硬编码中文切不了英文) -->\n <h1 class=\"headline\">\n {{ t('login.headlinePre') }}\n <span :style=\"{ color: app.accent }\">{{ t('login.headlineAccent') }}</span>\n {{ t('login.headlinePost') }}\n </h1>\n <p class=\"sub\">{{ site.subtitle || t('login.subtitle') }}</p>\n <ul class=\"points\">\n <li v-for=\"p in points\" :key=\"p\">\n <Icon icon=\"ph:check-circle-duotone\" :width=\"18\" :style=\"{ color: app.accent }\" />\n {{ p }}\n </li>\n </ul>\n </div>\n </div>\n\n <!-- 右:全高工作区(居中表单 + 版权页脚);主题/语言切换在外壳全局工具药丸 -->\n <div class=\"form-wrap\">\n <div class=\"mid\">\n <div class=\"form-inner\">\n <p class=\"greet\">{{ t('login.welcome') }}</p>\n <p class=\"greet-sub\">{{ t('login.welcomeSub') }}</p>\n <LoginForm :show-logo=\"false\" :show-title=\"false\" :show-footer=\"false\" />\n </div>\n </div>\n\n <p class=\"foot\">\n © {{ year }}\n <a v-if=\"site.copyrightUrl\" :href=\"site.copyrightUrl\" target=\"_blank\" rel=\"noopener\">\n {{ site.copyright || site.title }}\n </a>\n <template v-else>{{ site.copyright || site.title }}</template>\n <span v-if=\"appVersion\" class=\"foot-ver\">v{{ appVersion }}</span>\n </p>\n </div>\n </div>\n</template>\n\n<style scoped>\n.split {\n height: 100dvh;\n display: grid;\n grid-template-columns: 1.15fr 0.85fr;\n background: var(--color-bg-body);\n}\n/* 左栏 = recessed 品牌面(body 底 + 极光),与右栏 clean container 拉开图/底关系 */\n.panel {\n position: relative;\n overflow: hidden;\n background: var(--color-bg-body);\n border-right: 1px solid var(--color-border);\n}\n/* 细网格纹理,左上淡出 */\n.panel::before {\n content: '';\n position: absolute;\n inset: 0;\n background-image:\n linear-gradient(rgba(127, 127, 127, 0.08) 1px, transparent 1px),\n linear-gradient(90deg, rgba(127, 127, 127, 0.08) 1px, transparent 1px);\n background-size: 40px 40px;\n -webkit-mask-image: radial-gradient(circle at 30% 40%, #000, transparent 72%);\n mask-image: radial-gradient(circle at 30% 40%, #000, transparent 72%);\n}\n.panel-aurora {\n position: absolute;\n inset: -20%;\n background:\n radial-gradient(40% 40% at 25% 20%, var(--a1), transparent 68%),\n radial-gradient(45% 45% at 80% 78%, var(--a2), transparent 70%);\n filter: blur(45px);\n opacity: 0.9;\n animation: panel-move 22s ease-in-out infinite alternate;\n}\n@keyframes panel-move {\n 0% {\n transform: translate3d(-3%, -2%, 0) scale(1.05);\n }\n 100% {\n transform: translate3d(3%, 3%, 0) scale(1.12);\n }\n}\n.panel-inner {\n position: relative;\n z-index: 1;\n padding: 64px 56px;\n display: flex;\n flex-direction: column;\n height: 100%;\n justify-content: center;\n}\n.logo {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 22px;\n font-weight: 700;\n color: #2a3c82;\n}\n/* 后台配置的品牌 logo:限高与内置矢量 logo(size=40)齐平,宽度自适应不变形 */\n.bar {\n width: 40px;\n height: 3px;\n border-radius: 2px;\n margin: 28px 0 20px;\n}\n.headline {\n font-size: 42px;\n line-height: 1.2;\n font-weight: 800;\n color: var(--color-text-primary);\n margin: 0;\n}\n.sub {\n color: var(--color-text-secondary);\n margin: 16px 0 28px;\n}\n.points {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.points li {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--color-text-secondary);\n}\n\n/* 右栏 = 全高工作区:居中表单 + 页脚(主题/语言切换在外壳全局工具) */\n.form-wrap {\n position: relative;\n display: flex;\n flex-direction: column;\n background: var(--color-bg-container);\n}\n.mid {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n}\n.form-inner {\n width: 100%;\n max-width: 340px;\n animation: fade-up 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;\n}\n.greet {\n font-size: 26px;\n font-weight: 700;\n letter-spacing: -0.01em;\n color: var(--color-text-primary);\n margin: 0 0 6px;\n}\n.greet-sub {\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n margin: 0 0 26px;\n}\n.foot {\n margin: 0;\n padding: 18px 24px 22px;\n text-align: center;\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n}\n.foot a {\n color: inherit;\n text-decoration: none;\n}\n.foot a:hover {\n color: var(--color-primary);\n}\n.foot-ver {\n margin-left: 8px;\n opacity: 0.75;\n}\n@keyframes fade-up {\n from {\n opacity: 0;\n transform: translateY(16px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@media (max-width: 900px) {\n .split {\n grid-template-columns: 1fr;\n }\n .panel {\n display: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .panel-aurora,\n .form-inner {\n animation: none;\n }\n}\n</style>\n"],"names":["t","useI18n","app","useAppStore","site","appVersion","useSite","year","points","computed","vars","rgba","mix","_createElementBlock","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_createVNode","SmartLogo","_toDisplayString","_unref","_normalizeStyle","_hoisted_4","_createTextVNode","_hoisted_5","_hoisted_6","_Fragment","_renderList","p","Icon","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","LoginForm","_hoisted_12","_hoisted_13","_openBlock","_hoisted_14"],"mappings":"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"}
1
+ {"version":3,"file":"SplitPanel2.vue.js","sources":["../../../../src/views/login/skins/SplitPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { useLoginHero } from '#/composables/useLoginHero'\nimport { useAppStore } from '#/stores/app'\nimport { useSite } from '#/composables/useSite'\nimport { mix, rgba } from '#/theme/mix'\nimport LoginForm from '../LoginForm.vue'\nimport LoginHeroPanel from '../components/LoginHeroPanel.vue'\n\nconst { t } = useI18n()\nconst app = useAppStore()\nconst { site, appVersion } = useSite()\nconst hero = useLoginHero()\nconst year = new Date().getFullYear()\n\nconst vars = computed(() => ({\n '--a1': rgba(app.accent, 0.5),\n '--a2': rgba(mix(app.accent, '#8B5CF6', 0.6), 0.4),\n}))\n</script>\n\n<template>\n <div class=\"split\" :style=\"vars\">\n <!-- 左:品牌面板(窄屏隐藏)-->\n <div class=\"panel\">\n <div class=\"panel-aurora\" />\n <div class=\"panel-inner\">\n <LoginHeroPanel\n :headline=\"hero.headline\"\n :highlight=\"hero.highlight\"\n :subtitle=\"site.subtitle || t('login.subtitle')\"\n :features=\"hero.features\"\n />\n </div>\n </div>\n\n <!-- 右:全高工作区(居中表单 + 版权页脚);主题/语言切换在外壳全局工具药丸 -->\n <div class=\"form-wrap\">\n <div class=\"mid\">\n <div class=\"form-inner\">\n <p class=\"greet\">{{ t('login.welcome') }}</p>\n <p class=\"greet-sub\">{{ t('login.welcomeSub') }}</p>\n <LoginForm :show-logo=\"false\" :show-title=\"false\" :show-footer=\"false\" />\n </div>\n </div>\n\n <p class=\"foot\">\n © {{ year }}\n <a v-if=\"site.copyrightUrl\" :href=\"site.copyrightUrl\" target=\"_blank\" rel=\"noopener\">\n {{ site.copyright || site.title }}\n </a>\n <template v-else>{{ site.copyright || site.title }}</template>\n <span v-if=\"appVersion\" class=\"foot-ver\">v{{ appVersion }}</span>\n </p>\n </div>\n </div>\n</template>\n\n<style scoped>\n.split {\n height: 100dvh;\n display: grid;\n grid-template-columns: 1.15fr 0.85fr;\n background: var(--color-bg-body);\n}\n/* 左栏 = recessed 品牌面(body 底 + 极光),与右栏 clean container 拉开图/底关系 */\n.panel {\n position: relative;\n overflow: hidden;\n background: var(--color-bg-body);\n border-right: 1px solid var(--color-border);\n}\n/* 细网格纹理,左上淡出 */\n.panel::before {\n content: '';\n position: absolute;\n inset: 0;\n background-image:\n linear-gradient(rgba(127, 127, 127, 0.08) 1px, transparent 1px),\n linear-gradient(90deg, rgba(127, 127, 127, 0.08) 1px, transparent 1px);\n background-size: 40px 40px;\n -webkit-mask-image: radial-gradient(circle at 30% 40%, #000, transparent 72%);\n mask-image: radial-gradient(circle at 30% 40%, #000, transparent 72%);\n}\n.panel-aurora {\n position: absolute;\n inset: -20%;\n background:\n radial-gradient(40% 40% at 25% 20%, var(--a1), transparent 68%),\n radial-gradient(45% 45% at 80% 78%, var(--a2), transparent 70%);\n filter: blur(45px);\n opacity: 0.9;\n animation: panel-move 22s ease-in-out infinite alternate;\n}\n@keyframes panel-move {\n 0% {\n transform: translate3d(-3%, -2%, 0) scale(1.05);\n }\n 100% {\n transform: translate3d(3%, 3%, 0) scale(1.12);\n }\n}\n.panel-inner {\n position: relative;\n z-index: 1;\n padding: 64px 56px;\n display: flex;\n flex-direction: column;\n height: 100%;\n justify-content: center;\n}\n/* 右栏 = 全高工作区:居中表单 + 页脚(主题/语言切换在外壳全局工具) */\n.form-wrap {\n position: relative;\n display: flex;\n flex-direction: column;\n background: var(--color-bg-container);\n}\n.mid {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n}\n.form-inner {\n width: 100%;\n max-width: 340px;\n animation: fade-up 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;\n}\n.greet {\n font-size: 26px;\n font-weight: 700;\n letter-spacing: -0.01em;\n color: var(--color-text-primary);\n margin: 0 0 6px;\n}\n.greet-sub {\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n margin: 0 0 26px;\n}\n.foot {\n margin: 0;\n padding: 18px 24px 22px;\n text-align: center;\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n}\n.foot a {\n color: inherit;\n text-decoration: none;\n}\n.foot a:hover {\n color: var(--color-primary);\n}\n.foot-ver {\n margin-left: 8px;\n opacity: 0.75;\n}\n@keyframes fade-up {\n from {\n opacity: 0;\n transform: translateY(16px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@media (max-width: 900px) {\n .split {\n grid-template-columns: 1fr;\n }\n .panel {\n display: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .panel-aurora,\n .form-inner {\n animation: none;\n }\n}\n</style>\n"],"names":["t","useI18n","app","useAppStore","site","appVersion","useSite","hero","useLoginHero","year","vars","computed","rgba","mix","_createElementBlock","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","LoginHeroPanel","_unref","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_toDisplayString","_hoisted_7","LoginForm","_hoisted_8","_hoisted_9","_Fragment","_createTextVNode","_openBlock","_hoisted_10"],"mappings":";;;;;;;;;;;;;;AAUA,UAAM,EAAE,GAAAA,EAAA,IAAMC,EAAA,GACRC,IAAMC,EAAA,GACN,EAAE,MAAAC,GAAM,YAAAC,EAAA,IAAeC,EAAA,GACvBC,IAAOC,EAAA,GACPC,KAAO,oBAAI,KAAA,GAAO,YAAA,GAElBC,IAAOC,EAAS,OAAO;AAAA,MAC3B,QAAQC,EAAKV,EAAI,QAAQ,GAAG;AAAA,MAC5B,QAAQU,EAAKC,EAAIX,EAAI,QAAQ,WAAW,GAAG,GAAG,GAAG;AAAA,IAAA,EACjD;2BAIAY,EAiCM,OAAA;AAAA,MAjCD,OAAM;AAAA,MAAS,SAAOJ,EAAA,KAAI;AAAA,IAAA;MAE7BK,EAUM,OAVNC,GAUM;AAAA,wBATJD,EAA4B,OAAA,EAAvB,OAAM,eAAA,GAAc,MAAA,EAAA;AAAA,QACzBA,EAOM,OAPNE,GAOM;AAAA,UANJC,EAKEC,GAAA;AAAA,YAJC,UAAUC,EAAAb,CAAA,EAAK;AAAA,YACf,WAAWa,EAAAb,CAAA,EAAK;AAAA,YAChB,UAAUa,EAAAhB,CAAA,EAAK,YAAYgB,EAAApB,CAAA,EAAC,gBAAA;AAAA,YAC5B,UAAUoB,EAAAb,CAAA,EAAK;AAAA,UAAA;;;MAMtBQ,EAiBM,OAjBNM,GAiBM;AAAA,QAhBJN,EAMM,OANNO,GAMM;AAAA,UALJP,EAIM,OAJNQ,GAIM;AAAA,YAHJR,EAA6C,KAA7CS,GAA6CC,EAAzBL,EAAApB,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,YACrBe,EAAoD,KAApDW,GAAoDD,EAA5BL,EAAApB,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,YACzBkB,EAAyES,GAAA;AAAA,cAA7D,aAAW;AAAA,cAAQ,cAAY;AAAA,cAAQ,eAAa;AAAA,YAAA;;;QAIpEZ,EAOI,KAPJa,GAOI;AAAA,YAPY,QACZH,EAAGL,EAAAX,CAAA,CAAI,IAAG,KACZ,CAAA;AAAA,UAASW,EAAAhB,CAAA,EAAK,qBAAdU,EAEI,KAAA;AAAA;YAFyB,MAAMM,EAAAhB,CAAA,EAAK;AAAA,YAAc,QAAO;AAAA,YAAS,KAAI;AAAA,UAAA,GACrEqB,EAAAL,EAAAhB,CAAA,EAAK,aAAagB,EAAAhB,CAAA,EAAK,KAAK,GAAA,GAAAyB,CAAA,WAEjCf,EAA8DgB,GAAA,EAAA,KAAA,KAAA;AAAA,YAA1CC,EAAAN,EAAAL,EAAAhB,CAAA,EAAK,aAAagB,EAAAhB,CAAA,EAAK,KAAK,GAAA,CAAA;AAAA,UAAA;UACpCgB,EAAAf,CAAA,KAAZ2B,KAAAlB,EAAiE,QAAjEmB,GAAyC,QAAIb,EAAAf,CAAA,CAAU,GAAA,CAAA;;;;;;"}
@@ -0,0 +1,8 @@
1
+ import o from "./AdminMock2.vue.js";
2
+ /* empty css */
3
+ import t from "../../../../_virtual/_plugin-vue_export-helper.js";
4
+ const f = /* @__PURE__ */ t(o, [["__scopeId", "data-v-7ad8e65f"]]);
5
+ export {
6
+ f as default
7
+ };
8
+ //# sourceMappingURL=AdminMock.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminMock.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,76 @@
1
+ import { defineComponent as f, computed as r, openBlock as e, createElementBlock as i, createElementVNode as s, withDirectives as u, createVNode as h, toDisplayString as c, unref as m, Fragment as g, renderList as k, normalizeStyle as $ } from "vue";
2
+ import y from "../../../../components/SmartLogo.vue.js";
3
+ import { LOGO_KEY as b } from "../groups.js";
4
+ import { useConfigDraft as w } from "../draft.js";
5
+ import { vFlash as v } from "../flash.js";
6
+ const S = { class: "mock" }, z = { class: "chrome" }, D = { class: "btab" }, E = { class: "app" }, L = { class: "side" }, x = {
7
+ class: "brand",
8
+ "data-testid": "preview-brand"
9
+ }, A = { class: "main" }, B = { class: "foot" }, C = { key: 0 }, F = { key: 1 }, M = /* @__PURE__ */ f({
10
+ __name: "AdminMock",
11
+ setup(N) {
12
+ const { values: a } = w(), l = r(() => {
13
+ var t;
14
+ return ((t = a["sys.site.title"]) == null ? void 0 : t.trim()) || "SmartAdmin";
15
+ }), d = r(() => {
16
+ var t;
17
+ return ((t = a["sys.site.copyright"]) == null ? void 0 : t.trim()) || l.value;
18
+ }), p = r(() => {
19
+ var t;
20
+ return !!((t = a["sys.site.copyrightUrl"]) != null && t.trim());
21
+ }), n = r(() => a[b] ?? "");
22
+ return (t, o) => (e(), i("div", S, [
23
+ s("div", z, [
24
+ o[0] || (o[0] = s("span", { class: "lights" }, [
25
+ s("i"),
26
+ s("i"),
27
+ s("i")
28
+ ], -1)),
29
+ u((e(), i("span", D, [
30
+ h(y, {
31
+ size: 16,
32
+ src: n.value
33
+ }, null, 8, ["src"]),
34
+ s("span", null, c(l.value), 1)
35
+ ])), [
36
+ [m(v), `${l.value}|${n.value}`]
37
+ ])
38
+ ]),
39
+ s("div", E, [
40
+ s("div", L, [
41
+ u((e(), i("div", x, [
42
+ h(y, {
43
+ size: 30,
44
+ src: n.value
45
+ }, null, 8, ["src"]),
46
+ s("span", null, c(l.value), 1)
47
+ ])), [
48
+ [m(v), `${l.value}|${n.value}`]
49
+ ]),
50
+ (e(), i(g, null, k(5, (_) => s("i", {
51
+ key: _,
52
+ style: $({ width: _ % 2 ? "80%" : "62%" })
53
+ }, null, 4)), 64))
54
+ ]),
55
+ s("div", A, [
56
+ o[1] || (o[1] = s("div", { class: "top" }, null, -1)),
57
+ o[2] || (o[2] = s("div", { class: "body" }, [
58
+ s("i", { class: "w" }),
59
+ s("i"),
60
+ s("i"),
61
+ s("i")
62
+ ], -1)),
63
+ u((e(), i("div", B, [
64
+ p.value ? (e(), i("a", C, "© " + c(d.value), 1)) : (e(), i("span", F, "© " + c(d.value), 1))
65
+ ])), [
66
+ [m(v), `${d.value}|${p.value}`]
67
+ ])
68
+ ])
69
+ ])
70
+ ]));
71
+ }
72
+ });
73
+ export {
74
+ M as default
75
+ };
76
+ //# sourceMappingURL=AdminMock2.vue.js.map