@flecblog/core-nuxt 0.1.0 → 0.1.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.
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 邮箱绑定弹窗状态管理
|
|
3
|
+
*/
|
|
4
|
+
export function useBindEmail() {
|
|
5
|
+
const showBindEmailModal = useState<boolean>('showBindEmailModal', () => false)
|
|
6
|
+
const hasTriggeredGlobal = useState<boolean>('hasTriggeredGlobalBindEmail', () => false)
|
|
7
|
+
|
|
8
|
+
const openBindEmailModal = () => {
|
|
9
|
+
showBindEmailModal.value = true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const closeBindEmailModal = () => {
|
|
13
|
+
showBindEmailModal.value = false
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 全局触发邮箱绑定提示(路由切换时调用,但只触发一次)
|
|
18
|
+
*/
|
|
19
|
+
const triggerGlobal = () => {
|
|
20
|
+
// 如果已经触发过全局提示,不再重复触发
|
|
21
|
+
if (hasTriggeredGlobal.value) return
|
|
22
|
+
|
|
23
|
+
const { isLoggedIn, user } = useAuth()
|
|
24
|
+
|
|
25
|
+
// 仅在用户已登录但未绑定邮箱时触发
|
|
26
|
+
if (isLoggedIn.value && user.value && !user.value.email) {
|
|
27
|
+
openBindEmailModal()
|
|
28
|
+
hasTriggeredGlobal.value = true
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 绑定成功后的回调
|
|
34
|
+
*/
|
|
35
|
+
const onBindSuccess = () => {
|
|
36
|
+
closeBindEmailModal()
|
|
37
|
+
// 刷新用户信息
|
|
38
|
+
const { refreshUser } = useAuth()
|
|
39
|
+
refreshUser()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
showBindEmailModal,
|
|
44
|
+
openBindEmailModal,
|
|
45
|
+
closeBindEmailModal,
|
|
46
|
+
triggerGlobal,
|
|
47
|
+
onBindSuccess,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 登录弹窗状态管理
|
|
3
|
+
*/
|
|
4
|
+
export function useLoginModal() {
|
|
5
|
+
const showLoginModal = useState<boolean>('showLoginModal', () => false)
|
|
6
|
+
|
|
7
|
+
const openLoginModal = () => {
|
|
8
|
+
showLoginModal.value = true
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const closeLoginModal = () => {
|
|
12
|
+
showLoginModal.value = false
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
showLoginModal,
|
|
17
|
+
openLoginModal,
|
|
18
|
+
closeLoginModal,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
// Toast 类型
|
|
4
|
+
type ToastType = 'success' | 'error' | 'warning' | 'info';
|
|
5
|
+
|
|
6
|
+
// 内部状态接口
|
|
7
|
+
interface ToastItem {
|
|
8
|
+
id: number;
|
|
9
|
+
message: string;
|
|
10
|
+
type: ToastType;
|
|
11
|
+
show: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 全局状态
|
|
15
|
+
const toasts = ref<ToastItem[]>([]);
|
|
16
|
+
let nextId = 1;
|
|
17
|
+
|
|
18
|
+
// 默认持续时间配置
|
|
19
|
+
const DEFAULT_DURATION: Record<ToastType, number> = {
|
|
20
|
+
success: 3000,
|
|
21
|
+
error: 4000,
|
|
22
|
+
warning: 3500,
|
|
23
|
+
info: 3000,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Toast 消息提示
|
|
28
|
+
*/
|
|
29
|
+
export function useToast() {
|
|
30
|
+
const show = (message: string, type: ToastType = 'info', duration?: number) => {
|
|
31
|
+
const id = nextId++;
|
|
32
|
+
const toast: ToastItem = { id, message, type, show: true };
|
|
33
|
+
|
|
34
|
+
toasts.value.push(toast);
|
|
35
|
+
|
|
36
|
+
// 自动移除
|
|
37
|
+
const delay = duration ?? DEFAULT_DURATION[type];
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
const index = toasts.value.findIndex(t => t.id === id);
|
|
40
|
+
if (index > -1 && toasts.value[index]) {
|
|
41
|
+
toasts.value[index]!.show = false;
|
|
42
|
+
setTimeout(() => toasts.value.splice(index, 1), 300);
|
|
43
|
+
}
|
|
44
|
+
}, delay);
|
|
45
|
+
|
|
46
|
+
return id;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// 便捷方法
|
|
50
|
+
const success = (message: string, duration?: number) => show(message, 'success', duration);
|
|
51
|
+
const error = (message: string, duration?: number) => show(message, 'error', duration);
|
|
52
|
+
const warning = (message: string, duration?: number) => show(message, 'warning', duration);
|
|
53
|
+
const info = (message: string, duration?: number) => show(message, 'info', duration);
|
|
54
|
+
|
|
55
|
+
return { toasts, success, error, warning, info };
|
|
56
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flecblog/core-nuxt",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "FlecBlog Nuxt Layer(共享核心)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./nuxt.config.ts",
|
|
@@ -18,13 +18,8 @@
|
|
|
18
18
|
"types"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@nuxt/image": "^2.0.0",
|
|
22
|
-
"@nuxtjs/critters": "^0.9.0",
|
|
23
|
-
"@nuxtjs/seo": "^5.1.3",
|
|
24
21
|
"@traptitech/markdown-it-katex": "^3.6.0",
|
|
25
|
-
"@vite-pwa/nuxt": "^1.1.1",
|
|
26
22
|
"@vueuse/core": "^14.2.1",
|
|
27
|
-
"@vueuse/nuxt": "^14.2.1",
|
|
28
23
|
"dayjs": "^1.11.19",
|
|
29
24
|
"dompurify": "^3.3.1",
|
|
30
25
|
"highlight.js": "^11.11.1",
|
|
@@ -49,6 +44,11 @@
|
|
|
49
44
|
"typescript": "^5.9.3"
|
|
50
45
|
},
|
|
51
46
|
"peerDependencies": {
|
|
47
|
+
"@nuxt/image": "^2.0.0",
|
|
48
|
+
"@nuxtjs/critters": "^0.9.0",
|
|
49
|
+
"@nuxtjs/seo": "^5.1.3",
|
|
50
|
+
"@vite-pwa/nuxt": "^1.1.1",
|
|
51
|
+
"@vueuse/nuxt": "^14.2.1",
|
|
52
52
|
"nuxt": "^4.3.0",
|
|
53
53
|
"vue": "^3.5.0"
|
|
54
54
|
},
|