@tuya-sat/sdf-main-sdk 0.0.1-beta.1

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 (147) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/README.md +1 -0
  3. package/antd.less.overwrite.js +56 -0
  4. package/color.js +140 -0
  5. package/dark-variable.less +1449 -0
  6. package/package.json +74 -0
  7. package/scripts/gen-localize-file.mjs +56 -0
  8. package/src/App.less +156 -0
  9. package/src/App.tsx +87 -0
  10. package/src/api/index.ts +52 -0
  11. package/src/api/req.ts +23 -0
  12. package/src/api/res.ts +29 -0
  13. package/src/api/urls.ts +30 -0
  14. package/src/api/utils.ts +41 -0
  15. package/src/assets/imgs/404.svg +194 -0
  16. package/src/assets/imgs/reLogin.png +0 -0
  17. package/src/components/404/index.tsx +44 -0
  18. package/src/components/500/index.tsx +49 -0
  19. package/src/components/BCustomNav/index.module.less +17 -0
  20. package/src/components/BCustomNav/index.tsx +108 -0
  21. package/src/components/BForgot/index.module.less +5 -0
  22. package/src/components/BForgot/index.tsx +96 -0
  23. package/src/components/BHeaderUser/account.png +0 -0
  24. package/src/components/BHeaderUser/app-scan-en.png +0 -0
  25. package/src/components/BHeaderUser/app-scan-zh.png +0 -0
  26. package/src/components/BHeaderUser/app-scan.png +0 -0
  27. package/src/components/BHeaderUser/components/BSwitchLang/index.module.less +6 -0
  28. package/src/components/BHeaderUser/components/BSwitchLang/index.tsx +56 -0
  29. package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/Content.tsx +199 -0
  30. package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/index.module.less +11 -0
  31. package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/index.tsx +27 -0
  32. package/src/components/BHeaderUser/components/Badge/components/Notice/hooks.ts +104 -0
  33. package/src/components/BHeaderUser/components/Badge/components/Notice/index.module.less +70 -0
  34. package/src/components/BHeaderUser/components/Badge/components/Notice/index.tsx +184 -0
  35. package/src/components/BHeaderUser/components/Badge/components/Notice/table/index.tsx +184 -0
  36. package/src/components/BHeaderUser/components/Badge/components/Notice/table/read.tsx +67 -0
  37. package/src/components/BHeaderUser/components/Badge/components/Notice/tools/index.tsx +116 -0
  38. package/src/components/BHeaderUser/components/Badge/index.module.less +99 -0
  39. package/src/components/BHeaderUser/components/Badge/index.tsx +179 -0
  40. package/src/components/BHeaderUser/index.module.less +105 -0
  41. package/src/components/BHeaderUser/index.tsx +261 -0
  42. package/src/components/BHeaderUser/logout.tsx +26 -0
  43. package/src/components/BLayout/components/Header/index.module.less +27 -0
  44. package/src/components/BLayout/components/Header/index.tsx +36 -0
  45. package/src/components/BLayout/components/Layout/empty.tsx +35 -0
  46. package/src/components/BLayout/components/Layout/emptyPage.png +0 -0
  47. package/src/components/BLayout/components/Layout/index.tsx +72 -0
  48. package/src/components/BLayout/components/Logo.tsx +6 -0
  49. package/src/components/BLayout/components/Menu/collapse.tsx +41 -0
  50. package/src/components/BLayout/components/Menu/image/close.tsx +26 -0
  51. package/src/components/BLayout/components/Menu/image/closedefault.tsx +26 -0
  52. package/src/components/BLayout/components/Menu/image/open.tsx +38 -0
  53. package/src/components/BLayout/components/Menu/image/opendefault.tsx +38 -0
  54. package/src/components/BLayout/components/Menu/index.module.less +125 -0
  55. package/src/components/BLayout/components/Menu/index.tsx +244 -0
  56. package/src/components/BLayout/components/MenuIcon.module.less +5 -0
  57. package/src/components/BLayout/components/MenuIcon.tsx +46 -0
  58. package/src/components/BLayout/components/MultiSider/index.module.less +104 -0
  59. package/src/components/BLayout/components/MultiSider/index.tsx +172 -0
  60. package/src/components/BLayout/components/Sider/index.less +64 -0
  61. package/src/components/BLayout/components/Sider/index.module.less +17 -0
  62. package/src/components/BLayout/components/Sider/index.tsx +34 -0
  63. package/src/components/BLayout/index.tsx +78 -0
  64. package/src/components/BLayoutLogin/index.module.less +65 -0
  65. package/src/components/BLayoutLogin/index.tsx +68 -0
  66. package/src/components/BLayoutLogin/login.jpg +0 -0
  67. package/src/components/BLogin/component/Clause/index.module.less +25 -0
  68. package/src/components/BLogin/component/Clause/index.tsx +58 -0
  69. package/src/components/BLogin/component/ForgotBtn/index.module.less +9 -0
  70. package/src/components/BLogin/component/ForgotBtn/index.tsx +18 -0
  71. package/src/components/BLogin/component/Password/index.tsx +39 -0
  72. package/src/components/BLogin/component/SubmitBtn/index.tsx +30 -0
  73. package/src/components/BLogin/component/TenanSpace/index.tsx +28 -0
  74. package/src/components/BLogin/component/Title/index.module.less +6 -0
  75. package/src/components/BLogin/component/Title/index.tsx +12 -0
  76. package/src/components/BLogin/component/UserName/index.tsx +48 -0
  77. package/src/components/BLogin/component/VerifyCode/index.module.less +11 -0
  78. package/src/components/BLogin/component/VerifyCode/index.tsx +165 -0
  79. package/src/components/BLogin/index.module.less +31 -0
  80. package/src/components/BLogin/index.tsx +210 -0
  81. package/src/components/BRegister/components/TenantName/index.tsx +26 -0
  82. package/src/components/BRegister/index.module.less +5 -0
  83. package/src/components/BRegister/index.tsx +71 -0
  84. package/src/components/Back/index.tsx +25 -0
  85. package/src/components/IconFont/font.js +66 -0
  86. package/src/components/IconFont/index.tsx +18 -0
  87. package/src/components/MicroComponent/Header/index.module.less +7 -0
  88. package/src/components/MicroComponent/Header/index.tsx +220 -0
  89. package/src/components/PForgot/index.tsx +10 -0
  90. package/src/components/PLogin/index.tsx +12 -0
  91. package/src/components/PRegister/index.tsx +10 -0
  92. package/src/components/PSetting/index.module.less +53 -0
  93. package/src/components/PSetting/index.tsx +420 -0
  94. package/src/constant/chargeStatus.ts +6 -0
  95. package/src/constant/imgs.ts +6 -0
  96. package/src/constant/index.ts +293 -0
  97. package/src/dark-variable.less +1449 -0
  98. package/src/global.d.ts +54 -0
  99. package/src/hooks/index.ts +133 -0
  100. package/src/index.css +1493 -0
  101. package/src/index.tsx +105 -0
  102. package/src/lang/en.json +266 -0
  103. package/src/lang/index.ts +44 -0
  104. package/src/lang/utils.ts +285 -0
  105. package/src/lang/zh.json +270 -0
  106. package/src/micro-script/theme/index.ts +29 -0
  107. package/src/micro-script/theme/theme-css/static.js +73 -0
  108. package/src/micro-script/theme/theme-css/subscriber.ts +201 -0
  109. package/src/micro-script/theme/util/index.ts +58 -0
  110. package/src/mqtt/index.ts +121 -0
  111. package/src/pages/403.tsx +18 -0
  112. package/src/pages/404.tsx +17 -0
  113. package/src/pages/expiration.tsx +23 -0
  114. package/src/pages/forgot.tsx +9 -0
  115. package/src/pages/home/index.tsx +172 -0
  116. package/src/pages/home/setting/index.tsx +7 -0
  117. package/src/pages/index.ts +50 -0
  118. package/src/pages/login.tsx +46 -0
  119. package/src/pages/register.tsx +9 -0
  120. package/src/pages/relogin/index.module.less +0 -0
  121. package/src/pages/relogin/index.tsx +54 -0
  122. package/src/plugins/index.ts +11 -0
  123. package/src/public-path.js +8 -0
  124. package/src/qiankun/globalState.ts +6 -0
  125. package/src/qiankun/index.ts +174 -0
  126. package/src/qiankun/utils/index.ts +69 -0
  127. package/src/qiankun/xhook/index.ts +193 -0
  128. package/src/reportWebVitals.ts +15 -0
  129. package/src/sentry/index.ts +33 -0
  130. package/src/sky/index.ts +57 -0
  131. package/src/theme/custom-dark.less +64 -0
  132. package/src/theme/custom-light.less +48 -0
  133. package/src/theme/index.less +327 -0
  134. package/src/theme/variable.less +13 -0
  135. package/src/utils/checkPass.ts +21 -0
  136. package/src/utils/common.ts +195 -0
  137. package/src/utils/eventBus.ts +112 -0
  138. package/src/utils/gt.js +293 -0
  139. package/src/utils/index.ts +89 -0
  140. package/src/utils/theme/base.ts +110 -0
  141. package/src/utils/theme/changeCssVariable.ts +157 -0
  142. package/src/utils/theme/changeMenuCssVariable.ts +176 -0
  143. package/src/utils/theme/index.ts +85 -0
  144. package/src/utils/theme/store.ts +37 -0
  145. package/tsconfig.json +28 -0
  146. package/typings.d.ts +10 -0
  147. package/webpack.config.js +103 -0
