bohui-vue 1.0.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.
- package/README.md +121 -0
- package/bin/create-vue-template.js +565 -0
- package/package.json +28 -0
- package/templates/vue-project/.browserslistrc +3 -0
- package/templates/vue-project/.editorconfig +28 -0
- package/templates/vue-project/.env.development +2 -0
- package/templates/vue-project/.env.production +2 -0
- package/templates/vue-project/.eslintrc.cjs +76 -0
- package/templates/vue-project/.keep +0 -0
- package/templates/vue-project/.node-version +1 -0
- package/templates/vue-project/.prettierignore +13 -0
- package/templates/vue-project/.prettierrc +20 -0
- package/templates/vue-project/.prettierrc.txt +130 -0
- package/templates/vue-project/.stylelintrc.json +94 -0
- package/templates/vue-project/README.md +24 -0
- package/templates/vue-project/babel.config.js +5 -0
- package/templates/vue-project/index.html +34 -0
- package/templates/vue-project/package.json +75 -0
- package/templates/vue-project/public/favicon.ico +0 -0
- package/templates/vue-project/public/static/img/ai-default.jpg +0 -0
- package/templates/vue-project/public/static/img/image.png +0 -0
- package/templates/vue-project/public/static/img/ppt1.png +0 -0
- package/templates/vue-project/public/static/img/ppt2.png +0 -0
- package/templates/vue-project/public/static/img/ppt3.png +0 -0
- package/templates/vue-project/public/static/js/config.js +11 -0
- package/templates/vue-project/public/static/js/dataConfig.js +1143 -0
- package/templates/vue-project/src/App.vue +10 -0
- package/templates/vue-project/src/api/error-handler.ts +60 -0
- package/templates/vue-project/src/api/http.ts +254 -0
- package/templates/vue-project/src/api/services/aicebd.ts +47 -0
- package/templates/vue-project/src/api/services/base.ts +18 -0
- package/templates/vue-project/src/api/services/umse.ts +17 -0
- package/templates/vue-project/src/assets/font/Alibaba-PuHuiTi-Medium.otf +0 -0
- package/templates/vue-project/src/assets/font/Alibaba-PuHuiTi-Regular.otf +0 -0
- package/templates/vue-project/src/assets/font/DOUYINSANSBOLD.OTF +0 -0
- package/templates/vue-project/src/assets/font/Pangmen-Title.TTF +0 -0
- package/templates/vue-project/src/assets/font/font.css +25 -0
- package/templates/vue-project/src/assets/iconfont/iconfont.css +402 -0
- package/templates/vue-project/src/assets/iconfont/iconfont.js +66 -0
- package/templates/vue-project/src/assets/iconfont/iconfont.json +688 -0
- package/templates/vue-project/src/assets/iconfont/iconfont.ttf +0 -0
- package/templates/vue-project/src/assets/iconfont/iconfont.woff +0 -0
- package/templates/vue-project/src/assets/iconfont/iconfont.woff2 +0 -0
- package/templates/vue-project/src/assets/images/Click-tap.png +0 -0
- package/templates/vue-project/src/assets/images/Effects.png +0 -0
- package/templates/vue-project/src/assets/images/bg.png +0 -0
- package/templates/vue-project/src/assets/images/erCode.png +0 -0
- package/templates/vue-project/src/assets/images/header-bg.png +0 -0
- package/templates/vue-project/src/assets/images/logo.png +0 -0
- package/templates/vue-project/src/assets/scss/common.scss +530 -0
- package/templates/vue-project/src/assets/styles/element-overrides.css +53 -0
- package/templates/vue-project/src/assets/styles/reset.css +186 -0
- package/templates/vue-project/src/assets/styles/theme.css +100 -0
- package/templates/vue-project/src/components/BarChart.vue +238 -0
- package/templates/vue-project/src/components/echarts/EChart.vue +140 -0
- package/templates/vue-project/src/composables/useTheme.ts +84 -0
- package/templates/vue-project/src/main.ts +111 -0
- package/templates/vue-project/src/mocks/base.ts +37 -0
- package/templates/vue-project/src/mocks/umse.ts +31 -0
- package/templates/vue-project/src/router/index.ts +32 -0
- package/templates/vue-project/src/shims-vue.d.ts +19 -0
- package/templates/vue-project/src/store/index.ts +18 -0
- package/templates/vue-project/src/store/modules/user.ts +85 -0
- package/templates/vue-project/src/types/DTO/aicebd.d.ts +60 -0
- package/templates/vue-project/src/types/DTO/base.d.ts +26 -0
- package/templates/vue-project/src/types/DTO/global.d.ts +48 -0
- package/templates/vue-project/src/types/VO/teachingLog.d.ts +15 -0
- package/templates/vue-project/src/types/auto-imports.d.ts +73 -0
- package/templates/vue-project/src/types/components.d.ts +17 -0
- package/templates/vue-project/src/types/element-plus.d.ts +15 -0
- package/templates/vue-project/src/types/js-cookie.d.ts +1 -0
- package/templates/vue-project/src/types/unocss.d.ts +2 -0
- package/templates/vue-project/src/types/vite-plugins.d.ts +3 -0
- package/templates/vue-project/src/types/vue-router.d.ts +1 -0
- package/templates/vue-project/src/types/window-config.d.ts +12 -0
- package/templates/vue-project/src/utils/com-methods.ts +307 -0
- package/templates/vue-project/src/utils/echarts.ts +111 -0
- package/templates/vue-project/src/utils/number.ts +99 -0
- package/templates/vue-project/src/utils/rem.ts +82 -0
- package/templates/vue-project/src/utils/responsive.ts +103 -0
- package/templates/vue-project/src/utils/time.ts +314 -0
- package/templates/vue-project/src/utils/tracker.ts +527 -0
- package/templates/vue-project/src/utils/validators.ts +85 -0
- package/templates/vue-project/src/utils/window.ts +132 -0
- package/templates/vue-project/src/views/home/Home.vue +60 -0
- package/templates/vue-project/src/views/home/composables/useUserAuth.ts +13 -0
- package/templates/vue-project/src/views/teachingLog/TeachingLog.vue +40 -0
- package/templates/vue-project/src/views/teachingLog/__tests__/TeachingEffect.test.ts +96 -0
- package/templates/vue-project/src/views/teachingLog/__tests__/TeachingHighlight.test.ts +66 -0
- package/templates/vue-project/src/views/teachingLog/__tests__/TeachingLog.test.ts +34 -0
- package/templates/vue-project/src/views/teachingLog/components/TeachingEffect.vue +458 -0
- package/templates/vue-project/src/views/teachingLog/components/TeachingHighlight.vue +181 -0
- package/templates/vue-project/src/views/teachingLog/composables/useEffectTooltip.ts +88 -0
- package/templates/vue-project/src/views/teachingLog/composables/useEffectTrendChart.ts +160 -0
- package/templates/vue-project/tests/setup.ts +27 -0
- package/templates/vue-project/tsconfig.json +24 -0
- package/templates/vue-project/tsconfig.node.json +41 -0
- package/templates/vue-project/uno.config.ts +84 -0
- package/templates/vue-project/vite.config.ts +216 -0
- package/templates/vue-project/vue3_ai_prompt.md +652 -0
- package/templates/vue-project/vue3_ai_prompt_basic.md +722 -0
- package/templates/vue-project/vue3_ai_prompt_full.md +1021 -0
- package/templates/vue-project/vue3_ai_prompt_unocss.md +768 -0
- package/templates/vue-project//345/267/245/347/250/213/345/214/226/346/250/241/346/235/277/344/273/213/347/273/215.md +463 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 响应式单位转换工具函数
|
|
3
|
+
* 用于将设计稿的 px 值转换为基于当前窗口大小的实际像素值
|
|
4
|
+
* 设计稿基于 1080P 分辨率(1920x1080)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// 设计稿尺寸
|
|
8
|
+
const DESIGN_WIDTH = 1920;
|
|
9
|
+
const DESIGN_HEIGHT = 1080;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 响应式单位类型
|
|
13
|
+
*/
|
|
14
|
+
export type ResponsiveUnit = "vw" | "vh";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 将设计稿的 px 值转换为响应式的实际像素值(基于 vw)
|
|
18
|
+
* @param px 设计稿中的像素值
|
|
19
|
+
* @returns 转换后的实际像素值
|
|
20
|
+
* @example
|
|
21
|
+
* // 设计稿中 50px,转换为响应式像素值
|
|
22
|
+
* const fontSize = getResponsivePx(50, 'vw');
|
|
23
|
+
*/
|
|
24
|
+
export function getResponsivePx(px: number, unit: ResponsiveUnit = "vw"): number {
|
|
25
|
+
if (typeof window === "undefined") {
|
|
26
|
+
// SSR 环境,返回原始值
|
|
27
|
+
return px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (unit === "vw") {
|
|
31
|
+
if (window.innerWidth > 1920 && window.innerWidth <= 2560) {
|
|
32
|
+
return px * 1.1;
|
|
33
|
+
} else if (window.innerWidth > 2560) {
|
|
34
|
+
return px * 1.2;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 基于设计稿宽度 1920px
|
|
38
|
+
return (px / DESIGN_WIDTH) * window.innerWidth;
|
|
39
|
+
} else {
|
|
40
|
+
// 基于设计稿高度 1080px
|
|
41
|
+
return (px / DESIGN_HEIGHT) * window.innerHeight;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 批量转换多个 px 值
|
|
47
|
+
* @param values 需要转换的像素值对象
|
|
48
|
+
* @param unit 响应式单位类型(默认 'vw')
|
|
49
|
+
* @returns 转换后的像素值对象
|
|
50
|
+
* @example
|
|
51
|
+
* const sizes = getResponsivePxBatch({
|
|
52
|
+
* fontSize: 12,
|
|
53
|
+
* lineHeight: 15,
|
|
54
|
+
* padding: 20
|
|
55
|
+
* }, 'vw');
|
|
56
|
+
*/
|
|
57
|
+
export function getResponsivePxBatch<T extends Record<string, number>>(
|
|
58
|
+
values: T,
|
|
59
|
+
unit: ResponsiveUnit = "vw"
|
|
60
|
+
): { [K in keyof T]: number } {
|
|
61
|
+
const result = {} as { [K in keyof T]: number };
|
|
62
|
+
(Object.keys(values) as Array<keyof T>).forEach((key) => {
|
|
63
|
+
const value = values[key];
|
|
64
|
+
result[key] = getResponsivePx(value, unit);
|
|
65
|
+
});
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 获取当前窗口尺寸
|
|
71
|
+
* @returns 窗口宽度和高度
|
|
72
|
+
*/
|
|
73
|
+
export function getWindowSize(): { width: number; height: number } {
|
|
74
|
+
if (typeof window === "undefined") {
|
|
75
|
+
return { width: DESIGN_WIDTH, height: DESIGN_HEIGHT };
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
width: window.innerWidth,
|
|
79
|
+
height: window.innerHeight,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 响应式字体大小计算(专门用于字体大小,通常使用 vw)
|
|
85
|
+
* @param fontSize 设计稿中的字体大小(px)
|
|
86
|
+
* @returns 转换后的字体大小(px)
|
|
87
|
+
* @example
|
|
88
|
+
* const fontSize = getResponsiveFontSize(12); // 基于 vw 计算
|
|
89
|
+
*/
|
|
90
|
+
export function getResponsiveFontSize(fontSize: number): number {
|
|
91
|
+
return getResponsivePx(fontSize, "vw");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 响应式行高计算(通常使用 vh)
|
|
96
|
+
* @param lineHeight 设计稿中的行高(px)
|
|
97
|
+
* @returns 转换后的行高(px)
|
|
98
|
+
* @example
|
|
99
|
+
* const lineHeight = getResponsiveLineHeight(15); // 基于 vh 计算
|
|
100
|
+
*/
|
|
101
|
+
export function getResponsiveLineHeight(lineHeight: number): number {
|
|
102
|
+
return getResponsivePx(lineHeight, "vh");
|
|
103
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 时间工具函数集合
|
|
5
|
+
*
|
|
6
|
+
* 使用示例:
|
|
7
|
+
*
|
|
8
|
+
* // 基础时间格式化
|
|
9
|
+
* formatTime(1640995200000) // "2022-01-01 08:00:00"
|
|
10
|
+
* formatTime(new Date()) // "2024-01-15 14:30:25"
|
|
11
|
+
* formatTime('2022-01-01') // "2022-01-01 00:00:00"
|
|
12
|
+
*
|
|
13
|
+
* // 自定义格式
|
|
14
|
+
* formatTime(1640995200000, 'YYYY/MM/DD') // "2022/01/01"
|
|
15
|
+
* formatTime(1640995200000, 'MM-DD HH:mm') // "01-01 08:00"
|
|
16
|
+
*
|
|
17
|
+
* // 其他格式化函数
|
|
18
|
+
* formatDate(1640995200000) // "2022-01-01"
|
|
19
|
+
* formatTimeOnly(1640995200000) // "08:00:00"
|
|
20
|
+
* formatDateTime(1640995200000) // "01-01 08:00"
|
|
21
|
+
* formatTimeCN(1640995200000) // "2022年01月01日 08:00:00"
|
|
22
|
+
*
|
|
23
|
+
* // 相对时间和判断
|
|
24
|
+
* getRelativeTime(Date.now() - 3600000) // "1小时前"
|
|
25
|
+
* isToday(new Date()) // true
|
|
26
|
+
* isThisWeek(Date.now() - 86400000) // true
|
|
27
|
+
*
|
|
28
|
+
* // 时长计算
|
|
29
|
+
* getDuration('2022-01-01 08:00:00', '2022-01-01 10:30:00') // 150 (分钟)
|
|
30
|
+
* formatDuration('2022-01-01 08:00:00', '2022-01-01 10:30:00') // "2小时30分钟"
|
|
31
|
+
*
|
|
32
|
+
* // 时间单位转换
|
|
33
|
+
* convertTimeUnit(90, "分钟") // { firstValue: 1, secondValue: 30, firstUnit: "小时", secondUnit: "分钟" }
|
|
34
|
+
* convertTimeUnit(25, "小时") // { firstValue: 1, secondValue: 1, firstUnit: "天", secondUnit: "小时" }
|
|
35
|
+
* convertTimeUnit(2, "年") // { firstValue: 2, secondValue: 0, firstUnit: "年", secondUnit: "月" }
|
|
36
|
+
* convertTimeUnit(45, "天") // { firstValue: 1, secondValue: 15, firstUnit: "月", secondUnit: "天" }
|
|
37
|
+
*
|
|
38
|
+
* // 秒转换为时间单位
|
|
39
|
+
* formatSeconds(12345) // "15:00"
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
export interface TimeUnitConversionResult {
|
|
43
|
+
firstValue: number;
|
|
44
|
+
secondValue: number;
|
|
45
|
+
firstUnit: string;
|
|
46
|
+
secondUnit: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 将时间长度值转换为两个时间单位显示
|
|
51
|
+
* @param value 时间长度数值
|
|
52
|
+
* @param unit 时间单位(分钟、小时、天、月、年)
|
|
53
|
+
* @returns 转换后的两个时间单位及对应数值
|
|
54
|
+
*/
|
|
55
|
+
export function convertTimeUnit(value: number, unit: string): TimeUnitConversionResult {
|
|
56
|
+
let totalMinutes = 0;
|
|
57
|
+
|
|
58
|
+
// 统一转换为分钟
|
|
59
|
+
switch (unit) {
|
|
60
|
+
case "分钟":
|
|
61
|
+
case "分":
|
|
62
|
+
totalMinutes = value;
|
|
63
|
+
break;
|
|
64
|
+
case "小时":
|
|
65
|
+
case "时":
|
|
66
|
+
totalMinutes = value * 60;
|
|
67
|
+
break;
|
|
68
|
+
case "天":
|
|
69
|
+
case "日":
|
|
70
|
+
totalMinutes = value * 24 * 60;
|
|
71
|
+
break;
|
|
72
|
+
case "月":
|
|
73
|
+
totalMinutes = value * 30 * 24 * 60;
|
|
74
|
+
break;
|
|
75
|
+
case "年":
|
|
76
|
+
totalMinutes = value * 365 * 24 * 60;
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
totalMinutes = value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 转换为两个时间单位
|
|
83
|
+
let firstValue = 0;
|
|
84
|
+
let secondValue = 0;
|
|
85
|
+
let firstUnit = "";
|
|
86
|
+
let secondUnit = "";
|
|
87
|
+
|
|
88
|
+
if (totalMinutes >= 365 * 24 * 60) {
|
|
89
|
+
// 年 + 月
|
|
90
|
+
firstValue = Math.floor(totalMinutes / (365 * 24 * 60));
|
|
91
|
+
secondValue = Math.floor((totalMinutes % (365 * 24 * 60)) / (30 * 24 * 60));
|
|
92
|
+
firstUnit = "年";
|
|
93
|
+
secondUnit = "月";
|
|
94
|
+
} else if (totalMinutes >= 30 * 24 * 60) {
|
|
95
|
+
// 月 + 天
|
|
96
|
+
firstValue = Math.floor(totalMinutes / (30 * 24 * 60));
|
|
97
|
+
secondValue = Math.floor((totalMinutes % (30 * 24 * 60)) / (24 * 60));
|
|
98
|
+
firstUnit = "月";
|
|
99
|
+
secondUnit = "天";
|
|
100
|
+
} else if (totalMinutes >= 1000 * 60) {
|
|
101
|
+
// 天 + 小时(小时数达到四位数时转换为天)
|
|
102
|
+
firstValue = Math.floor(totalMinutes / (24 * 60));
|
|
103
|
+
secondValue = Math.floor((totalMinutes % (24 * 60)) / 60);
|
|
104
|
+
firstUnit = "天";
|
|
105
|
+
secondUnit = "小时";
|
|
106
|
+
} else if (totalMinutes >= 60) {
|
|
107
|
+
// 小时 + 分钟(小时数可能达到四位数)
|
|
108
|
+
firstValue = Math.floor(totalMinutes / 60);
|
|
109
|
+
secondValue = totalMinutes % 60;
|
|
110
|
+
firstUnit = "小时";
|
|
111
|
+
secondUnit = "分钟";
|
|
112
|
+
} else {
|
|
113
|
+
// 分钟 + 秒(如果小于1分钟,显示0小时X分钟)
|
|
114
|
+
firstValue = 0;
|
|
115
|
+
secondValue = totalMinutes;
|
|
116
|
+
firstUnit = "小时";
|
|
117
|
+
secondUnit = "分钟";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
firstValue,
|
|
122
|
+
secondValue,
|
|
123
|
+
firstUnit,
|
|
124
|
+
secondUnit,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 将时间数值拆分为单个数字数组(用于数字展示组件)
|
|
130
|
+
* @param value 时间数值
|
|
131
|
+
* @returns 数字数组,如 1234 => [1, 2, 3, 4]
|
|
132
|
+
*/
|
|
133
|
+
export function splitTimeValueToDigits(value: number): number[] {
|
|
134
|
+
return String(Math.abs(Math.round(value)))
|
|
135
|
+
.split("")
|
|
136
|
+
.map(Number);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 格式化时间戳为标准日期时间格式
|
|
141
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
142
|
+
* @param format 格式化模板,默认为 'YYYY-MM-DD HH:mm:ss'
|
|
143
|
+
* @returns 格式化后的时间字符串
|
|
144
|
+
*/
|
|
145
|
+
export const formatTime = (
|
|
146
|
+
timestamp: string | number | Date,
|
|
147
|
+
format = "YYYY-MM-DD HH:mm:ss"
|
|
148
|
+
): string => {
|
|
149
|
+
if (!timestamp) return "-";
|
|
150
|
+
return moment(timestamp).format(format);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 格式化时间戳为日期格式(年-月-日)
|
|
155
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
156
|
+
* @returns 格式化后的日期字符串
|
|
157
|
+
*/
|
|
158
|
+
export const formatDate = (timestamp: string | number | Date): string => {
|
|
159
|
+
return formatTime(timestamp, "YYYY-MM-DD");
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 格式化时间戳为时间格式(时:分:秒)
|
|
164
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
165
|
+
* @returns 格式化后的时间字符串
|
|
166
|
+
*/
|
|
167
|
+
export const formatTimeOnly = (timestamp: string | number | Date): string => {
|
|
168
|
+
return formatTime(timestamp, "HH:mm:ss");
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 格式化时间戳为短日期时间格式
|
|
173
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
174
|
+
* @returns 格式化后的时间字符串
|
|
175
|
+
*/
|
|
176
|
+
export const formatDateTime = (timestamp: string | number | Date): string => {
|
|
177
|
+
return formatTime(timestamp, "MM-DD HH:mm");
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 格式化时间戳为中文日期时间格式
|
|
182
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
183
|
+
* @returns 格式化后的时间字符串
|
|
184
|
+
*/
|
|
185
|
+
export const formatTimeCN = (timestamp: string | number | Date): string => {
|
|
186
|
+
return formatTime(timestamp, "YYYY年MM月DD日 HH:mm:ss");
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* 获取相对时间(如:1小时前、3天前等)
|
|
191
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
192
|
+
* @returns 相对时间字符串
|
|
193
|
+
*/
|
|
194
|
+
export const getRelativeTime = (timestamp: string | number | Date): string => {
|
|
195
|
+
if (!timestamp) return "-";
|
|
196
|
+
return moment(timestamp).fromNow();
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 判断是否是今天
|
|
201
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
202
|
+
* @returns 是否是今天
|
|
203
|
+
*/
|
|
204
|
+
export const isToday = (timestamp: string | number | Date): boolean => {
|
|
205
|
+
if (!timestamp) return false;
|
|
206
|
+
return moment(timestamp).isSame(moment(), "day");
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* 判断是否是本周
|
|
211
|
+
* @param timestamp 时间戳(毫秒)或日期字符串
|
|
212
|
+
* @returns 是否是本周
|
|
213
|
+
*/
|
|
214
|
+
export const isThisWeek = (timestamp: string | number | Date): boolean => {
|
|
215
|
+
if (!timestamp) return false;
|
|
216
|
+
return moment(timestamp).isSame(moment(), "week");
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* 获取两个时间之间的时长
|
|
221
|
+
* @param startTime 开始时间
|
|
222
|
+
* @param endTime 结束时间
|
|
223
|
+
* @param unit 单位('days', 'hours', 'minutes', 'seconds')
|
|
224
|
+
* @returns 时长数值
|
|
225
|
+
*/
|
|
226
|
+
export const getDuration = (
|
|
227
|
+
startTime: string | number | Date,
|
|
228
|
+
endTime: string | number | Date,
|
|
229
|
+
unit: "days" | "hours" | "minutes" | "seconds" = "minutes"
|
|
230
|
+
): number => {
|
|
231
|
+
if (!startTime || !endTime) return 0;
|
|
232
|
+
const start = moment(startTime);
|
|
233
|
+
const end = moment(endTime);
|
|
234
|
+
return end.diff(start, unit);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* 格式化时长为可读格式
|
|
239
|
+
* @param startTime 开始时间
|
|
240
|
+
* @param endTime 结束时间
|
|
241
|
+
* @returns 格式化的时长字符串(如:2小时30分钟)
|
|
242
|
+
*/
|
|
243
|
+
export const formatDuration = (
|
|
244
|
+
startTime: string | number | Date,
|
|
245
|
+
endTime: string | number | Date
|
|
246
|
+
): string => {
|
|
247
|
+
if (!startTime || !endTime) return "-";
|
|
248
|
+
|
|
249
|
+
const start = moment(startTime);
|
|
250
|
+
const end = moment(endTime);
|
|
251
|
+
const duration = moment.duration(end.diff(start));
|
|
252
|
+
|
|
253
|
+
const days = Math.floor(duration.asDays());
|
|
254
|
+
const hours = duration.hours();
|
|
255
|
+
const minutes = duration.minutes();
|
|
256
|
+
const seconds = duration.seconds();
|
|
257
|
+
|
|
258
|
+
let result = "";
|
|
259
|
+
if (days > 0) result += `${days}天`;
|
|
260
|
+
if (hours > 0) result += `${hours}小时`;
|
|
261
|
+
if (minutes > 0) result += `${minutes}分钟`;
|
|
262
|
+
if (seconds > 0) result += `${seconds}秒`;
|
|
263
|
+
|
|
264
|
+
return result || "0秒";
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* 秒转转化为 *天*小时*分钟*秒
|
|
269
|
+
* @param seconds 秒数
|
|
270
|
+
* @returns 格式化的时长字符串
|
|
271
|
+
*/
|
|
272
|
+
export const formatSecToStr = (seconds: number): string => {
|
|
273
|
+
const daySec = 24 * 60 * 60;
|
|
274
|
+
const hourSec = 60 * 60;
|
|
275
|
+
const minuteSec = 60;
|
|
276
|
+
const dd = Math.floor(seconds / daySec);
|
|
277
|
+
const hh = Math.floor((seconds % daySec) / hourSec);
|
|
278
|
+
const mm = Math.floor((seconds % hourSec) / minuteSec);
|
|
279
|
+
const ss = seconds % minuteSec;
|
|
280
|
+
if (dd > 0) {
|
|
281
|
+
return `${dd}天${hh}小时${mm}分钟${ss}秒`;
|
|
282
|
+
}
|
|
283
|
+
if (hh > 0) {
|
|
284
|
+
return `${hh}小时${mm}分钟`;
|
|
285
|
+
}
|
|
286
|
+
if (mm > 0) {
|
|
287
|
+
return `${mm}分钟${ss}秒`;
|
|
288
|
+
}
|
|
289
|
+
return `${ss}秒`;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* 秒转时分秒
|
|
294
|
+
* @param value 秒数
|
|
295
|
+
* @returns 时分秒格式字符串(HH:mm:ss)
|
|
296
|
+
*/
|
|
297
|
+
export const formatSeconds = (value: number): string => {
|
|
298
|
+
let secondTime = value; // 秒
|
|
299
|
+
let minuteTime = 0; // 分
|
|
300
|
+
let hourTime = 0; // 小时
|
|
301
|
+
if (secondTime >= 60) {
|
|
302
|
+
minuteTime = Math.floor(secondTime / 60);
|
|
303
|
+
secondTime = secondTime % 60;
|
|
304
|
+
if (minuteTime >= 60) {
|
|
305
|
+
hourTime = Math.floor(minuteTime / 60);
|
|
306
|
+
minuteTime = minuteTime % 60;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
let result = `${secondTime < 10 ? `0${Math.floor(secondTime)}` : Math.floor(secondTime)}`;
|
|
310
|
+
|
|
311
|
+
result = `${minuteTime < 10 ? `0${minuteTime}` : minuteTime}:${result}`;
|
|
312
|
+
result = `${hourTime < 10 ? `0${hourTime}` : hourTime}:${result}`;
|
|
313
|
+
return result;
|
|
314
|
+
};
|