mirror of
https://gitee.com/HuLaSpark/HuLa.git
synced 2024-11-29 10:18:35 +08:00
refactor(view): ♻️ 重构注册页面样式和项目路由文件命名规范
This commit is contained in:
parent
bbb74ee78a
commit
d144630433
@ -119,7 +119,7 @@ import Mitt from '@/utils/Bus.ts'
|
||||
import { CacheUserItem, MockItem } from '@/services/types.ts'
|
||||
import { emit, listen } from '@tauri-apps/api/event'
|
||||
import { useSettingStore } from '@/stores/setting.ts'
|
||||
import { sendOptions } from '@/views/homeWindow/more/settings/config.ts'
|
||||
import { sendOptions } from '@/views/moreWindow/settings/config.ts'
|
||||
import { useMsgInput } from '@/hooks/useMsgInput.ts'
|
||||
import { useCommon } from '@/hooks/useCommon.ts'
|
||||
import { onKeyStroke } from '@vueuse/core'
|
||||
|
@ -4,6 +4,10 @@
|
||||
data-tauri-drag-region
|
||||
:class="osType === 'windows' ? 'flex justify-end select-none' : 'h-24px select-none w-full'">
|
||||
<template v-if="osType === 'windows'">
|
||||
<!-- 登录窗口的代理按钮 -->
|
||||
<div v-if="proxy" @click="router.push('/proxy')" class="w-30px h-24px flex-center">
|
||||
<svg class="size-16px color-[--action-bar-icon-color] cursor-pointer"><use href="#settings"></use></svg>
|
||||
</div>
|
||||
<!-- 固定在最顶层 -->
|
||||
<div v-if="topWinLabel !== void 0" @click="handleAlwaysOnTop" class="hover-box">
|
||||
<n-popover trigger="hover">
|
||||
@ -86,10 +90,12 @@ import { emit, listen } from '@tauri-apps/api/event'
|
||||
import { CloseBxEnum, EventEnum, MittEnum } from '@/enums'
|
||||
import { exit } from '@tauri-apps/plugin-process'
|
||||
import { type } from '@tauri-apps/plugin-os'
|
||||
import router from '@/router'
|
||||
|
||||
const appWindow = WebviewWindow.getCurrent()
|
||||
const {
|
||||
topWinLabel,
|
||||
proxy = false,
|
||||
minW = true,
|
||||
maxW = true,
|
||||
closeW = true,
|
||||
@ -103,6 +109,7 @@ const {
|
||||
topWinLabel?: string
|
||||
currentLabel?: string
|
||||
shrinkStatus?: boolean
|
||||
proxy?: boolean
|
||||
}>()
|
||||
const { getWindowTop, setWindowTop } = useAlwaysOnTopStore()
|
||||
const settingStore = useSettingStore()
|
||||
@ -239,10 +246,10 @@ onUnmounted(() => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.hover-box {
|
||||
@apply w-28px h24px flex-center hover:bg-[--icon-hover-color];
|
||||
@apply w-28px h-24px flex-center hover:bg-[--icon-hover-color];
|
||||
}
|
||||
.action-close {
|
||||
@apply w-28px h24px flex-center cursor-pointer hover:bg-#c22b1c svg:hover:color-[#fff];
|
||||
@apply w-28px h-24px flex-center cursor-pointer hover:bg-#c22b1c svg:hover:color-[#fff];
|
||||
}
|
||||
.n-modal {
|
||||
align-self: start;
|
||||
|
@ -3,6 +3,7 @@ import { Ref } from 'vue'
|
||||
import { createFileOrVideoDom } from '@/utils/CreateDom.ts'
|
||||
import { RegExp } from '@/utils/RegExp.ts'
|
||||
import { useSettingStore } from '@/stores/setting.ts'
|
||||
import GraphemeSplitter from 'grapheme-splitter'
|
||||
|
||||
/** 常用工具类 */
|
||||
export const useCommon = () => {
|
||||
@ -345,6 +346,12 @@ export const useCommon = () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 计算字符长度 */
|
||||
const countGraphemes = (value: string) => {
|
||||
const splitter = new GraphemeSplitter()
|
||||
return splitter.countGraphemes(value)
|
||||
}
|
||||
|
||||
/** 去除字符串中的元素标记 */
|
||||
const removeTag = (fragment: any) => new DOMParser().parseFromString(fragment, 'text/html').body.textContent || ''
|
||||
|
||||
@ -357,6 +364,7 @@ export const useCommon = () => {
|
||||
handlePaste,
|
||||
removeTag,
|
||||
FileOrVideoPaste,
|
||||
countGraphemes,
|
||||
reply,
|
||||
userUid
|
||||
}
|
||||
|
@ -37,7 +37,10 @@
|
||||
:color="'#909090'"
|
||||
:src="editInfo.content.avatar"
|
||||
round
|
||||
style="border: 3px solid #fff" />
|
||||
class="text-22px"
|
||||
style="border: 3px solid #fff">
|
||||
{{ editInfo.content.name?.slice(0, 1) }}
|
||||
</n-avatar>
|
||||
</n-flex>
|
||||
<n-flex v-if="currentBadge" align="center" justify="center">
|
||||
<span class="text-(14px #707070)">当前佩戴的徽章:</span>
|
||||
@ -60,6 +63,7 @@
|
||||
:passively-activated="true"
|
||||
class="rounded-6px"
|
||||
clearable
|
||||
:allow-input="noSideSpace"
|
||||
placeholder="请输入你的昵称"
|
||||
show-count
|
||||
type="text">
|
||||
@ -115,8 +119,13 @@ import { leftHook } from '@/layout/left/hook.ts'
|
||||
import Mitt from '@/utils/Bus.ts'
|
||||
import apis from '@/services/apis.ts'
|
||||
import { type } from '@tauri-apps/plugin-os'
|
||||
import { useCommon } from '@/hooks/useCommon.ts'
|
||||
|
||||
const { login, editInfo, currentBadge, saveEditInfo, toggleWarningBadge, countGraphemes } = leftHook()
|
||||
const { login, editInfo, currentBadge, saveEditInfo, toggleWarningBadge } = leftHook()
|
||||
const { countGraphemes } = useCommon()
|
||||
|
||||
/** 不允许输入空格 */
|
||||
const noSideSpace = (value: string) => !value.startsWith(' ') && !value.endsWith(' ')
|
||||
|
||||
onMounted(() => {
|
||||
Mitt.on(MittEnum.OPEN_EDIT_INFO, () => {
|
||||
@ -137,7 +146,7 @@ onMounted(() => {
|
||||
.badge-item {
|
||||
.tip {
|
||||
transition: opacity 0.4s ease-in-out;
|
||||
@apply absolute top-0 left-0 w-full h-full flex-center z-999 opacity-0;
|
||||
@apply absolute top-0 left-0 w-full h-full flex-center gap-4px z-999 opacity-0;
|
||||
}
|
||||
@apply bg-#ccc relative rounded-50% size-fit p-4px cursor-pointer;
|
||||
&:hover .tip {
|
||||
|
@ -18,7 +18,7 @@
|
||||
{{ avatarExists }}
|
||||
</n-avatar>
|
||||
|
||||
<n-avatar v-else :color="'#909090'" :size="34" :src="login.accountInfo.avatar" fallback-src="/logo.png" round />
|
||||
<n-avatar v-else :size="34" :src="login.accountInfo.avatar" fallback-src="/logo.png" round />
|
||||
|
||||
<div
|
||||
class="bg-[--left-bg-color] text-10px rounded-50% size-12px absolute bottom--2px right--2px border-(2px solid [--left-bg-color])"
|
||||
|
@ -11,7 +11,6 @@ import { renderReplyContent } from '@/utils/RenderReplyContent.ts'
|
||||
import { formatTimestamp } from '@/utils/ComputedTime.ts'
|
||||
import Mitt from '@/utils/Bus.ts'
|
||||
import apis from '@/services/apis.ts'
|
||||
import GraphemeSplitter from 'grapheme-splitter'
|
||||
import { delay } from 'lodash-es'
|
||||
import router from '@/router'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
@ -133,20 +132,12 @@ export const leftHook = () => {
|
||||
/** 佩戴徽章 */
|
||||
const toggleWarningBadge = async (badge: BadgeType) => {
|
||||
if (!badge?.id) return
|
||||
const res: any = await apis.setUserBadge(badge.id)
|
||||
if (res) {
|
||||
window.$message.success('佩戴成功')
|
||||
/** 获取用户信息 */
|
||||
apis.getUserInfo().then((res) => {
|
||||
editInfo.value.content = res as any
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/** 计算字符长度 */
|
||||
const countGraphemes = (value: string) => {
|
||||
const splitter = new GraphemeSplitter()
|
||||
return splitter.countGraphemes(value)
|
||||
await apis.setUserBadge(badge.id)
|
||||
window.$message.success('佩戴成功')
|
||||
/** 获取用户信息 */
|
||||
apis.getUserInfo().then((res) => {
|
||||
editInfo.value.content = res as any
|
||||
})
|
||||
}
|
||||
|
||||
/* 打开并且创建modal */
|
||||
@ -262,7 +253,6 @@ export const leftHook = () => {
|
||||
openContent,
|
||||
saveEditInfo,
|
||||
toggleWarningBadge,
|
||||
countGraphemes,
|
||||
updateCurrentUserCache,
|
||||
followOS
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<n-flex data-tauri-drag-region vertical :size="10" align="center" justify="center" class="flex flex-1">
|
||||
<!-- logo -->
|
||||
<img data-tauri-drag-region class="w-275px h-125px drop-shadow-2xl" src="@/assets/logo/hula.png" alt="" />
|
||||
<img data-tauri-drag-region class="w-275px h-125px drop-shadow-2xl" src="../../../assets/logo/hula.png" alt="" />
|
||||
|
||||
<n-flex data-tauri-drag-region vertical justify="center" :size="16" class="p-[30px_20px]">
|
||||
<p class="text-(14px [--chat-text-color])">你可以尝试使用以下功能:</p>
|
@ -11,13 +11,18 @@ const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/register',
|
||||
name: 'register',
|
||||
component: () => import('@/views/loginWindow/Register.vue')
|
||||
component: () => import('@/views/registerWindow/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/qrCode',
|
||||
name: 'qrCode',
|
||||
component: () => import('@/views/loginWindow/QRCode.vue')
|
||||
},
|
||||
{
|
||||
path: '/proxy',
|
||||
name: 'proxy',
|
||||
component: () => import('@/views/loginWindow/Proxy.vue')
|
||||
},
|
||||
{
|
||||
path: '/tray',
|
||||
name: 'tray',
|
||||
@ -53,44 +58,44 @@ const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/robot',
|
||||
name: 'robot',
|
||||
component: () => import('@/views/homeWindow/robot/index.vue'),
|
||||
component: () => import('@/plugins/robot/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/welcome',
|
||||
name: 'welcome',
|
||||
component: () => import('@/views/homeWindow/robot/views/Welcome.vue')
|
||||
component: () => import('@/plugins/robot/views/Welcome.vue')
|
||||
},
|
||||
{
|
||||
path: '/chat',
|
||||
name: 'chat',
|
||||
component: () => import('@/views/homeWindow/robot/views/Chat.vue')
|
||||
component: () => import('@/plugins/robot/views/Chat.vue')
|
||||
},
|
||||
{
|
||||
path: '/chatSettings',
|
||||
name: 'chatSettings',
|
||||
component: () => import('@/views/homeWindow/robot/views/chatSettings/index.vue')
|
||||
component: () => import('@/plugins/robot/views/chatSettings/index.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/mail',
|
||||
name: 'mail',
|
||||
component: () => import('@/views/homeWindow/Mail.vue')
|
||||
component: () => import('@/views/mailWindow/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/dynamic',
|
||||
name: 'dynamic',
|
||||
component: () => import('@/views/homeWindow/Dynamic.vue')
|
||||
component: () => import('@/plugins/dynamic/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/onlineStatus',
|
||||
name: 'onlineStatus',
|
||||
component: () => import('@/views/homeWindow/onlineStatus/index.vue')
|
||||
component: () => import('@/views/onlineStatusWindow/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
component: () => import('@/views/homeWindow/more/About.vue')
|
||||
component: () => import('@/views/aboutWindow/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/alone',
|
||||
@ -105,22 +110,22 @@ const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/settings',
|
||||
name: 'settings',
|
||||
component: () => import('@/views/homeWindow/more/settings/index.vue'),
|
||||
component: () => import('@/views/moreWindow/settings/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/general',
|
||||
name: 'general',
|
||||
component: () => import('@/views/homeWindow/more/settings/General.vue')
|
||||
component: () => import('@/views/moreWindow/settings/General.vue')
|
||||
},
|
||||
{
|
||||
path: '/loginSetting',
|
||||
name: 'loginSetting',
|
||||
component: () => import('@/views/homeWindow/more/settings/LoginSetting.vue')
|
||||
component: () => import('@/views/moreWindow/settings/LoginSetting.vue')
|
||||
},
|
||||
{
|
||||
path: '/versatile',
|
||||
name: 'versatile',
|
||||
component: () => import('@/views/homeWindow/more/settings/Versatile.vue')
|
||||
component: () => import('@/views/moreWindow/settings/Versatile.vue')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { useSettingStore } from '@/stores/setting.ts'
|
||||
import Http, { HttpParams } from './http.ts'
|
||||
import { ServiceResponse } from '@/services/types.ts'
|
||||
|
||||
@ -29,16 +28,8 @@ const responseInterceptor = async <T>(
|
||||
body: any,
|
||||
abort?: AbortController
|
||||
): Promise<T> => {
|
||||
const token = useSettingStore().login.accountInfo.token
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
|
||||
let httpParams: HttpParams = {
|
||||
method,
|
||||
headers
|
||||
method
|
||||
}
|
||||
|
||||
if (method === 'GET') {
|
||||
|
@ -188,7 +188,8 @@ export const useChatStore = defineStore('chat', () => {
|
||||
sessionOptions.isLoading = true
|
||||
const response = await apis
|
||||
.getSessionList({
|
||||
pageSize: sessionList.length > pageSize ? sessionList.length : pageSize
|
||||
pageSize: sessionList.length > pageSize ? sessionList.length : pageSize,
|
||||
cursor: isFresh || !sessionOptions.cursor ? '' : sessionOptions.cursor
|
||||
})
|
||||
.catch(() => {
|
||||
sessionOptions.isLoading = false
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { StoresEnum } from '@/enums'
|
||||
import { statusItem } from '@/views/homeWindow/onlineStatus/config.ts'
|
||||
import { statusItem } from '@/views/onlineStatusWindow/config.ts'
|
||||
import Colorthief from 'colorthief'
|
||||
|
||||
const colorthief = new Colorthief()
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { CloseBxEnum, StoresEnum, ShowModeEnum, ThemeEnum } from '@/enums'
|
||||
import apis from '@/services/apis.ts'
|
||||
import { isDiffNow10Min } from '@/utils/ComputedTime.ts'
|
||||
import type { CacheBadgeItem } from '@/services/types.ts'
|
||||
|
||||
const badgeCachedList = reactive<Record<number, Partial<CacheBadgeItem>>>({})
|
||||
// TODO 使用indexDB或sqlite缓存数据,还需要根据每个账号来进行配置 (nyh -> 2024-03-26 01:22:12)
|
||||
export const useSettingStore = defineStore(StoresEnum.SETTING, {
|
||||
state: (): STO.Setting => ({
|
||||
@ -74,27 +70,6 @@ export const useSettingStore = defineStore(StoresEnum.SETTING, {
|
||||
setAccountInfo(accountInfo: STO.Setting['login']['accountInfo']) {
|
||||
this.login.accountInfo = accountInfo
|
||||
},
|
||||
/** 批量获取用户徽章详细信息 */
|
||||
async getBatchBadgeInfo(itemIds: number[]) {
|
||||
// 没有 lastModifyTime 的要更新,lastModifyTime 距离现在 10 分钟已上的也要更新
|
||||
const result = itemIds
|
||||
.map((itemId) => {
|
||||
const cacheBadge = badgeCachedList[itemId]
|
||||
return { itemId, lastModifyTime: cacheBadge?.lastModifyTime }
|
||||
})
|
||||
.filter((item) => !item.lastModifyTime || isDiffNow10Min(item.lastModifyTime))
|
||||
if (!result.length) return
|
||||
const data = await apis.getBadgesBatch(result)
|
||||
data?.forEach(
|
||||
(item: CacheBadgeItem) =>
|
||||
// 更新最后更新时间。
|
||||
(badgeCachedList[item.itemId] = {
|
||||
...(item?.needRefresh ? item : badgeCachedList[item.itemId]),
|
||||
needRefresh: void 0,
|
||||
lastModifyTime: Date.now()
|
||||
})
|
||||
)
|
||||
},
|
||||
/** 清空账号信息 */
|
||||
clearAccount() {
|
||||
this.login.accountInfo.password = ''
|
||||
|
@ -17,7 +17,7 @@ const task = () => {
|
||||
request?.abort()
|
||||
if (queue.size > 0) {
|
||||
// 开始新请求
|
||||
request = apis.getMsgReadCount({ params: { msgIds: [...queue] } })
|
||||
request = apis.getMsgReadCount({ msgIds: [...queue] })
|
||||
request.send().then((res: MsgReadUnReadCountType[]) => {
|
||||
const result = new Map<number, MsgReadUnReadCountType>()
|
||||
res.forEach((item) => result.set(item.msgId, item))
|
||||
|
@ -51,7 +51,7 @@
|
||||
import { useWindow } from '@/hooks/useWindow.ts'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { exit } from '@tauri-apps/plugin-process'
|
||||
import { statusItem } from '@/views/homeWindow/onlineStatus/config.ts'
|
||||
import { statusItem } from '@/views/onlineStatusWindow/config.ts'
|
||||
import { onlineStatus } from '@/stores/onlineStatus.ts'
|
||||
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
|
@ -5,13 +5,13 @@
|
||||
<n-flex vertical align="center" :size="20" class="size-full pt-100px" data-tauri-drag-region>
|
||||
<div @mousemove="handleMouseMove" @mouseleave="handleMouseLeave" class="box" data-tauri-drag-region>
|
||||
<div id="computer" class="computer">
|
||||
<img class="w-224px h-158px relative" src="@/assets/img/win.png" alt="" />
|
||||
<img class="w-224px h-158px relative" src="../../assets/img/win.png" alt="" />
|
||||
<div
|
||||
style="background: rgba(111, 111, 111, 0.1)"
|
||||
class="w-170px h-113px absolute top-9% left-51% transform -translate-x-51% -translate-y-9%"></div>
|
||||
<img
|
||||
class="drop-shadow-md absolute top-30% left-1/2 transform -translate-x-1/2 -translate-y-30% w-140px h-60px"
|
||||
src="@/assets/logo/hula.png"
|
||||
src="../../assets/logo/hula.png"
|
||||
alt="" />
|
||||
</div>
|
||||
</div>
|
@ -1,22 +1,25 @@
|
||||
<template>
|
||||
<!-- todo 这里设置了 data-tauri-drag-region但是有部分区域不可以拖动 -->
|
||||
<!-- 单独使用n-config-provider来包裹不需要主题切换的界面 -->
|
||||
<n-config-provider :theme="lightTheme" data-tauri-drag-region class="login-box size-full rounded-8px select-none">
|
||||
<!--顶部操作栏-->
|
||||
<ActionBar :max-w="false" :shrink="false" />
|
||||
<ActionBar :max-w="false" :shrink="false" proxy />
|
||||
|
||||
<!-- 手动登录样式 -->
|
||||
<n-flex vertical :size="25" v-if="!login.autoLogin || !login.accountInfo.token" data-tauri-drag-region>
|
||||
<n-flex vertical :size="25" v-if="!login.autoLogin || !login.accountInfo.token">
|
||||
<!-- 头像 -->
|
||||
<n-flex justify="center" class="w-full pt-35px" data-tauri-drag-region>
|
||||
<img
|
||||
class="w-80px h-80px rounded-50% bg-#b6d6d9ff border-(2px solid #fff)"
|
||||
:src="info.avatar || '/logo.png'"
|
||||
alt="" />
|
||||
<n-avatar
|
||||
v-if="info.avatar"
|
||||
class="size-80px rounded-50% bg-#b6d6d9ff border-(2px solid #fff)"
|
||||
:src="info.avatar || '/logo.png'" />
|
||||
|
||||
<n-avatar v-else class="size-80px text-20px rounded-50% bg-#b6d6d9ff border-(2px solid #fff)">
|
||||
{{ info.name.slice(0, 1) }}
|
||||
</n-avatar>
|
||||
</n-flex>
|
||||
|
||||
<!-- 登录菜单 -->
|
||||
<n-flex class="ma text-center h-full w-260px" vertical :size="16" data-tauri-drag-region>
|
||||
<n-flex class="ma text-center h-full w-260px" vertical :size="16">
|
||||
<n-input
|
||||
style="padding-left: 20px"
|
||||
size="large"
|
||||
@ -38,7 +41,7 @@
|
||||
</template>
|
||||
</n-input>
|
||||
|
||||
<!-- 账号选择框 TODO 尝试使用n-popover组件来实现这个功能 (nyh -> 2024-03-09 02:56:06)-->
|
||||
<!-- 账号选择框-->
|
||||
<div
|
||||
style="border: 1px solid rgba(70, 70, 70, 0.1)"
|
||||
v-if="loginHistories.length > 0 && arrowStatus"
|
||||
@ -51,7 +54,10 @@
|
||||
@click="giveAccount(item)"
|
||||
class="p-8px cursor-pointer hover:bg-#f3f3f3 hover:rounded-6px">
|
||||
<div class="flex-between-center">
|
||||
<img :src="item.avatar" class="w-28px h-28px bg-#ccc rounded-50%" alt="" />
|
||||
<n-avatar v-if="item.avatar" :src="item.avatar" class="size-28px bg-#ccc rounded-50%" />
|
||||
<n-avatar v-else :src="item.avatar" :color="'#909090'" class="size-28px text-10px bg-#ccc rounded-50%">
|
||||
{{ item.name.slice(0, 1) }}
|
||||
</n-avatar>
|
||||
<p class="text-14px color-#505050">{{ item.account }}</p>
|
||||
<svg @click.stop="delAccount(item)" class="w-12px h-12px">
|
||||
<use href="#close"></use>
|
||||
@ -128,18 +134,24 @@
|
||||
</n-flex>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<n-flex justify="center" class="text-14px" id="bottomBar" data-tauri-drag-region>
|
||||
<n-flex justify="center" class="text-14px" id="bottomBar">
|
||||
<div class="color-#13987f cursor-pointer" @click="router.push('/qrCode')">扫码登录</div>
|
||||
<div class="w-1px h-14px bg-#ccc"></div>
|
||||
<div v-if="login.autoLogin" class="color-#13987f cursor-pointer" @click="removeToken">移除账号</div>
|
||||
<n-popover v-else trigger="click" :show-checkmark="false" :show-arrow="false">
|
||||
<n-popover
|
||||
v-else
|
||||
trigger="click"
|
||||
id="moreShow"
|
||||
v-model:show="moreShow"
|
||||
:show-checkmark="false"
|
||||
:show-arrow="false">
|
||||
<template #trigger>
|
||||
<div class="color-#13987f cursor-pointer">更多选项</div>
|
||||
</template>
|
||||
<n-flex vertical :size="2">
|
||||
<div
|
||||
class="text-14px cursor-pointer hover:bg-#f3f3f3 hover:rounded-6px p-8px"
|
||||
@click="router.push('/register')">
|
||||
@click="createWebviewWindow('注册', 'register', 600, 600)">
|
||||
注册账号
|
||||
</div>
|
||||
<div class="text-14px cursor-pointer hover:bg-#f3f3f3 hover:rounded-6px p-8px">忘记密码</div>
|
||||
@ -185,6 +197,7 @@ const protocol = ref(true)
|
||||
const loginDisabled = ref(false)
|
||||
const loading = ref(false)
|
||||
const arrowStatus = ref(false)
|
||||
const moreShow = ref(false)
|
||||
const { setLoginState } = useLogin()
|
||||
const accountPH = ref('输入HuLa账号')
|
||||
const passwordPH = ref('输入HuLa密码')
|
||||
@ -239,8 +252,9 @@ const normalLogin = async () => {
|
||||
apis
|
||||
.login({ ...info.value } as unknown as User)
|
||||
.then(async (token) => {
|
||||
loginText.value = '登录成功, 正在跳转'
|
||||
if (interruptLogin.value) return
|
||||
loginDisabled.value = true
|
||||
loginText.value = '登录成功, 正在跳转'
|
||||
userStore.isSign = true
|
||||
login.value.accountInfo.token = token
|
||||
// localStorage.setItem('USER_INFO', JSON.stringify(rest))
|
||||
@ -315,17 +329,7 @@ const autoLogin = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const closeMenu = (event: MouseEvent) => {
|
||||
const target = event.target as Element
|
||||
if (!target.matches('.account-box, .account-box *, .down')) {
|
||||
arrowStatus.value = false
|
||||
}
|
||||
if (target.matches('#bottomBar *') && login.value.autoLogin) {
|
||||
interruptLogin.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// 移除已登录账号
|
||||
/** 移除已登录账号 */
|
||||
const removeToken = () => {
|
||||
login.value.accountInfo = {
|
||||
account: '',
|
||||
@ -338,6 +342,19 @@ const removeToken = () => {
|
||||
login.value.autoLogin = false
|
||||
}
|
||||
|
||||
const closeMenu = (event: MouseEvent) => {
|
||||
const target = event.target as Element
|
||||
if (!target.matches('.account-box, .account-box *, .down')) {
|
||||
arrowStatus.value = false
|
||||
}
|
||||
if (target.matches('#bottomBar *') && login.value.autoLogin) {
|
||||
interruptLogin.value = true
|
||||
}
|
||||
if (!target.matches('#moreShow')) {
|
||||
moreShow.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const enterKey = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
normalLogin()
|
||||
|
23
src/views/loginWindow/Proxy.vue
Normal file
23
src/views/loginWindow/Proxy.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<n-config-provider :theme="lightTheme" data-tauri-drag-region class="login-box size-full rounded-8px select-none">
|
||||
<!--顶部操作栏-->
|
||||
<ActionBar :max-w="false" :shrink="false" proxy data-tauri-drag-region />
|
||||
|
||||
<n-flex vertical :size="25" align="center" class="pt-30px">
|
||||
<span class="text-(16px #70938c) font-bold textFont">网络代理设置</span>
|
||||
<p>敬请期待</p>
|
||||
<p @click="router.push('/login')" class="text-(14px #13987f) cursor-pointer">返回</p>
|
||||
</n-flex>
|
||||
</n-config-provider>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { lightTheme } from 'naive-ui'
|
||||
import router from '@/router'
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '@/styles/scss/global/login-bg';
|
||||
.textFont {
|
||||
font-family: AliFangYuan, sans-serif !important;
|
||||
}
|
||||
</style>
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<n-config-provider :theme="lightTheme" data-tauri-drag-region class="login-box size-full rounded-8px select-none">
|
||||
<!--顶部操作栏-->
|
||||
<ActionBar :max-w="false" :shrink="false" data-tauri-drag-region />
|
||||
<ActionBar :max-w="false" :shrink="false" proxy data-tauri-drag-region />
|
||||
|
||||
<n-flex justify="center" class="mt-15px" data-tauri-drag-region>
|
||||
<img src="@/assets/logo/hula.png" class="w-140px h-60px drop-shadow-xl" alt="" data-tauri-drag-region />
|
||||
@ -36,7 +36,9 @@
|
||||
<n-flex justify="center" class="text-14px mt-48px" data-tauri-drag-region>
|
||||
<div class="color-#13987f cursor-pointer" @click="router.push('/login')">账密登录</div>
|
||||
<div class="w-1px h-14px bg-#ccc"></div>
|
||||
<div class="color-#13987f cursor-pointer" @click="router.push('/register')">注册账号</div>
|
||||
<div class="color-#13987f cursor-pointer" @click="createWebviewWindow('注册', 'register', 600, 600)">
|
||||
注册账号
|
||||
</div>
|
||||
</n-flex>
|
||||
</n-config-provider>
|
||||
</template>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<p class="text-(12px #13987f) cursor-pointer">GitHub 给添加星标</p>
|
||||
</template>
|
||||
<n-flex vertical class="w-360px h-fit">
|
||||
<video class="w-full h-240px rounded-t-8px object-cover" src="@/assets/video/star.mp4" autoplay loop />
|
||||
<video class="w-full h-240px rounded-t-8px object-cover" src="../../../assets/video/star.mp4" autoplay loop />
|
||||
<n-flex vertical :size="10" class="p-14px">
|
||||
<p class="text-(16px [--text-color] font-bold)">在 GitHub 为我们点亮星标</p>
|
||||
<p class="text-(12px [--chat-text-color]) leading-5">
|
||||
@ -40,7 +40,11 @@
|
||||
<p class="text-(12px #13987f) cursor-pointer">分享您宝贵的建议</p>
|
||||
</template>
|
||||
<n-flex vertical class="w-360px h-fit">
|
||||
<video class="w-full h-240px rounded-t-8px object-cover" src="@/assets/video/issue.mp4" autoplay loop />
|
||||
<video
|
||||
class="w-full h-240px rounded-t-8px object-cover"
|
||||
src="../../../assets/video/issue.mp4"
|
||||
autoplay
|
||||
loop />
|
||||
<n-flex vertical :size="10" class="p-14px">
|
||||
<p class="text-(16px [--text-color] font-bold)">在 GitHub 分享您宝贵的反馈</p>
|
||||
<p class="text-(12px [--chat-text-color]) leading-5">
|
@ -27,7 +27,7 @@
|
||||
@click="handleVersatile('simple')"
|
||||
:class="{ 'outline outline-2 outline-[--border-active-color] outline-offset': themes.versatile === 'simple' }"
|
||||
class="w-108px h-84px flex-col-center gap-10px cursor-pointer rounded-8px bg-#f1f1f1">
|
||||
<img class="size-34px" src="@/assets/img/hula_bg_l.png" alt="" />
|
||||
<img class="size-34px" src="../../../assets/img/hula_bg_l.png" alt="" />
|
||||
<p class="text-(12px [--chat-text-color])">极简素雅</p>
|
||||
</div>
|
||||
</n-flex>
|
@ -62,7 +62,7 @@
|
||||
import router from '@/router'
|
||||
import { sideOptions } from './config.ts'
|
||||
import { useSettingStore } from '@/stores/setting.ts'
|
||||
import Foot from '@/views/homeWindow/more/settings/Foot.vue'
|
||||
import Foot from '@/views/moreWindow/settings/Foot.vue'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
@ -93,7 +93,7 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '@/styles/scss/global/variable.scss' as *;
|
||||
@use '@/styles/scss/global/variable' as *;
|
||||
.left-bar {
|
||||
@include menu-list();
|
||||
background: var(--bg-left-menu);
|
@ -4,21 +4,21 @@
|
||||
<!--顶部操作栏-->
|
||||
<ActionBar :max-w="false" :shrink="false" />
|
||||
|
||||
<!-- 手动登录样式 -->
|
||||
<n-flex vertical :size="25" data-tauri-drag-region>
|
||||
<!-- 头像 -->
|
||||
<n-flex justify="center" class="w-full pt-20px" data-tauri-drag-region>
|
||||
<img class="w-32px h-32px rounded-50% bg-#b6d6d9ff border-(2px solid #fff)" src="/logo.png" alt="" />
|
||||
<n-flex vertical :size="25" class="pt-80px">
|
||||
<n-flex justify="center" align="center">
|
||||
<span class="text-(24px #70938c) font-bold textFont">欢迎注册</span>
|
||||
<img class="w-100px h-40px" src="@/assets/logo/hula.png" alt="" />
|
||||
</n-flex>
|
||||
|
||||
<!-- 登录菜单 -->
|
||||
<n-flex class="ma text-center h-full w-260px" vertical :size="16" data-tauri-drag-region>
|
||||
<!-- 注册菜单 -->
|
||||
<n-flex class="ma text-center h-full w-260px" vertical :size="16">
|
||||
<n-input
|
||||
maxlength="16"
|
||||
minlength="6"
|
||||
maxlength="8"
|
||||
minlength="1"
|
||||
size="large"
|
||||
v-model:value="info.name"
|
||||
type="text"
|
||||
:allow-input="noSideSpace"
|
||||
:placeholder="namePH"
|
||||
@focus="namePH = ''"
|
||||
@blur="namePH = '输入HuLa昵称'"
|
||||
@ -26,10 +26,11 @@
|
||||
|
||||
<n-input
|
||||
size="large"
|
||||
maxlength="16"
|
||||
maxlength="12"
|
||||
minlength="6"
|
||||
v-model:value="info.account"
|
||||
type="text"
|
||||
:allow-input="noSideSpace"
|
||||
:placeholder="accountPH"
|
||||
@focus="accountPH = ''"
|
||||
@blur="accountPH = '输入HuLa账号'"
|
||||
@ -42,6 +43,7 @@
|
||||
size="large"
|
||||
v-model:value="info.password"
|
||||
type="password"
|
||||
:allow-input="noSideSpace"
|
||||
:placeholder="passwordPH"
|
||||
@focus="passwordPH = ''"
|
||||
@blur="passwordPH = '输入HuLa密码'"
|
||||
@ -69,18 +71,17 @@
|
||||
</n-flex>
|
||||
</n-flex>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<n-flex justify="center" class="text-14px" id="bottomBar" data-tauri-drag-region>
|
||||
<div class="color-#13987f cursor-pointer" @click="router.push('/login')">账号登录</div>
|
||||
<div class="w-1px h-14px bg-#ccc"></div>
|
||||
<div class="color-#13987f cursor-pointer" @click="router.push('/qrCode')">扫码登录</div>
|
||||
<!-- 底部栏 -->
|
||||
<n-flex class="text-(12px #909090)" :size="8" justify="center">
|
||||
<span>Copyright © {{ currentYear - 1 }}-{{ currentYear }} HuLaSpark All Rights Reserved.</span>
|
||||
</n-flex>
|
||||
</n-config-provider>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import router from '@/router'
|
||||
import { lightTheme } from 'naive-ui'
|
||||
import apis from '@/services/apis.ts'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
/** 账号信息 */
|
||||
const info = ref({
|
||||
@ -88,8 +89,6 @@ const info = ref({
|
||||
password: '',
|
||||
name: ''
|
||||
})
|
||||
/** 是否中断登录 */
|
||||
const interruptLogin = ref(false)
|
||||
/** 协议 */
|
||||
const protocol = ref(true)
|
||||
const btnEnable = ref(false)
|
||||
@ -99,9 +98,14 @@ const accountPH = ref('输入HuLa账号')
|
||||
const passwordPH = ref('输入HuLa密码')
|
||||
/** 登录按钮的文本内容 */
|
||||
const btnText = ref('注册')
|
||||
// 使用day.js获取当前年份
|
||||
const currentYear = dayjs().year()
|
||||
|
||||
/** 不允许输入空格 */
|
||||
const noSideSpace = (value: string) => !value.startsWith(' ') && !value.endsWith(' ')
|
||||
|
||||
const register = async () => {
|
||||
interruptLogin.value = true
|
||||
btnEnable.value = true
|
||||
loading.value = true
|
||||
btnText.value = '注册中...'
|
||||
// 注册
|
||||
@ -113,19 +117,18 @@ const register = async () => {
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
interruptLogin.value = false
|
||||
btnEnable.value = false
|
||||
btnText.value = '注册'
|
||||
})
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
btnEnable.value = !(info.value.account && info.value.password && protocol.value)
|
||||
if (interruptLogin.value) {
|
||||
btnEnable.value = false
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {})
|
||||
onMounted(async () => {
|
||||
await getCurrentWebviewWindow().show()
|
||||
})
|
||||
|
||||
onUnmounted(() => {})
|
||||
</script>
|
||||
@ -133,4 +136,8 @@ onUnmounted(() => {})
|
||||
<style scoped lang="scss">
|
||||
@use '@/styles/scss/global/login-bg';
|
||||
@use '@/styles/scss/login';
|
||||
|
||||
.textFont {
|
||||
font-family: AliFangYuan, sans-serif !important;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user