@@ -0,0 +1,270 @@
1
+ {
2
+ "translation": {
3
+ "login": {
4
+ "title": "SaaS开发框架Demo",
5
+ "tabs": {
6
+ "tele": "手机号",
7
+ "email": "邮箱"
8
+ },
9
+ "form": {
10
+ "username": {
11
+ "label": "账号",
12
+ "validate": {
13
+ "require": "请输入账号",
14
+ "pattern": "请输入正确的手机号码或邮箱账号",
15
+ "emailPattern": "请输入正确的邮箱",
16
+ "phonePattern": "请输入有效的电话号码"
17
+ },
18
+ "placeholder": "请输入手机号/邮箱"
19
+ },
20
+ "password": {
21
+ "label": "密码",
22
+ "validate": {
23
+ "require": "请输入密码",
24
+ "pattern": "密码长度 8-20 位,至少包含以下三种字符类型(数字、大写字母、小写字母、英文符号)"
25
+ },
26
+ "placeholder": "请输入密码"
27
+ },
28
+ "newPassword": {
29
+ "label": "新密码"
30
+ },
31
+ "phone": {
32
+ "label": "电话号码",
33
+ "phonePattern": "请输入有效的电话号码"
34
+ },
35
+ "code": {
36
+ "require": "请输入验证码",
37
+ "requireAccount": "请输入接收验证码地址",
38
+ "placeholder": "验证码",
39
+ "getCode": "获取验证码",
40
+ "len": "请输入6位数字验证码",
41
+ "countdown": "等待 "
42
+ },
43
+ "tenantId": {
44
+ "label": "租户ID/企业别名",
45
+ "placeholder": "请输入租户ID/企业别名",
46
+ "require": "请输入租户ID/企业别名",
47
+ "pattern": "租户ID/企业别名长度4-16位,必须以小写字母开头(支持小写字母、数字、连字符)"
48
+ }
49
+ },
50
+ "signIn": "登录",
51
+ "forgot": "忘记密码?",
52
+ "back2login": "返回登录",
53
+ "resetPwd": "重置密码",
54
+ "resetPwdSuccess": "密码修改成功,请使用新密码登录",
55
+ "text": "阅读并同意",
56
+ "service": "《服务条款》",
57
+ "legal": "《法律声明》",
58
+ "privacy": "《隐私政策》",
59
+ "admin_account_login": "管理员登录",
60
+ "sub_account_login": "子账号登录",
61
+ "lang": "简体中文",
62
+ "thirdLoginError": "三方登录失败"
63
+ },
64
+ "menu": {
65
+ "title": {
66
+ "default": "SaaS开发框架Demo",
67
+ "assets": "资产管理",
68
+ "devices": "设备管理",
69
+ "setting": "账号设置",
70
+ "permission": "角色权限",
71
+ "account": "用户管理"
72
+ },
73
+ "edition": {
74
+ "preview": "预览",
75
+ "latest": "最新",
76
+ "stable": "稳定",
77
+ "trial": "体验"
78
+ },
79
+ "logout": "退出登录"
80
+ },
81
+ "notice": {
82
+ "title": "消息详情",
83
+ "typeSelect": {
84
+ "placeholder": "消息类型",
85
+ "all": "全部",
86
+ "message": "消息通知",
87
+ "alert": "告警通知"
88
+ },
89
+ "originSelect": {
90
+ "placeholder": "消息来源",
91
+ "all": "全部",
92
+ "center": "消息中心(Web)",
93
+ "app": "App Push",
94
+ "short": "短信",
95
+ "email": "邮件",
96
+ "telephone": "电话"
97
+ },
98
+ "StatusSelect": {
99
+ "placeholder": "消息状态",
100
+ "all": "全部",
101
+ "readed": "已读",
102
+ "unread": "未读"
103
+ },
104
+ "buttons": {
105
+ "read": "全部标为已读",
106
+ "unread": "全部标为未读"
107
+ },
108
+ "badge": {
109
+ "title": "消息通知",
110
+ "type": "通知类型",
111
+ "message": "查看全部消息"
112
+ },
113
+ "tools": {
114
+ "button": {
115
+ "read": "标为已读",
116
+ "unread": "标为未读",
117
+ "delete": "删除",
118
+ "allRead": "全部标为已读"
119
+ },
120
+ "checkbox": {
121
+ "onlyViewUnread": "只看未读"
122
+ },
123
+ "select": {
124
+ "all": "全部类型",
125
+ "system": "系统通知",
126
+ "device": "设备消息",
127
+ "work": "业务信息"
128
+ },
129
+ "popconfirm": {
130
+ "title": "确定要删除选中的消息吗?",
131
+ "content": "删除之后不可恢复",
132
+ "cancel": "取消",
133
+ "ok": "确定"
134
+ },
135
+ "selectedAllContent": "已选择所有{{num}}条消息",
136
+ "itemsNums": "已选择本页{{num}}条消息",
137
+ "totalNums": "选择所有{{num}}条消息",
138
+ "cancelSelect": "取消选择",
139
+ "pread": "批量标为已读",
140
+ "punread": "批量标为未读",
141
+ "pdelete": "批量删除"
142
+ },
143
+ "table": {
144
+ "column": {
145
+ "content": "消息内容",
146
+ "status": "消息状态",
147
+ "type": "消息类型",
148
+ "source": "消息来源",
149
+ "time": "通知时间"
150
+ },
151
+ "render": {
152
+ "status": {
153
+ "read": "已读",
154
+ "unread": "未读"
155
+ }
156
+ },
157
+ "hover": {
158
+ "read": "标为已读",
159
+ "unread": "标为未读",
160
+ "del": "删除"
161
+ },
162
+ "delTip": "确认要删除消息吗?"
163
+ }
164
+ },
165
+ "setting": {
166
+ "title": "设置",
167
+ "account": "用户账号",
168
+ "phone": "手机号",
169
+ "email": "邮箱",
170
+ "modify": "修改",
171
+ "bindPhone": "绑定手机号",
172
+ "bindEmail": "绑定邮箱",
173
+ "modifyPhone": "修改手机号",
174
+ "modifyEmail": "修改邮箱",
175
+ "bind": "绑定",
176
+ "unBind": "未绑定",
177
+ "username": "用户名",
178
+ "role": "角色",
179
+ "password": "密码",
180
+ "modifyPwd": "修改密码",
181
+ "language": "语言",
182
+ "phoneLable": "请输入手机号",
183
+ "emailLable": "请输入邮箱",
184
+ "accountLable": "用户账号(登录账号)",
185
+ "name": "名称",
186
+ "form": {
187
+ "oldPassword": {
188
+ "label": "旧密码",
189
+ "validate": {
190
+ "require": "请输入旧密码",
191
+ "pattern": "密码长度 8-20 位,至少包含以下三种字符类型(数字、大写字母、小写字母、英文符号)"
192
+ }
193
+ },
194
+ "newPassword": {
195
+ "label": "新密码",
196
+ "validate": {
197
+ "require": "请输入新密码",
198
+ "pattern": "密码长度 8-20 位,至少包含以下三种字符类型(数字、大写字母、小写字母、英文符号)"
199
+ }
200
+ },
201
+ "confirm": {
202
+ "label": "确认新密码",
203
+ "validate": {
204
+ "require": "请再次输入新密码",
205
+ "pattern": "密码长度 8-20 位,至少包含以下三种字符类型(数字、大写字母、小写字母、英文符号)",
206
+ "unanimous": "两次密码输入不一致"
207
+ }
208
+ }
209
+ },
210
+ "modifySuccess": "修改成功"
211
+ },
212
+ "httpCodeText": {
213
+ "400": "请求错误",
214
+ "401": "未授权,请重新登录",
215
+ "403": "拒绝访问",
216
+ "404": "请求出错",
217
+ "408": "请求超时",
218
+ "500": "服务器错误",
219
+ "501": "服务未实现",
220
+ "502": "网络错误",
221
+ "503": "服务不可用",
222
+ "504": "网络超时,请重试尝试",
223
+ "505": "HTTP版本不受支持",
224
+ "default": "服务异常({{status}})",
225
+ "timeout": "请求超时",
226
+ "abort": "连接失败",
227
+ "callBack": "网络异常"
228
+ },
229
+ "appHint1": "扫描下方二维码,下载智慧行业App",
230
+ "appHint2": "探索更多移动端功能",
231
+ "backLoginPage": "返回登录页",
232
+ "backHome": "返回首页",
233
+ "pageError": "抱歉,您暂无权访问",
234
+ "page404": "抱歉,你访问的站点不存在",
235
+ "page500": "系统错误,请稍后重试",
236
+ "emptyPage": "暂无权限,请联系管理员添加权限",
237
+ "expirationPage": "该SaaS体验服务已到期,请联系开发人员进行付费",
238
+ "trial": "体验版",
239
+ "admin": "超级管理员",
240
+ "forgot": {
241
+ "title": "找回密码",
242
+ "resetPwd": "重置密码",
243
+ "tenantRole": "租户子账号",
244
+ "managerRole": "租户管理员账号",
245
+ "noAccount": "还没有账号?",
246
+ "toRegister": "租户注册"
247
+ },
248
+ "register": {
249
+ "form": {
250
+ "enterprise": {
251
+ "label": "企业/组织名称",
252
+ "validate": {
253
+ "require": "请输入企业/组织名称"
254
+ },
255
+ "placeholder": "请输入企业/组织名称"
256
+ },
257
+ "username": {
258
+ "label": "租户管理员账号"
259
+ }
260
+ },
261
+ "register": "注册租户",
262
+ "registerSuccess": "注册成功"
263
+ },
264
+ "relogin": {
265
+ "tip": "账号已在其他设备(浏览器)登录或已过期",
266
+ "btn": "重新登录",
267
+ "pwd": "如非本人操作,建议前往账号设置修改密码"
268
+ }
269
+ }
270
+ }
@@ -0,0 +1,29 @@
1
+ import {
2
+ CustomizeVariableWithDarkLightChange,
3
+ DarkLightChange,
4
+ CustomizeVariableWithSingleTheme,
5
+ CustomVariable,
6
+ Fallback,
7
+ SingleTheme,
8
+ } from './theme-css/subscriber';
9
+
10
+ import {
11
+ isSupportCssVariable,
12
+ isSupportLightDarkSwitch,
13
+ isSpecificTheme,
14
+ } from '@/utils/theme/base';
15
+
16
+ let microThemeControl = new Fallback();
17
+ if (isSupportLightDarkSwitch() && isSupportCssVariable()) {
18
+ microThemeControl = new CustomizeVariableWithDarkLightChange();
19
+ } else if (isSpecificTheme() && isSupportCssVariable()) {
20
+ microThemeControl = new CustomizeVariableWithSingleTheme();
21
+ } else if (isSupportLightDarkSwitch()) {
22
+ microThemeControl = new DarkLightChange();
23
+ } else if (isSpecificTheme()) {
24
+ microThemeControl = new SingleTheme();
25
+ } else if (isSupportCssVariable()) {
26
+ microThemeControl = new CustomVariable();
27
+ }
28
+
29
+ export { microThemeControl };
@@ -0,0 +1,73 @@
1
+ const themeScript = `
2
+ (function () {
3
+ const oemAppId = OEM_APP_ID_PLACEHOLDER;
4
+
5
+ let base = OEM_APP_BASE_PLACEHOLDER;
6
+
7
+ console.log('base: ' + base);
8
+
9
+ if (!base.includes('http')) {
10
+ base = new URL(base, location.origin).href;
11
+ }
12
+
13
+ const initalTheme = INITAL_THEME_PLACEHOLDER;
14
+ const otherTheme = initalTheme === 'dark' ? 'light' : 'dark';
15
+
16
+ const darkCss = getDarkCssNode();
17
+ const lightCss = getLightCssNode();
18
+ const darkLink = darkCss ? darkCss.getAttribute('href') : '';
19
+ const lightLink = lightCss ? lightCss.getAttribute('href') : '';
20
+
21
+ function getOriginPath(theme) {
22
+ return theme == 'dark' ? darkLink : lightLink;
23
+ }
24
+
25
+ function getDarkCssNode() {
26
+ return document.querySelector('link[id="micro-dark-theme-css"]');
27
+ }
28
+ function getLightCssNode() {
29
+ return document.querySelector('link[id="micro-light-theme-css"]');
30
+ }
31
+
32
+ function createLink(path, theme) {
33
+ const linkDom = document.createElement('link');
34
+ linkDom.href = path;
35
+ linkDom.rel = 'stylesheet';
36
+ linkDom.setAttribute('reference-id', 'micro-light-theme-css');
37
+ linkDom.setAttribute('id', 'micro-unique-light-dark-id-' + theme);
38
+ document.head.insertBefore(linkDom, getLightCssNode());
39
+ }
40
+
41
+ function getAbosultePath(theme) {
42
+ const originPath = getOriginPath(theme);
43
+ const abosultePath = new URL(originPath, base).href;
44
+ return abosultePath;
45
+ }
46
+
47
+ function queryStyle(href) {
48
+ return document.querySelector(\`style[data-qiankun-href=\"\$\{href\}\"\]\`);
49
+ }
50
+
51
+ function subscriber(theme) {
52
+ if (!darkLink || !lightLink) {
53
+ return;
54
+ }
55
+ if (theme === initalTheme) {
56
+ //判断是否存在非初始主题的动态style,有 需要删除
57
+ const abosultePath = getAbosultePath(otherTheme);
58
+ const style = queryStyle(abosultePath);
59
+ style && document.head.removeChild(style);
60
+ } else {
61
+ //判断是否存在非初始主题的动态style,有 不动
62
+ const abosultePath = getAbosultePath(theme);
63
+ const style = queryStyle(abosultePath);
64
+ !style && createLink(abosultePath, theme);
65
+ }
66
+ }
67
+
68
+ darkLightChangeSubscriber.add(oemAppId, subscriber);
69
+ })();
70
+
71
+ `;
72
+
73
+ export default themeScript;
@@ -0,0 +1,201 @@
1
+ import { getMicroAppId } from '@/utils';
2
+ import {
3
+ getCurrentMicroResourceRoot,
4
+ HREF_REGEX,
5
+ DEFAULT_LINK_REGEX,
6
+ LIGHT_LINK_REGEX,
7
+ DARK_LINK_REGEX,
8
+ CSS_VARIABLE_STYLE_TAG_REGEX,
9
+ getMicroIdFromHtml,
10
+ } from '../util/index';
11
+ import type { Theme } from '@/utils/theme/base';
12
+ import { LIGHT, getRenderTheme } from '@/utils/theme/base';
13
+ import themeScript from './static.js';
14
+
15
+ interface Subscriber {
16
+ (theme: Theme): void;
17
+ }
18
+
19
+ //主要为了剥离css变量
20
+ function removeCssVariable(tpl: string) {
21
+ //移除微应用内css变量,方便主应用控制全局的css变量
22
+ return tpl.replace(CSS_VARIABLE_STYLE_TAG_REGEX, '');
23
+ }
24
+
25
+ //获取匹配亮色/暗色的正则
26
+ function getLinkRegExp(theme: Theme) {
27
+ return theme === LIGHT ? LIGHT_LINK_REGEX : DARK_LINK_REGEX;
28
+ }
29
+
30
+ //获取亮色/暗色下的style的href
31
+ function getMicroAppSpecificThemeLinkHref(tpl: string, theme: Theme) {
32
+ const linkRegExp = getLinkRegExp(theme);
33
+ const [link] = linkRegExp.exec(tpl) || [];
34
+ if (!link) {
35
+ return null;
36
+ }
37
+ const [, href] = HREF_REGEX.exec(link);
38
+ return href;
39
+ }
40
+
41
+ //获取初始亮/暗下的模板
42
+ function getInitalThemeTpl(tpl: string, href: string) {
43
+ return (
44
+ tpl
45
+ //默认移除有效的light样式
46
+ .replace(DEFAULT_LINK_REGEX, '')
47
+ //往light link链接之前插入当前具体明暗的链接
48
+ .replace(LIGHT_LINK_REGEX, (match) => {
49
+ return `<link rel="stylesheet" href="${href}">${match}`;
50
+ })
51
+ );
52
+ }
53
+
54
+ //创建一个color-scheme的控制器
55
+ function createMicroColorSchemeControl() {
56
+ return {
57
+ microAppWithThemeMap: new Map<string, boolean>(),
58
+ add(id: string, value: boolean) {
59
+ this.microAppWithThemeMap.set(id, value);
60
+ },
61
+ setColorScheme(id: string) {
62
+ const container = document.querySelector('#container') as HTMLElement;
63
+ if (!this.microAppWithThemeMap.get(id)) {
64
+ container.style['colorScheme'] = LIGHT;
65
+ } else {
66
+ container.style['colorScheme'] = 'inherit';
67
+ }
68
+ },
69
+ };
70
+ }
71
+
72
+ class Fallback {
73
+ changeTheme(value: unknown) {}
74
+ cannotExclude(url: string) {
75
+ return false;
76
+ }
77
+ beforeMount(app) {}
78
+ getTemplate(tpl: string) {
79
+ return tpl;
80
+ }
81
+ }
82
+
83
+ //单一亮/暗
84
+ class SingleTheme extends Fallback {
85
+ microColorSchemeControl: ReturnType<typeof createMicroColorSchemeControl>;
86
+ theme: Theme;
87
+ constructor() {
88
+ super();
89
+ this.theme = getRenderTheme();
90
+ this.microColorSchemeControl = createMicroColorSchemeControl();
91
+ }
92
+ beforeMount(app: any): void {
93
+ this.microColorSchemeControl.setColorScheme(app.name);
94
+ }
95
+ getTemplate(tpl: string): string {
96
+ const id = getMicroAppId();
97
+ const styleHref = getMicroAppSpecificThemeLinkHref(tpl, this.theme);
98
+ if (!styleHref) {
99
+ this.microColorSchemeControl.add(id, false);
100
+ return tpl;
101
+ }
102
+ this.microColorSchemeControl.add(id, true);
103
+ const outputTpl = getInitalThemeTpl(tpl, styleHref);
104
+ return outputTpl;
105
+ }
106
+ }
107
+
108
+ //支持亮暗切换
109
+ class DarkLightChange extends SingleTheme {
110
+ private subscribers = new Map();
111
+ constructor() {
112
+ super();
113
+ window.darkLightChangeSubscriber = this;
114
+ }
115
+ changeTheme(theme: Theme) {
116
+ this.theme = theme;
117
+ this.dispatch(getMicroAppId(), theme);
118
+ }
119
+ beforeMount(app) {
120
+ this.dispatch(app.name, this.theme);
121
+ super.beforeMount(app);
122
+ }
123
+ cannotExclude(url: string) {
124
+ return /(light|dark).[\s\S]+.css$/.test(url);
125
+ }
126
+ injectVarible(str: string, varibles: [string, string][]) {
127
+ let make = str;
128
+ for (const [key, value] of varibles) {
129
+ make = make.replace(key, JSON.stringify(value));
130
+ }
131
+ return make;
132
+ }
133
+ getTemplate(tpl: string) {
134
+ const id = getMicroIdFromHtml(tpl);
135
+ const styleHref = getMicroAppSpecificThemeLinkHref(tpl, this.theme);
136
+ if (!styleHref) {
137
+ this.microColorSchemeControl.add(id, false);
138
+ return tpl;
139
+ }
140
+ this.microColorSchemeControl.add(id, true);
141
+ const resourceRoot = getCurrentMicroResourceRoot(id);
142
+ const outputTpl = getInitalThemeTpl(tpl, styleHref).replace(
143
+ '</head>',
144
+ `
145
+ <script>
146
+ ${this.injectVarible(themeScript, [
147
+ ['OEM_APP_ID_PLACEHOLDER', id],
148
+ ['OEM_APP_BASE_PLACEHOLDER', resourceRoot],
149
+ ['INITAL_THEME_PLACEHOLDER', this.theme],
150
+ ['INITAL_HREF_PLACEHOLDER', styleHref],
151
+ ])}
152
+ </script>
153
+ </head>
154
+ `
155
+ );
156
+ return outputTpl;
157
+ }
158
+ add(id: string, subscriber: Subscriber) {
159
+ this.subscribers.set(id, subscriber);
160
+ }
161
+ clear() {
162
+ this.subscribers = new Map();
163
+ }
164
+ dispatch(id: string, theme: string) {
165
+ this.subscribers.get(id)?.(theme);
166
+ }
167
+ }
168
+
169
+ //css变量
170
+ class CustomVariable extends Fallback {
171
+ removeCssVariable = removeCssVariable;
172
+ getTemplate(tpl: string): string {
173
+ return this.removeCssVariable(tpl);
174
+ }
175
+ }
176
+
177
+ //css变量 + 单一亮暗
178
+ class CustomizeVariableWithSingleTheme extends SingleTheme {
179
+ removeCssVariable = removeCssVariable;
180
+ getTemplate(tpl: string): string {
181
+ const initalThemeTpl = super.getTemplate(tpl);
182
+ return this.removeCssVariable(initalThemeTpl);
183
+ }
184
+ }
185
+
186
+ //css变量 + 明暗切换
187
+ class CustomizeVariableWithDarkLightChange extends DarkLightChange {
188
+ removeCssVariable = removeCssVariable;
189
+ getTemplate(tpl: string): string {
190
+ return this.removeCssVariable(super.getTemplate(tpl));
191
+ }
192
+ }
193
+
194
+ export {
195
+ SingleTheme,
196
+ DarkLightChange,
197
+ CustomVariable,
198
+ CustomizeVariableWithSingleTheme,
199
+ CustomizeVariableWithDarkLightChange,
200
+ Fallback,
201
+ };
@@ -0,0 +1,58 @@
1
+ import { micApps } from '@/utils';
2
+
3
+ const HREF_REGEX = /href="([\s\S]+?)"/;
4
+ const DEFAULT_LINK_REGEX = /<link[^>]+?id="micro-default-theme-css"[^>]*?>/;
5
+ const LIGHT_LINK_REGEX = /<link[^>]+?id="micro-light-theme-css"[^>]*?>/;
6
+ const DARK_LINK_REGEX = /<link[^>]+?id="micro-dark-theme-css"[^>]*?>/;
7
+ const CSS_VARIABLE_STYLE_TAG_REGEX =
8
+ /<style[^>]+?id="micro-css-variable">[\s\S]*?<\/style>/;
9
+ const MICRO_APP_ID_REGEX = /<meta[\s\S]+?content="([\s\S]+?)"\/>/;
10
+
11
+ function getCurrentMicroResourceRoot(id: string) {
12
+ let currentApp = null;
13
+ for (const app of micApps()) {
14
+ if (app.oem_micro_app_id === id) {
15
+ currentApp = app;
16
+ break;
17
+ }
18
+ }
19
+ if (!currentApp) return;
20
+ const { resource } = currentApp;
21
+ const resourceRoot = resource.replace(/index.html$/, '');
22
+ return resourceRoot;
23
+ }
24
+
25
+ function processHtmlInTheme(url: string, apps: any[]) {
26
+ return {
27
+ async text() {
28
+ const res = await fetch(url);
29
+ if (res.ok) {
30
+ const microApp = apps.find((item) => item.entry === url);
31
+ const text = await res.text();
32
+ if (microApp) {
33
+ return text.replace(
34
+ '<head>',
35
+ `<head><meta name="micro-app-id" content="${microApp.name}"/>`
36
+ );
37
+ }
38
+ return text;
39
+ }
40
+ return '';
41
+ },
42
+ };
43
+ }
44
+
45
+ function getMicroIdFromHtml(tpl) {
46
+ return MICRO_APP_ID_REGEX.exec(tpl)?.[1];
47
+ }
48
+
49
+ export {
50
+ HREF_REGEX,
51
+ DEFAULT_LINK_REGEX,
52
+ LIGHT_LINK_REGEX,
53
+ DARK_LINK_REGEX,
54
+ CSS_VARIABLE_STYLE_TAG_REGEX,
55
+ getCurrentMicroResourceRoot,
56
+ processHtmlInTheme,
57
+ getMicroIdFromHtml,
58
+ };