diff --git a/package.json b/package.json index cf7142a3..e6e33e39 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "mitt": "^3.0.1", "nprogress": "^0.2.0", "pinia": "^2.1.7", + "pinia-plugin-persist": "^1.0.0", "qrcode": "^1.5.3", "qs": "^6.11.2", "steady-xml": "^0.1.0", diff --git a/src/assets/imgs/avatar.jpg b/src/assets/imgs/avatar.jpg new file mode 100644 index 00000000..d46a70a4 Binary files /dev/null and b/src/assets/imgs/avatar.jpg differ diff --git a/src/components/Editor/src/Editor.vue b/src/components/Editor/src/Editor.vue index ec40bca2..fd31bcd2 100644 --- a/src/components/Editor/src/Editor.vue +++ b/src/components/Editor/src/Editor.vue @@ -185,7 +185,7 @@ defineExpose({ userStore.user.avatar ?? avatarImg) const userName = computed(() => userStore.user.nickname ?? 'Admin') +// 锁定屏幕 +const lockStore = useLockStore() +const getIsLock = computed(() => lockStore.getLockInfo?.isLock ?? false) +const dialogVisible = ref(false) +const lockScreen = () => { + dialogVisible.value = true +} + const loginOut = async () => { try { await ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), { @@ -33,8 +44,7 @@ const loginOut = async () => { await userStore.loginOut() tagsViewStore.delAllViews() replace('/login?redirect=/index') - } - catch { } + } catch {} } const toProfile = async () => { push('/user/profile') @@ -62,6 +72,10 @@ const toDocument = () => {
{{ t('common.document') }}
+ + +
{{ t('lock.lockScreen') }}
+
{{ t('common.loginOut') }}
@@ -69,4 +83,31 @@ const toDocument = () => { + + + + + + + + + + diff --git a/src/layout/components/UserInfo/src/components/LockDialog.vue b/src/layout/components/UserInfo/src/components/LockDialog.vue new file mode 100644 index 00000000..f4ab7d4f --- /dev/null +++ b/src/layout/components/UserInfo/src/components/LockDialog.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/layout/components/UserInfo/src/components/LockPage.vue b/src/layout/components/UserInfo/src/components/LockPage.vue new file mode 100644 index 00000000..0e153e7e --- /dev/null +++ b/src/layout/components/UserInfo/src/components/LockPage.vue @@ -0,0 +1,272 @@ + + + + + diff --git a/src/layout/components/UserInfo/src/components/useNow.ts b/src/layout/components/UserInfo/src/components/useNow.ts new file mode 100644 index 00000000..10795965 --- /dev/null +++ b/src/layout/components/UserInfo/src/components/useNow.ts @@ -0,0 +1,60 @@ +import { dateUtil } from '@/utils/dateUtil' +import { reactive, toRefs } from 'vue' +import { tryOnMounted, tryOnUnmounted } from '@vueuse/core' + +export function useNow(immediate = true) { + let timer: IntervalHandle + + const state = reactive({ + year: 0, + month: 0, + week: '', + day: 0, + hour: '', + minute: '', + second: 0, + meridiem: '' + }) + + const update = () => { + const now = dateUtil() + + const h = now.format('HH') + const m = now.format('mm') + const s = now.get('s') + + state.year = now.get('y') + state.month = now.get('M') + 1 + state.week = '星期' + ['日', '一', '二', '三', '四', '五', '六'][now.day()] + state.day = now.get('date') + state.hour = h + state.minute = m + state.second = s + + state.meridiem = now.format('A') + } + + function start() { + update() + clearInterval(timer) + timer = setInterval(() => update(), 1000) + } + + function stop() { + clearInterval(timer) + } + + tryOnMounted(() => { + immediate && start() + }) + + tryOnUnmounted(() => { + stop() + }) + + return { + ...toRefs(state), + start, + stop + } +} diff --git a/src/locales/en.ts b/src/locales/en.ts index 4f4d4895..6562c9b7 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -56,6 +56,16 @@ export default { copySuccess: 'Copy Success', copyError: 'Copy Error' }, + lock: { + lockScreen: 'Lock screen', + lock: 'Lock', + lockPassword: 'Lock screen password', + unlock: 'Click to unlock', + backToLogin: 'Back to login', + entrySystem: 'Entry the system', + placeholder: 'Please enter the lock screen password', + message: 'Lock screen password error' + }, error: { noPermission: `Sorry, you don't have permission to access this page.`, pageError: 'Sorry, the page you visited does not exist.', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 6346a3d3..0721651d 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -56,6 +56,16 @@ export default { copySuccess: '复制成功', copyError: '复制失败' }, + lock: { + lockScreen: '锁定屏幕', + lock: '锁定', + lockPassword: '锁屏密码', + unlock: '点击解锁', + backToLogin: '返回登录', + entrySystem: '进入系统', + placeholder: '请输入锁屏密码', + message: '锁屏密码错误' + }, error: { noPermission: `抱歉,您无权访问此页面。`, pageError: '抱歉,您访问的页面不存在。', diff --git a/src/store/index.ts b/src/store/index.ts index 65964ea8..7740bdd3 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,7 +1,9 @@ import type { App } from 'vue' import { createPinia } from 'pinia' +import piniaPersist from 'pinia-plugin-persist' const store = createPinia() +store.use(piniaPersist) export const setupStore = (app: App) => { app.use(store) diff --git a/src/store/modules/lock.ts b/src/store/modules/lock.ts new file mode 100644 index 00000000..bf6ceb49 --- /dev/null +++ b/src/store/modules/lock.ts @@ -0,0 +1,52 @@ +import { defineStore } from 'pinia' +import { store } from '@/store' + +interface lockInfo { + isLock?: boolean + password?: string +} + +interface LockState { + lockInfo: lockInfo +} + +// TODO 芋艿:【锁屏】这里有报错,后续解决下 +export const useLockStore = defineStore('lock', { + state: (): LockState => { + return { + lockInfo: { + // isLock: false, // 是否锁定屏幕 + // password: '' // 锁屏密码 + } + } + }, + getters: { + getLockInfo(): lockInfo { + return this.lockInfo + } + }, + actions: { + setLockInfo(lockInfo: lockInfo) { + this.lockInfo = lockInfo + }, + resetLockInfo() { + this.lockInfo = {} + }, + unLock(password: string) { + if (this.lockInfo?.password === password) { + this.resetLockInfo() + return true + } else { + return false + } + } + }, + persist: { + enabled: true, + strategies: [{ key: 'lock', storage: localStorage }] + } +}) + +export const useLockStoreWithOut = () => { + return useLockStore(store) +} diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts new file mode 100644 index 00000000..316b870b --- /dev/null +++ b/src/utils/dateUtil.ts @@ -0,0 +1,18 @@ +/** + * Independent time operation tool to facilitate subsequent switch to dayjs + */ +// TODO 芋艿:【锁屏】可能后面删除掉 +import dayjs from 'dayjs' + +const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss' +const DATE_FORMAT = 'YYYY-MM-DD' + +export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FORMAT): string { + return dayjs(date).format(format) +} + +export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string { + return dayjs(date).format(format) +} + +export const dateUtil = dayjs diff --git a/types/global.d.ts b/types/global.d.ts index 5e292687..e91e1fe4 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -14,6 +14,9 @@ declare global { type LocaleType = 'zh-CN' | 'en' + declare type TimeoutHandle = ReturnType + declare type IntervalHandle = ReturnType + type AxiosHeaders = | 'application/json' | 'application/x-www-form-urlencoded'