@jiangood/springboot-admin-starter 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/dist/config.js +32 -0
- package/config/dist/index.js +0 -1
- package/config/dist/plugins/form-plugin.js +2 -2
- package/package.json +12 -10
- package/src/forms/demoForm.jsx +5 -5
- package/src/framework/components/DownloadFileButton.jsx +2 -2
- package/src/framework/components/Ellipsis.jsx +2 -2
- package/src/framework/components/LinkButton.d.ts +4 -4
- package/src/framework/components/LinkButton.jsx +6 -9
- package/src/framework/components/Page/index.jsx +2 -2
- package/src/framework/components/PageLoading.tsx +27 -0
- package/src/framework/components/ProTable/components/ToolBar/index.jsx +6 -7
- package/src/framework/components/ProTable/index.d.ts +5 -1
- package/src/framework/components/ProTable/index.jsx +4 -6
- package/src/framework/components/ProTable/index.less +0 -1
- package/src/framework/components/ValueType/registry.jsx +9 -20
- package/src/framework/components/{index.js → index.ts} +2 -10
- package/src/framework/components/system/ButtonList.jsx +35 -0
- package/src/framework/components/system/HasPerm.tsx +14 -0
- package/src/framework/components/system/index.tsx +29 -0
- package/src/framework/components/view/ViewBooleanEnableDisable.tsx +20 -0
- package/src/framework/components/view/ViewEllipsis.jsx +2 -2
- package/src/framework/components/view/ViewFile.jsx +1 -2
- package/src/framework/components/view/ViewImage.jsx +2 -3
- package/src/framework/components/view/ViewText.tsx +16 -0
- package/src/framework/components/view/{index.js → index.ts} +0 -2
- package/src/framework/field-components/FieldBoolean.d.ts +13 -0
- package/src/framework/field-components/FieldBoolean.jsx +76 -0
- package/src/framework/field-components/FieldDate.d.ts +25 -0
- package/src/framework/field-components/FieldDate.jsx +109 -0
- package/src/framework/field-components/FieldDateRange.d.ts +6 -0
- package/src/framework/field-components/FieldDateRange.jsx +101 -0
- package/src/framework/field-components/FieldDictSelect.d.ts +13 -0
- package/src/framework/field-components/FieldDictSelect.jsx +16 -0
- package/src/framework/field-components/FieldEditor.d.ts +10 -0
- package/src/framework/field-components/FieldEditor.jsx +58 -0
- package/src/framework/field-components/FieldPercent.d.ts +12 -0
- package/src/framework/field-components/FieldPercent.jsx +27 -0
- package/src/framework/field-components/FieldRemoteSelect.d.ts +13 -0
- package/src/framework/field-components/FieldRemoteSelect.jsx +87 -0
- package/src/framework/field-components/FieldRemoteSelectMultiple.d.ts +13 -0
- package/src/framework/field-components/FieldRemoteSelectMultiple.jsx +86 -0
- package/src/framework/field-components/FieldRemoteSelectMultipleInline.d.ts +20 -0
- package/src/framework/field-components/FieldRemoteSelectMultipleInline.jsx +86 -0
- package/src/framework/field-components/FieldRemoteTree.d.ts +21 -0
- package/src/framework/field-components/FieldRemoteTree.jsx +45 -0
- package/src/framework/field-components/FieldRemoteTreeCascader.d.ts +23 -0
- package/src/framework/field-components/FieldRemoteTreeCascader.jsx +61 -0
- package/src/framework/field-components/FieldRemoteTreeSelect.d.ts +17 -0
- package/src/framework/field-components/FieldRemoteTreeSelect.jsx +67 -0
- package/src/framework/field-components/FieldRemoteTreeSelectMultiple.d.ts +17 -0
- package/src/framework/field-components/FieldRemoteTreeSelectMultiple.jsx +68 -0
- package/src/framework/field-components/FieldSysOrgTree.d.ts +12 -0
- package/src/framework/field-components/FieldSysOrgTree.jsx +23 -0
- package/src/framework/field-components/FieldSysOrgTreeSelect.d.ts +12 -0
- package/src/framework/field-components/FieldSysOrgTreeSelect.jsx +23 -0
- package/src/framework/field-components/FieldTable.d.ts +17 -0
- package/src/framework/field-components/FieldTable.jsx +108 -0
- package/src/framework/{components/field/select/FieldTableSelect/index.d.ts → field-components/FieldTableSelect.d.ts} +4 -14
- package/src/framework/field-components/FieldTableSelect.jsx +59 -0
- package/src/framework/{components/field/upload → field-components}/FieldUploadFile.d.ts +0 -1
- package/src/framework/{components/field/upload → field-components}/FieldUploadFile.jsx +5 -9
- package/src/framework/field-components/index.ts +20 -0
- package/src/framework/{components/OrgTree.jsx → field-components/system/OrgTree.tsx} +8 -7
- package/src/framework/{components/RoleTree.jsx → field-components/system/RoleTree.tsx} +3 -3
- package/src/framework/field-components/system/index.ts +2 -0
- package/src/framework/index.ts +5 -0
- package/src/framework/pages/LoginPage.d.ts +11 -0
- package/src/framework/pages/LoginPage.jsx +136 -0
- package/src/{pages/login.less → framework/pages/LoginPage.less} +1 -1
- package/src/framework/pages/index.ts +1 -0
- package/src/framework/utils/ArrUtils.ts +229 -0
- package/src/framework/utils/ColorsUtils.ts +378 -0
- package/src/framework/utils/{date.js → DateUtils.ts} +69 -69
- package/src/framework/utils/DeviceUtils.ts +46 -0
- package/src/framework/utils/DomUtils.ts +50 -0
- package/src/framework/utils/EventBusUtils.ts +143 -0
- package/src/framework/utils/MessageUtils.tsx +182 -0
- package/src/framework/utils/ObjectUtils.ts +113 -0
- package/src/framework/utils/StorageUtils.ts +67 -0
- package/src/framework/utils/StringUtils.ts +410 -0
- package/src/framework/utils/TreeUtils.ts +248 -0
- package/src/framework/utils/UrlUtils.ts +152 -0
- package/src/framework/utils/UuidUtils.ts +88 -0
- package/src/framework/utils/ValidateUtils.ts +28 -0
- package/src/framework/utils/index.ts +16 -0
- package/src/framework/utils/system/DictUtils.ts +97 -0
- package/src/framework/utils/system/FormRegistryUtils.ts +77 -0
- package/src/framework/utils/system/HttpUtils.ts +246 -0
- package/src/framework/utils/system/PageUtils.ts +153 -0
- package/src/framework/utils/system/PermUtils.ts +79 -0
- package/src/framework/utils/system/SysUtils.ts +97 -0
- package/src/framework/utils/system/ThemeUtils.ts +27 -0
- package/src/framework/utils/system/index.ts +7 -0
- package/src/framework/view-components/ViewBoolean.jsx +4 -0
- package/src/framework/view-components/index.js +3 -0
- package/src/layouts/PageRender.jsx +2 -2
- package/src/layouts/admin/HeaderRight.jsx +9 -9
- package/src/layouts/admin/TabPageRender.jsx +2 -2
- package/src/layouts/admin/index.jsx +27 -40
- package/src/layouts/admin/index.less +2 -1
- package/src/layouts/index.jsx +30 -38
- package/src/layouts/index.less +0 -21
- package/src/loading.jsx +2 -2
- package/src/{components → pages/flowable}/InstanceInfo.jsx +5 -4
- package/src/pages/flowable/design/customTranslate/customTranslate.js +16 -0
- package/src/pages/flowable/design/customTranslate/translations-properties-panel.js +10 -0
- package/src/pages/flowable/design/customTranslate/translations.js +144 -0
- package/src/pages/flowable/design/descriptors/flowable.json +1109 -0
- package/src/pages/flowable/design/index.jsx +61 -234
- package/src/pages/flowable/design/provider/FlowablePropertiesProvider.js +75 -0
- package/src/pages/flowable/design/provider/index.js +6 -0
- package/src/pages/flowable/design/provider/properties/ConditionDesign.jsx +175 -0
- package/src/pages/flowable/design/provider/properties/ConditionProps.jsx +76 -0
- package/src/pages/flowable/design/provider/properties/DelegateExpressionProps.js +54 -0
- package/src/pages/flowable/design/provider/properties/FormProps.js +55 -0
- package/src/pages/flowable/design/provider/properties/MultiInstanceProps.js +100 -0
- package/src/pages/flowable/design/provider/properties/UserTaskForm.jsx +48 -0
- package/src/pages/flowable/design/provider/properties/utils.jsx +35 -0
- package/src/pages/flowable/index.jsx +28 -69
- package/src/pages/flowable/monitor/definition.jsx +87 -0
- package/src/pages/flowable/monitor/instance/index.jsx +177 -0
- package/src/pages/flowable/monitor/instance/view.jsx +102 -0
- package/src/pages/flowable/monitor/task.jsx +93 -0
- package/src/pages/flowable/task/form.jsx +5 -5
- package/src/pages/flowable/task/index.jsx +5 -5
- package/src/pages/flowable/test/index.jsx +13 -10
- package/src/pages/index.jsx +8 -13
- package/src/pages/login.jsx +4 -129
- package/src/pages/{api/doc.jsx → system/api/ApiDoc.jsx} +56 -47
- package/src/pages/system/api/index.jsx +268 -0
- package/src/pages/system/api/perm.jsx +69 -0
- package/src/pages/system/config/index.jsx +3 -3
- package/src/pages/system/dict/Dict.jsx +2 -3
- package/src/pages/system/dict/DictItem.jsx +5 -5
- package/src/pages/system/file/index.jsx +13 -5
- package/src/pages/{job → system/job}/index.jsx +124 -39
- package/src/pages/system/log/index.jsx +3 -3
- package/src/pages/system/org/index.jsx +11 -12
- package/src/pages/system/role/index.jsx +11 -11
- package/src/pages/system/role/perm.jsx +8 -8
- package/src/pages/system/sysManual/index.jsx +6 -6
- package/src/pages/system/user/UserPerm.jsx +7 -42
- package/src/pages/system/user/index.jsx +13 -17
- package/src/pages/test.jsx +188 -3
- package/src/pages/ureport/index.jsx +4 -4
- package/src/pages/userCenter/ChangePassword.jsx +3 -4
- package/src/pages/userCenter/index.jsx +2 -2
- package/src/pages/userCenter/manual.jsx +3 -7
- package/src/pages/userCenter/message.jsx +5 -5
- package/config/dist/config.local.js +0 -23
- package/src/components/InstanceStatusInfo.jsx +0 -79
- package/src/components/StreamLog.jsx +0 -27
- package/src/components/flow/BpmnUtils.js +0 -85
- package/src/components/flow/customTranslate/customTranslate.js +0 -19
- package/src/components/flow/customTranslate/translations.js +0 -79
- package/src/components/flow/design/form/ConditionForm.jsx +0 -316
- package/src/components/flow/design/form/ServiceTaskForm.jsx +0 -55
- package/src/components/flow/design/form/TimerEventDefinitionForm.jsx +0 -62
- package/src/components/flow/design/form/UserTaskForm.jsx +0 -211
- package/src/components/flow/design/palette.js +0 -39
- package/src/components/monitor/AllDefinition.jsx +0 -46
- package/src/components/monitor/AllInstance.jsx +0 -76
- package/src/forms/driverForm.jsx +0 -18
- package/src/framework/components/ButtonList.jsx +0 -91
- package/src/framework/components/Echarts/index.d.ts +0 -10
- package/src/framework/components/Echarts/index.jsx +0 -49
- package/src/framework/components/EditTable/index.d.ts +0 -11
- package/src/framework/components/EditTable/index.jsx +0 -85
- package/src/framework/components/FieldRemoteTree.jsx +0 -20
- package/src/framework/components/HasPerm.jsx +0 -18
- package/src/framework/components/ImageView.d.ts +0 -12
- package/src/framework/components/ImageView.jsx +0 -64
- package/src/framework/components/MsgBox.jsx +0 -180
- package/src/framework/components/PageLoading.jsx +0 -31
- package/src/framework/components/Panel/index.d.ts +0 -11
- package/src/framework/components/Panel/index.jsx +0 -24
- package/src/framework/components/Panel/index.less +0 -0
- package/src/framework/components/field/FieldAutoTime/index.tsx +0 -46
- package/src/framework/components/field/FieldBoolean/index.tsx +0 -92
- package/src/framework/components/field/FieldEditTable/index.d.ts +0 -13
- package/src/framework/components/field/FieldEditTable/index.jsx +0 -103
- package/src/framework/components/field/FieldEditTable/index.less +0 -29
- package/src/framework/components/field/FieldEditor.jsx +0 -48
- package/src/framework/components/field/FieldFileBase64/index.d.ts +0 -15
- package/src/framework/components/field/FieldFileBase64/index.jsx +0 -23
- package/src/framework/components/field/FieldImageBase64/index.d.ts +0 -15
- package/src/framework/components/field/FieldImageBase64/index.jsx +0 -22
- package/src/framework/components/field/FieldInput.jsx +0 -13
- package/src/framework/components/field/FieldOrgTree/index.tsx +0 -45
- package/src/framework/components/field/FieldPassword.jsx +0 -11
- package/src/framework/components/field/FieldProps.ts +0 -19
- package/src/framework/components/field/FieldRemoteTreeCascader.jsx +0 -75
- package/src/framework/components/field/FieldRemoteTreeCheckable.jsx +0 -81
- package/src/framework/components/field/FieldRemoteTreeMultipleSelect.jsx +0 -100
- package/src/framework/components/field/FieldRemoteTreeSelect.jsx +0 -82
- package/src/framework/components/field/FieldSelectPosition/index.tsx +0 -85
- package/src/framework/components/field/FieldTree.jsx +0 -45
- package/src/framework/components/field/dict/index.tsx +0 -110
- package/src/framework/components/field/flat-multiple-select/index.d.ts +0 -4
- package/src/framework/components/field/flat-multiple-select/index.jsx +0 -116
- package/src/framework/components/field/flat-multiple-select/index.less +0 -12
- package/src/framework/components/field/flat-select/index.d.ts +0 -4
- package/src/framework/components/field/flat-select/index.jsx +0 -107
- package/src/framework/components/field/flat-select/index.less +0 -12
- package/src/framework/components/field/index.js +0 -33
- package/src/framework/components/field/input-number-percent/index.d.ts +0 -11
- package/src/framework/components/field/input-number-percent/index.jsx +0 -28
- package/src/framework/components/field/select/FieldSelect/index.d.ts +0 -39
- package/src/framework/components/field/select/FieldSelect/index.jsx +0 -156
- package/src/framework/components/field/select/FieldTableSelect/index.jsx +0 -155
- package/src/framework/components/field/select/index.jsx +0 -2
- package/src/framework/components/field/switch-y-n/index.d.ts +0 -11
- package/src/framework/components/field/switch-y-n/index.jsx +0 -31
- package/src/framework/components/field/text/index.tsx +0 -7
- package/src/framework/components/field/time/DatePickerString.tsx +0 -37
- package/src/framework/components/field/time/DateTimePickerString.tsx +0 -42
- package/src/framework/components/field/time/FieldDateRange.d.ts +0 -9
- package/src/framework/components/field/time/FieldDateRange.jsx +0 -49
- package/src/framework/components/field/time/HHmmPickerString.tsx +0 -42
- package/src/framework/components/field/time/MonthPickerString.tsx +0 -45
- package/src/framework/components/field/time/TimePickerTool.ts +0 -14
- package/src/framework/components/field/time/YearPickerString.tsx +0 -41
- package/src/framework/components/field/time/YearQuarterString.tsx +0 -38
- package/src/framework/components/field/time/index.tsx +0 -7
- package/src/framework/components/field/upload/FieldUploadCropImage/index.d.ts +0 -22
- package/src/framework/components/field/upload/FieldUploadCropImage/index.jsx +0 -11
- package/src/framework/components/field/upload/FieldUploadImage.d.ts +0 -7
- package/src/framework/components/field/upload/FieldUploadImage.jsx +0 -16
- package/src/framework/components/field/upload/index.jsx +0 -3
- package/src/framework/components/system.jsx +0 -29
- package/src/framework/components/view/ViewBoolean.jsx +0 -15
- package/src/framework/components/view/ViewBooleanEnableDisable.jsx +0 -16
- package/src/framework/components/view/ViewText.jsx +0 -9
- package/src/framework/index.js +0 -3
- package/src/framework/system/dict.js +0 -88
- package/src/framework/system/formRegistry.js +0 -58
- package/src/framework/system/http.jsx +0 -290
- package/src/framework/system/index.js +0 -13
- package/src/framework/system/page.js +0 -109
- package/src/framework/system/permission.js +0 -44
- package/src/framework/system/sys.js +0 -60
- package/src/framework/system/theme.js +0 -17
- package/src/framework/utils/arr.js +0 -118
- package/src/framework/utils/browser.js +0 -24
- package/src/framework/utils/color.js +0 -269
- package/src/framework/utils/debounce.js +0 -33
- package/src/framework/utils/dom.js +0 -16
- package/src/framework/utils/eventBus.js +0 -70
- package/src/framework/utils/html.js +0 -13
- package/src/framework/utils/index.js +0 -17
- package/src/framework/utils/obj.js +0 -72
- package/src/framework/utils/storage.js +0 -37
- package/src/framework/utils/str.js +0 -297
- package/src/framework/utils/tree.js +0 -175
- package/src/framework/utils/uid.js +0 -76
- package/src/framework/utils/url.js +0 -84
- package/src/framework/utils/validate.js +0 -9
- package/src/pages/api/accessLog/index.jsx +0 -108
- package/src/pages/api/accountResource/index.jsx +0 -149
- package/src/pages/api/index.jsx +0 -163
- package/src/pages/api/resource.jsx +0 -18
- package/src/pages/flowable/instance/view.jsx +0 -13
- package/src/pages/flowable/monitor.jsx +0 -106
- package/src/pages/flowable/test/form.jsx +0 -31
- package/src/pages/job/logList.jsx +0 -100
- package/src/pages/job/status.jsx +0 -84
- /package/src/framework/components/{ButtonList.d.ts → system/ButtonList.d.ts} +0 -0
- /package/src/framework/{components/EditTable/index.less → field-components/FieldTable.less} +0 -0
- /package/src/framework/{components/view → view-components}/ViewPassword.jsx +0 -0
- /package/src/{index.js → index.ts} +0 -0
- /package/src/{components/flow → pages/flowable}/design/contextPad.js +0 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* forked form https://github.com/quasarframework/quasar
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// 正则表达式用于匹配 rgba 格式的字符串
|
|
6
|
+
const reRGBA = /^rgb(a)?\((\d{1,3}),(\d{1,3}),(\d{1,3}),?([01]?\.?\d*?)?\)$/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* RGB 颜色接口
|
|
10
|
+
* r, g, b 的范围是 [0, 255]
|
|
11
|
+
* a 的范围是 [0, 100] (百分比)
|
|
12
|
+
*/
|
|
13
|
+
export interface RGB {
|
|
14
|
+
r: number
|
|
15
|
+
g: number
|
|
16
|
+
b: number
|
|
17
|
+
a?: number // 可选的 alpha (百分比)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* HSV 颜色接口
|
|
22
|
+
* h 的范围是 [0, 360]
|
|
23
|
+
* s, v 的范围是 [0, 100] (百分比)
|
|
24
|
+
* a 的范围是 [0, 100] (百分比)
|
|
25
|
+
*/
|
|
26
|
+
export interface HSV {
|
|
27
|
+
h: number
|
|
28
|
+
s: number
|
|
29
|
+
v: number
|
|
30
|
+
a?: number // 可选的 alpha (百分比)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 颜色工具类,提供颜色相关的转换和操作方法。
|
|
35
|
+
*/
|
|
36
|
+
export class ColorsUtils {
|
|
37
|
+
/**
|
|
38
|
+
* 将 RGB 颜色对象转换为十六进制字符串 (包含可选的 alpha 值).
|
|
39
|
+
* @param color RGB 颜色对象
|
|
40
|
+
* @returns 十六进制颜色字符串, 如 '#RRGGBB' 或 '#RRGGBBAA'
|
|
41
|
+
*/
|
|
42
|
+
static rgbToHex (color: RGB): string {
|
|
43
|
+
let { r, g, b, a } = color
|
|
44
|
+
const alpha = a !== void 0
|
|
45
|
+
|
|
46
|
+
r = Math.round(r)
|
|
47
|
+
g = Math.round(g)
|
|
48
|
+
b = Math.round(b)
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
r > 255
|
|
52
|
+
|| g > 255
|
|
53
|
+
|| b > 255
|
|
54
|
+
|| (alpha && a! > 100)
|
|
55
|
+
) {
|
|
56
|
+
throw new TypeError('Expected 3 numbers below 256 (and optionally one below 100)')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const alphaHex = alpha
|
|
60
|
+
? (Math.round(255 * a! / 100) | 1 << 8).toString(16).slice(1)
|
|
61
|
+
: ''
|
|
62
|
+
|
|
63
|
+
return '#' + ((b | g << 8 | r << 16) | 1 << 24).toString(16).slice(1) + alphaHex
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 将 RGB 颜色对象转换为 rgb() 或 rgba() 字符串.
|
|
68
|
+
* @param color RGB 颜色对象
|
|
69
|
+
* @returns rgb() 或 rgba() 颜色字符串
|
|
70
|
+
*/
|
|
71
|
+
static rgbToString (color: RGB): string {
|
|
72
|
+
const { r, g, b, a } = color
|
|
73
|
+
return `rgb${a !== void 0 ? 'a' : ''}(${r},${g},${b}${a !== void 0 ? ',' + (a / 100) : ''})`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 将十六进制颜色字符串转换为 RGB 颜色对象.
|
|
78
|
+
* 支持 '#RGB', '#RGBA', '#RRGGBB', '#RRGGBBAA' 格式.
|
|
79
|
+
* @param hex 十六进制颜色字符串
|
|
80
|
+
* @returns RGB 颜色对象
|
|
81
|
+
*/
|
|
82
|
+
static hexToRgb (hex: string): RGB {
|
|
83
|
+
if (typeof hex !== 'string') {
|
|
84
|
+
throw new TypeError('Expected a string')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
hex = hex.replace(/^#/, '')
|
|
88
|
+
|
|
89
|
+
if (hex.length === 3) {
|
|
90
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
|
|
91
|
+
} else if (hex.length === 4) {
|
|
92
|
+
// 确保 alpha 也被扩展
|
|
93
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const num = parseInt(hex, 16)
|
|
97
|
+
|
|
98
|
+
return hex.length > 6
|
|
99
|
+
? { r: num >> 24 & 255, g: num >> 16 & 255, b: num >> 8 & 255, a: Math.round((num & 255) / 2.55) }
|
|
100
|
+
: { r: num >> 16, g: num >> 8 & 255, b: num & 255 }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 将 HSV 颜色对象转换为 RGB 颜色对象.
|
|
105
|
+
* @param color HSV 颜色对象
|
|
106
|
+
* @returns RGB 颜色对象
|
|
107
|
+
*/
|
|
108
|
+
static hsvToRgb (color: HSV): RGB {
|
|
109
|
+
let r: number = 0, g: number = 0, b: number = 0
|
|
110
|
+
let { h, s, v, a } = color
|
|
111
|
+
s = s / 100
|
|
112
|
+
v = v / 100
|
|
113
|
+
|
|
114
|
+
h = h / 360
|
|
115
|
+
const
|
|
116
|
+
i = Math.floor(h * 6),
|
|
117
|
+
f = h * 6 - i,
|
|
118
|
+
p = v * (1 - s),
|
|
119
|
+
q = v * (1 - f * s),
|
|
120
|
+
t = v * (1 - (1 - f) * s)
|
|
121
|
+
|
|
122
|
+
switch (i % 6) {
|
|
123
|
+
case 0:
|
|
124
|
+
r = v
|
|
125
|
+
g = t
|
|
126
|
+
b = p
|
|
127
|
+
break
|
|
128
|
+
case 1:
|
|
129
|
+
r = q
|
|
130
|
+
g = v
|
|
131
|
+
b = p
|
|
132
|
+
break
|
|
133
|
+
case 2:
|
|
134
|
+
r = p
|
|
135
|
+
g = v
|
|
136
|
+
b = t
|
|
137
|
+
break
|
|
138
|
+
case 3:
|
|
139
|
+
r = p
|
|
140
|
+
g = q
|
|
141
|
+
b = v
|
|
142
|
+
break
|
|
143
|
+
case 4:
|
|
144
|
+
r = t
|
|
145
|
+
g = p
|
|
146
|
+
b = v
|
|
147
|
+
break
|
|
148
|
+
case 5:
|
|
149
|
+
r = v
|
|
150
|
+
g = p
|
|
151
|
+
b = q
|
|
152
|
+
break
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
r: Math.round(r * 255),
|
|
157
|
+
g: Math.round(g * 255),
|
|
158
|
+
b: Math.round(b * 255),
|
|
159
|
+
a
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* 将 RGB 颜色对象转换为 HSV 颜色对象.
|
|
165
|
+
* @param color RGB 颜色对象
|
|
166
|
+
* @returns HSV 颜色对象
|
|
167
|
+
*/
|
|
168
|
+
static rgbToHsv (color: RGB): HSV {
|
|
169
|
+
const { r, g, b, a } = color
|
|
170
|
+
const
|
|
171
|
+
max = Math.max(r, g, b),
|
|
172
|
+
min = Math.min(r, g, b),
|
|
173
|
+
d = max - min,
|
|
174
|
+
s = (max === 0 ? 0 : d / max),
|
|
175
|
+
v = max / 255
|
|
176
|
+
let h: number
|
|
177
|
+
|
|
178
|
+
switch (max) {
|
|
179
|
+
case min:
|
|
180
|
+
h = 0
|
|
181
|
+
break
|
|
182
|
+
case r:
|
|
183
|
+
h = (g - b) + d * (g < b ? 6 : 0)
|
|
184
|
+
h /= 6 * d
|
|
185
|
+
break
|
|
186
|
+
case g:
|
|
187
|
+
h = (b - r) + d * 2
|
|
188
|
+
h /= 6 * d
|
|
189
|
+
break
|
|
190
|
+
case b:
|
|
191
|
+
h = (r - g) + d * 4
|
|
192
|
+
h /= 6 * d
|
|
193
|
+
break
|
|
194
|
+
default:
|
|
195
|
+
h = 0 // 理论上不会走到这里
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
h: Math.round(h * 360),
|
|
200
|
+
s: Math.round(s * 100),
|
|
201
|
+
v: Math.round(v * 100),
|
|
202
|
+
a
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* 将颜色文本 (hex 或 rgb/rgba) 转换为 RGB 颜色对象.
|
|
208
|
+
* @param str 颜色字符串
|
|
209
|
+
* @returns RGB 颜色对象
|
|
210
|
+
*/
|
|
211
|
+
static textToRgb (str: string): RGB {
|
|
212
|
+
if (typeof str !== 'string') {
|
|
213
|
+
throw new TypeError('Expected a string')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const color = str.replace(/ /g, '')
|
|
217
|
+
|
|
218
|
+
const m = reRGBA.exec(color)
|
|
219
|
+
|
|
220
|
+
if (m === null) {
|
|
221
|
+
return this.hexToRgb(color)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const rgb: RGB = {
|
|
225
|
+
r: Math.min(255, parseInt(m[2], 10)),
|
|
226
|
+
g: Math.min(255, parseInt(m[3], 10)),
|
|
227
|
+
b: Math.min(255, parseInt(m[4], 10))
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (m[1]) {
|
|
231
|
+
const alpha = parseFloat(m[5])
|
|
232
|
+
// alpha 值在 [0, 1],需要转换为 [0, 100]
|
|
233
|
+
rgb.a = Math.min(1, isNaN(alpha) === true ? 1 : alpha) * 100
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return rgb
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 调亮或调暗颜色.
|
|
241
|
+
* percent > 0 为调亮 (lighten), percent < 0 为调暗 (darken).
|
|
242
|
+
* @param color 颜色字符串
|
|
243
|
+
* @param percent 百分比偏移量, 范围通常为 [-100, 100]
|
|
244
|
+
* @returns 新的十六进制颜色字符串
|
|
245
|
+
*/
|
|
246
|
+
static lighten (color: string, percent: number): string {
|
|
247
|
+
if (typeof color !== 'string') {
|
|
248
|
+
throw new TypeError('Expected a string as color')
|
|
249
|
+
}
|
|
250
|
+
if (typeof percent !== 'number') {
|
|
251
|
+
throw new TypeError('Expected a numeric percent')
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const rgb = this.textToRgb(color)
|
|
255
|
+
const
|
|
256
|
+
t = percent < 0 ? 0 : 255,
|
|
257
|
+
p = Math.abs(percent) / 100,
|
|
258
|
+
R = rgb.r,
|
|
259
|
+
G = rgb.g,
|
|
260
|
+
B = rgb.b
|
|
261
|
+
|
|
262
|
+
return '#' + (
|
|
263
|
+
0x1000000 + (Math.round((t - R) * p) + R) * 0x10000
|
|
264
|
+
+ (Math.round((t - G) * p) + G) * 0x100
|
|
265
|
+
+ (Math.round((t - B) * p) + B)
|
|
266
|
+
).toString(16).slice(1)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 计算颜色的亮度 (Luminosity).
|
|
271
|
+
* @param color 颜色字符串或 RGB 对象
|
|
272
|
+
* @returns 颜色的亮度值 (0 到 1)
|
|
273
|
+
*/
|
|
274
|
+
static luminosity (color: string | RGB): number {
|
|
275
|
+
if (typeof color !== 'string' && (!color || color.r === void 0)) {
|
|
276
|
+
throw new TypeError('Expected a string or a {r, g, b} object as color')
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const
|
|
280
|
+
rgb = typeof color === 'string' ? this.textToRgb(color) : color,
|
|
281
|
+
r = rgb.r / 255,
|
|
282
|
+
g = rgb.g / 255,
|
|
283
|
+
b = rgb.b / 255,
|
|
284
|
+
// 标准化 R, G, B 值
|
|
285
|
+
R = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4),
|
|
286
|
+
G = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4),
|
|
287
|
+
B = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4)
|
|
288
|
+
|
|
289
|
+
// W3C WCAG 2.0 亮度公式
|
|
290
|
+
return 0.2126 * R + 0.7152 * G + 0.0722 * B
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* 计算颜色的感知亮度 (Brightness).
|
|
295
|
+
* @param color 颜色字符串或 RGB 对象
|
|
296
|
+
* @returns 颜色的感知亮度值 (0 到 255)
|
|
297
|
+
*/
|
|
298
|
+
static brightness (color: string | RGB): number {
|
|
299
|
+
if (typeof color !== 'string' && (!color || color.r === void 0)) {
|
|
300
|
+
throw new TypeError('Expected a string or a {r, g, b} object as color')
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const rgb = typeof color === 'string'
|
|
304
|
+
? this.textToRgb(color)
|
|
305
|
+
: color
|
|
306
|
+
|
|
307
|
+
// 根据人眼感知度的加权平均 (常用公式)
|
|
308
|
+
return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* 将前景颜色 (fgColor) 混合到背景颜色 (bgColor) 上。
|
|
313
|
+
* @param fgColor 前景颜色字符串或 RGB 对象
|
|
314
|
+
* @param bgColor 背景颜色字符串或 RGB 对象
|
|
315
|
+
* @returns 如果 fgColor 是字符串则返回十六进制字符串,否则返回 RGB 对象
|
|
316
|
+
*/
|
|
317
|
+
static blend (fgColor: string | RGB, bgColor: string | RGB): string | RGB {
|
|
318
|
+
if (typeof fgColor !== 'string' && (!fgColor || fgColor.r === void 0)) {
|
|
319
|
+
throw new TypeError('Expected a string or a {r, g, b[, a]} object as fgColor')
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (typeof bgColor !== 'string' && (!bgColor || bgColor.r === void 0)) {
|
|
323
|
+
throw new TypeError('Expected a string or a {r, g, b[, a]} object as bgColor')
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const
|
|
327
|
+
rgb1 = typeof fgColor === 'string' ? this.textToRgb(fgColor) : fgColor,
|
|
328
|
+
r1 = rgb1.r / 255,
|
|
329
|
+
g1 = rgb1.g / 255,
|
|
330
|
+
b1 = rgb1.b / 255,
|
|
331
|
+
a1 = rgb1.a !== void 0 ? rgb1.a / 100 : 1, // 前景 alpha (0-1)
|
|
332
|
+
rgb2 = typeof bgColor === 'string' ? this.textToRgb(bgColor) : bgColor,
|
|
333
|
+
r2 = rgb2.r / 255,
|
|
334
|
+
g2 = rgb2.g / 255,
|
|
335
|
+
b2 = rgb2.b / 255,
|
|
336
|
+
a2 = rgb2.a !== void 0 ? rgb2.a / 100 : 1, // 背景 alpha (0-1)
|
|
337
|
+
|
|
338
|
+
// Porter-Duff Over 运算符
|
|
339
|
+
a = a1 + a2 * (1 - a1), // 混合后的总 alpha
|
|
340
|
+
r = Math.round(((r1 * a1 + r2 * a2 * (1 - a1)) / a) * 255),
|
|
341
|
+
g = Math.round(((g1 * a1 + g2 * a2 * (1 - a1)) / a) * 255),
|
|
342
|
+
b = Math.round(((b1 * a1 + b2 * a2 * (1 - a1)) / a) * 255)
|
|
343
|
+
|
|
344
|
+
const ret: RGB = { r, g, b, a: Math.round(a * 100) } // a 转换回 (0-100)
|
|
345
|
+
|
|
346
|
+
// 如果前景颜色输入是字符串,则返回十六进制字符串,否则返回 RGB 对象
|
|
347
|
+
return typeof fgColor === 'string'
|
|
348
|
+
? this.rgbToHex(ret)
|
|
349
|
+
: ret
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* 改变颜色字符串的 alpha 透明度。
|
|
354
|
+
* @param color 颜色字符串 (如 '#RRGGBB' 或 'rgb(r,g,b)')
|
|
355
|
+
* @param offset alpha 的偏移量, 范围 [-1, 1]。正值增加透明度,负值减少透明度。
|
|
356
|
+
* @returns 带有新 alpha 值的十六进制颜色字符串 (#RRGGBBAA)
|
|
357
|
+
*/
|
|
358
|
+
static changeAlpha (color: string, offset: number): string {
|
|
359
|
+
if (typeof color !== 'string') {
|
|
360
|
+
throw new TypeError('Expected a string as color')
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (offset === void 0 || offset < -1 || offset > 1) {
|
|
364
|
+
throw new TypeError('Expected offset to be between -1 and 1')
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const { r, g, b, a } = this.textToRgb(color)
|
|
368
|
+
// 当前 alpha (0-1)
|
|
369
|
+
const alpha = a !== void 0 ? a / 100 : 1 // 如果没有 alpha,默认为 1 (100%)
|
|
370
|
+
|
|
371
|
+
// 新的 alpha (0-100)
|
|
372
|
+
const newAlpha = Math.round(Math.min(1, Math.max(0, alpha + offset)) * 100)
|
|
373
|
+
|
|
374
|
+
return this.rgbToHex({
|
|
375
|
+
r, g, b, a: newAlpha
|
|
376
|
+
})
|
|
377
|
+
}
|
|
378
|
+
}
|
|
@@ -1,108 +1,105 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StringUtils } from './StringUtils';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
year(date) {
|
|
3
|
+
export class DateUtils {
|
|
4
|
+
public static year(date: Date): number {
|
|
7
5
|
return date.getFullYear();
|
|
8
|
-
}
|
|
6
|
+
}
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
|
-
*
|
|
9
|
+
* 获取月份,自动补0
|
|
12
10
|
* @param date
|
|
13
|
-
* @returns {
|
|
11
|
+
* @returns {string}
|
|
14
12
|
*/
|
|
15
|
-
|
|
13
|
+
public static month(date: Date): string {
|
|
16
14
|
const n = date.getMonth() + 1; // (注意月份从0开始,所以要加1)
|
|
17
|
-
return
|
|
18
|
-
}
|
|
15
|
+
return StringUtils.pad(n, 2);
|
|
16
|
+
}
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
19
|
* 获取日期,
|
|
22
20
|
* @param date
|
|
23
21
|
*/
|
|
24
|
-
|
|
25
|
-
return
|
|
26
|
-
}
|
|
22
|
+
public static date(date: Date): string {
|
|
23
|
+
return StringUtils.pad(date.getDate(), 2);
|
|
24
|
+
}
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
|
-
* 小时,
|
|
27
|
+
* 小时,24进制
|
|
30
28
|
* @param date
|
|
31
29
|
* @returns {string}
|
|
32
30
|
*/
|
|
33
|
-
|
|
34
|
-
return
|
|
35
|
-
}
|
|
31
|
+
public static hour(date: Date): string {
|
|
32
|
+
return StringUtils.pad(date.getHours(), 2);
|
|
33
|
+
}
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
return
|
|
39
|
-
}
|
|
35
|
+
public static minute(date: Date): string {
|
|
36
|
+
return StringUtils.pad(date.getMinutes(), 2);
|
|
37
|
+
}
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
return
|
|
43
|
-
}
|
|
39
|
+
public static second(date: Date): string {
|
|
40
|
+
return StringUtils.pad(date.getSeconds(), 2);
|
|
41
|
+
}
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
return this.year(d) + '-' + this.month(d) +
|
|
47
|
-
}
|
|
43
|
+
public static formatDate(d: Date): string {
|
|
44
|
+
return this.year(d) + '-' + this.month(d) + '-' + this.date(d);
|
|
45
|
+
}
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
return this.hour(d) + ':' + this.minute(d) +
|
|
51
|
-
}
|
|
47
|
+
public static formatTime(d: Date): string {
|
|
48
|
+
return this.hour(d) + ':' + this.minute(d) + ':' + this.second(d);
|
|
49
|
+
}
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
return this.formatDate(d) +
|
|
55
|
-
}
|
|
51
|
+
public static formatDateTime(d: Date): string {
|
|
52
|
+
return this.formatDate(d) + ' ' + this.formatTime(d);
|
|
53
|
+
}
|
|
56
54
|
|
|
57
55
|
/**
|
|
58
56
|
*
|
|
59
57
|
* @param d
|
|
60
58
|
* @returns {string} 2020年1月30日
|
|
61
59
|
*/
|
|
62
|
-
|
|
63
|
-
return this.year(d) + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日'
|
|
64
|
-
}
|
|
60
|
+
public static formatDateCn(d: Date): string {
|
|
61
|
+
return this.year(d) + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日';
|
|
62
|
+
}
|
|
65
63
|
|
|
66
64
|
/***
|
|
67
65
|
当前时间, 如 2022-01-23 11:59:59
|
|
68
66
|
*/
|
|
69
|
-
|
|
67
|
+
public static now(): string {
|
|
70
68
|
return this.formatDateTime(new Date());
|
|
71
|
-
}
|
|
69
|
+
}
|
|
72
70
|
|
|
73
71
|
/**
|
|
74
72
|
* 当前日期 ,如 2022-01-23
|
|
75
73
|
*
|
|
76
74
|
*/
|
|
77
|
-
|
|
75
|
+
public static today(): string {
|
|
78
76
|
return this.formatDate(new Date());
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
thisYear() {
|
|
82
|
-
return this.year(new Date())
|
|
83
|
-
},
|
|
77
|
+
}
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
return this.
|
|
87
|
-
}
|
|
79
|
+
public static thisYear(): number {
|
|
80
|
+
return this.year(new Date());
|
|
81
|
+
}
|
|
88
82
|
|
|
83
|
+
public static thisMonth(): string {
|
|
84
|
+
return this.month(new Date());
|
|
85
|
+
}
|
|
89
86
|
|
|
90
87
|
/**
|
|
91
|
-
*
|
|
92
|
-
* @param pastDate 日期, 支持Date,
|
|
88
|
+
* 显示友好时间,如 2小时前,1周前
|
|
89
|
+
* @param pastDate 日期, 支持Date,String,Number
|
|
93
90
|
*/
|
|
94
|
-
|
|
91
|
+
public static friendlyTime(pastDate: Date | string | number): string | undefined {
|
|
95
92
|
if (pastDate == null) {
|
|
96
|
-
return
|
|
93
|
+
return undefined;
|
|
97
94
|
}
|
|
98
95
|
if (!(pastDate instanceof Date)) {
|
|
99
|
-
pastDate = new Date(pastDate)
|
|
96
|
+
pastDate = new Date(pastDate);
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
const currentDate = new Date();
|
|
103
|
-
let elapsedMilliseconds = currentDate - pastDate;
|
|
104
|
-
const suffix = elapsedMilliseconds > 0 ?
|
|
105
|
-
elapsedMilliseconds = Math.abs(elapsedMilliseconds)
|
|
100
|
+
let elapsedMilliseconds = currentDate.getTime() - pastDate.getTime();
|
|
101
|
+
const suffix = elapsedMilliseconds > 0 ? '前' : '后';
|
|
102
|
+
elapsedMilliseconds = Math.abs(elapsedMilliseconds);
|
|
106
103
|
|
|
107
104
|
// 计算年、月、日、小时、分钟和秒的差值
|
|
108
105
|
const elapsedYears = Math.floor(elapsedMilliseconds / (1000 * 60 * 60 * 24 * 365));
|
|
@@ -134,20 +131,26 @@ export const DateUtil = {
|
|
|
134
131
|
return `${elapsedMinutes} 分钟${suffix}`;
|
|
135
132
|
}
|
|
136
133
|
return `${elapsedSeconds} 秒${suffix}`;
|
|
137
|
-
}
|
|
134
|
+
}
|
|
138
135
|
|
|
139
136
|
/**
|
|
140
137
|
* 总共耗时, 如 3分5秒
|
|
141
138
|
* @param time 数字 (Date.getTime)
|
|
142
139
|
* @returns {string|null}
|
|
143
140
|
*/
|
|
144
|
-
|
|
141
|
+
public static friendlyTotalTime(time: number | string | null): string | null {
|
|
145
142
|
if (time == null || time === '-') {
|
|
146
|
-
return null
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let seconds: number;
|
|
147
|
+
if (typeof time === 'string') {
|
|
148
|
+
seconds = parseInt(time, 10) / 1000;
|
|
149
|
+
} else {
|
|
150
|
+
seconds = time / 1000;
|
|
147
151
|
}
|
|
148
|
-
let seconds = time / 1000;
|
|
149
152
|
|
|
150
|
-
seconds = Math.floor(seconds)
|
|
153
|
+
seconds = Math.floor(seconds);
|
|
151
154
|
|
|
152
155
|
if (seconds < 60) {
|
|
153
156
|
return seconds + '秒';
|
|
@@ -157,17 +160,14 @@ export const DateUtil = {
|
|
|
157
160
|
seconds = seconds % 60;
|
|
158
161
|
|
|
159
162
|
min = Math.floor(min);
|
|
160
|
-
seconds = Math.floor(seconds)
|
|
163
|
+
seconds = Math.floor(seconds);
|
|
161
164
|
|
|
162
|
-
return min + '分' + seconds + '秒'
|
|
163
|
-
}
|
|
165
|
+
return min + '分' + seconds + '秒';
|
|
166
|
+
}
|
|
164
167
|
|
|
165
|
-
beginOfMonth(){
|
|
168
|
+
public static beginOfMonth(): string {
|
|
166
169
|
const d = new Date();
|
|
167
|
-
d.
|
|
168
|
-
|
|
169
|
-
return this.formatDate(d)
|
|
170
|
+
d.setDate(1);
|
|
171
|
+
return this.formatDate(d);
|
|
170
172
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
173
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 包含了常用的浏览器和网络工具函数。
|
|
3
|
+
*/
|
|
4
|
+
export class DeviceUtils {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 判断当前设备是否为移动设备 (包括 Windows Phone, Android, iOS)。
|
|
8
|
+
* @returns {boolean} 如果是移动设备返回 true,否则返回 false。
|
|
9
|
+
*/
|
|
10
|
+
public static isMobileDevice(): boolean {
|
|
11
|
+
// 使用可选链操作符来安全地访问 navigator 和 window 上的属性,
|
|
12
|
+
// 以防在非浏览器环境中运行 (尽管这个函数主要用于浏览器环境)。
|
|
13
|
+
const userAgent = navigator?.userAgent || navigator?.vendor || (window as any)?.opera || '';
|
|
14
|
+
|
|
15
|
+
// 1. Windows Phone 必须放在 Android 之前,因为它的 UA 也可能包含 "Android"
|
|
16
|
+
if (/windows phone/i.test(userAgent)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 2. Android devices
|
|
21
|
+
if (/android/i.test(userAgent)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 3. iOS devices
|
|
26
|
+
// window.MSStream 检查是为了排除旧版 IE 上的触控设备,确保只检测移动设备。
|
|
27
|
+
// 对于 TypeScript,需要断言 window.MSStream 可能不存在。
|
|
28
|
+
if (/iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 根据当前页面的协议 (http/https) 和主机名构造 WebSocket 的基础 URL (ws/wss)。
|
|
37
|
+
* @returns {string} WebSocket 的基础 URL,例如 "ws://localhost:8080" 或 "wss://example.com"。
|
|
38
|
+
*/
|
|
39
|
+
public static getWebsocketBaseUrl(): string {
|
|
40
|
+
// 使用 location.protocol 来确定是 ws 还是 wss。
|
|
41
|
+
const protocol: string = location.protocol === 'http:' ? 'ws:' : 'wss:';
|
|
42
|
+
|
|
43
|
+
// location.host 包含主机名和端口号 (如果有)。
|
|
44
|
+
return `${protocol}//${location.host}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview DOM 操作工具类
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 封装了获取元素位置和尺寸的工具方法。
|
|
7
|
+
*/
|
|
8
|
+
export class DomUtils {
|
|
9
|
+
/**
|
|
10
|
+
* 获取元素相对于视口的偏移量(top 和 left)。
|
|
11
|
+
*
|
|
12
|
+
* @param el 目标 DOM 元素或 window 对象。
|
|
13
|
+
* @returns 包含 top 和 left 属性的对象。
|
|
14
|
+
*/
|
|
15
|
+
static offset(el: Element | Window): { top: number; left: number } {
|
|
16
|
+
if (el === window) {
|
|
17
|
+
return { top: 0, left: 0 };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 类型断言,确保 el 是 Element 类型,以便调用 getBoundingClientRect
|
|
21
|
+
const element = el as Element;
|
|
22
|
+
const { top, left } = element.getBoundingClientRect();
|
|
23
|
+
|
|
24
|
+
return { top, left };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 获取元素的外部高度(如果是 window,则返回视口高度)。
|
|
29
|
+
*
|
|
30
|
+
* @param el 目标 DOM 元素或 window 对象。
|
|
31
|
+
* @returns 元素的高度(以像素为单位)。
|
|
32
|
+
*/
|
|
33
|
+
static height(el: Element | Window): number {
|
|
34
|
+
return el === window
|
|
35
|
+
? window.innerHeight // 视口高度
|
|
36
|
+
: (el as Element).getBoundingClientRect().height; // 元素高度
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 获取元素的外部宽度(如果是 window,则返回视口宽度)。
|
|
41
|
+
*
|
|
42
|
+
* @param el 目标 DOM 元素或 window 对象。
|
|
43
|
+
* @returns 元素的宽度(以像素为单位)。
|
|
44
|
+
*/
|
|
45
|
+
static width(el: Element | Window): number {
|
|
46
|
+
return el === window
|
|
47
|
+
? window.innerWidth // 视口宽度
|
|
48
|
+
: (el as Element).getBoundingClientRect().width; // 元素宽度
|
|
49
|
+
}
|
|
50
|
+
}
|