修复问题0-60
This commit is contained in:
parent
ed54cb1f97
commit
230ea69786
|
@ -19,6 +19,7 @@ import useRouterStore from './useRouterStore'
|
|||
import BackupRecovery from './user/BackupRecovery'
|
||||
import { ConfigProvider } from 'ant-design-vue'
|
||||
import zhCN from 'ant-design-vue/es/locale/zh_CN'
|
||||
import ModalPgae from './layout/grid/ModalPgae'
|
||||
const Grid = asyncLoader(() => import('./layout/grid'))
|
||||
const Fox = asyncLoader(() => import('./fox'))
|
||||
const settings = useSettingsStore()
|
||||
|
@ -30,7 +31,7 @@ const router = useRouterStore()
|
|||
const layout = useLayoutStore()
|
||||
</script>
|
||||
<template>
|
||||
<ConfigProvider :locale="zhCN">
|
||||
<!-- <ConfigProvider :locale="zhCN"> -->
|
||||
<div class="fixed left-0 top-0 w-full h-screen style-root" @contextmenu.prevent>
|
||||
<Header />
|
||||
<Background
|
||||
|
@ -76,7 +77,8 @@ const layout = useLayoutStore()
|
|||
|
||||
<BackupRecovery v-if="router.path === 'global-backup'"></BackupRecovery>
|
||||
</div>
|
||||
</ConfigProvider>
|
||||
<ModalPgae />
|
||||
<!-- </ConfigProvider> -->
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Button, Slider } from 'ant-design-vue'
|
||||
import { Button, Slider } from 'ant-design-vue'
|
||||
import { defineComponent, ref, Transition, watch } from 'vue'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import { DownloadOutlined, EyeInvisibleOutlined, SwapOutlined } from '@ant-design/icons-vue'
|
||||
|
@ -23,11 +23,33 @@ export default defineComponent(() => {
|
|||
const settings = useSettingsStore()
|
||||
return () => (
|
||||
<div class="absolute left-0 top-0 w-full h-full p-4 overflow-y-auto scrollbar-hide">
|
||||
|
||||
<div class="px-4">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
壁纸
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整壁纸</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<div class="h-[180px]">
|
||||
{layout.background.video && layout.background.type !== 'own' ? (
|
||||
<video class="w-full h-full" src={layout.background.video} loop autoplay={false} controls />
|
||||
<video
|
||||
class="w-full h-full"
|
||||
src={layout.background.video}
|
||||
loop
|
||||
autoplay={false}
|
||||
controls
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
class="w-full h-full bg-center bg-no-repeat bg-cover"
|
||||
|
|
|
@ -86,6 +86,7 @@ export default defineComponent({
|
|||
watch(pair, console.log)
|
||||
return () => (
|
||||
<div class="absolute left-0 top-0 w-full h-screen z-0">
|
||||
|
||||
<Transition name={animate.value ? 'background' : ''}>
|
||||
{pair.front ? (
|
||||
<div class="absolute left-0 top-0 w-full h-full">
|
||||
|
|
|
@ -5,7 +5,9 @@ import LinkBlock from '../grid/LinkBlock'
|
|||
import useSettingsStore from '@/settings/useSettingsStore'
|
||||
import clsx from 'clsx'
|
||||
import { useMenuStore } from '../GlobalMenu'
|
||||
|
||||
import { HiSolidLockOpen, HiSolidLockClosed } from 'oh-vue-icons/icons'
|
||||
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
||||
addIcons(HiSolidLockClosed, HiSolidLockOpen)
|
||||
export default defineComponent(() => {
|
||||
const layout = useLayoutStore()
|
||||
const setting = useSettingsStore()
|
||||
|
@ -28,12 +30,16 @@ export default defineComponent(() => {
|
|||
onMouseleave={() => {
|
||||
show.value = false
|
||||
}}
|
||||
class={'w-3/5 min-w-[800px] h-[120px] fixed left-1/2 bottom-0 -translate-x-1/2'}
|
||||
class={'w-3/5 min-w-[800px] group h-[120px] fixed left-1/2 bottom-0 -translate-x-1/2'}
|
||||
>
|
||||
<div
|
||||
class={clsx(
|
||||
'fixed bottom-4 left-1/2 duration-150 -translate-x-1/2 p-4 rounded-lg bg-white/60 backdrop-blur flex gap-4 shadow-lg',
|
||||
setting.state.showDock === 'auto' ? show.value ? 'bottom-4' : 'bottom-[-90px]' : 'bottom-4'
|
||||
'fixed bottom-6 left-1/2 duration-150 -translate-x-1/2 px-5 p-4 rounded-xl bg-white/60 backdrop-blur flex gap-5 shadow-lg',
|
||||
setting.state.showDock === 'auto'
|
||||
? show.value
|
||||
? 'bottom-4'
|
||||
: 'bottom-[-90px]'
|
||||
: 'bottom-4'
|
||||
)}
|
||||
ref={container}
|
||||
onMouseleave={() => {
|
||||
|
@ -45,6 +51,21 @@ export default defineComponent(() => {
|
|||
menu.open('dock')
|
||||
}}
|
||||
>
|
||||
<div
|
||||
onClick={()=> {
|
||||
setting.state.showDock = setting.state.showDock === 'auto'? 'show' : 'auto'
|
||||
}}
|
||||
class={clsx(
|
||||
'p-1 group-hover:block hidden rounded-lg cursor-pointer hover:bg-black/[.22] absolute bottom-0 -right-8'
|
||||
)}
|
||||
>
|
||||
<OhVueIcon
|
||||
name={
|
||||
setting.state.showDock === 'auto' ? HiSolidLockClosed.name : HiSolidLockOpen.name
|
||||
}
|
||||
fill="white"
|
||||
></OhVueIcon>
|
||||
</div>
|
||||
{layout.state.dockLabels.split('').map((l, i) => {
|
||||
const block = layout.state.dock[i]
|
||||
return (
|
||||
|
@ -54,8 +75,8 @@ export default defineComponent(() => {
|
|||
style={
|
||||
current.value >= 0
|
||||
? {
|
||||
transform: `translateY(${current.value === i - 1 || current.value === i + 1 ? '-5%' : current.value === i ? '-10%' : '0'}) scale(${current.value === i - 1 || current.value === i + 1 ? 1.1 : current.value === i ? 1.2 : 1})`
|
||||
}
|
||||
transform: `translateY(${current.value === i - 1 || current.value === i + 1 ? '-5%' : current.value === i ? '-10%' : '0'}) scale(${current.value === i - 1 || current.value === i + 1 ? 1.1 : current.value === i ? 1.2 : 1})`
|
||||
}
|
||||
: {}
|
||||
}
|
||||
id={block?.id || ''}
|
||||
|
@ -90,8 +111,8 @@ export default defineComponent(() => {
|
|||
{block && <LinkBlock block={block} dock />}
|
||||
{!setting.state.disabledShortcut && (
|
||||
<div
|
||||
class="absolute z-10 left-0 bottom-0 w-full bg-black/20 text-[12px] text-white text-center"
|
||||
style={{ boxShadow: block ? 'none' : '0 -4px 14px 0 rgba(0,0,0,.3)' }}
|
||||
class="absolute z-10 left-0 bottom-0 w-full bg-black/20 text-[12px] backdrop-blur-md text-white text-center"
|
||||
style={{ boxShadow: block ? 'none' : '0 -4px 14px 0 rgba(0,0,0,.4) ' }}
|
||||
>
|
||||
{l}
|
||||
</div>
|
||||
|
|
|
@ -2,11 +2,30 @@ import SettingItem from '@/settings/SettingItem'
|
|||
import useSettingsStore from '@/settings/useSettingsStore'
|
||||
import { Slider, Switch } from 'ant-design-vue'
|
||||
import { defineComponent } from 'vue'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import clsx from 'clsx'
|
||||
|
||||
export default defineComponent(() => {
|
||||
const settings = useSettingsStore()
|
||||
return () => (
|
||||
<div class="p-4">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
图标
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整图标样式</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<SettingItem
|
||||
v-slots={{
|
||||
label: () => <div>图标显示名称</div>
|
||||
|
|
|
@ -39,7 +39,7 @@ export default defineComponent({
|
|||
style={{
|
||||
gridColumn: `span ${props.block.w}`,
|
||||
gridRow: `span ${props.block.h}`,
|
||||
transition: 'border .3s, transform .2s',
|
||||
transition: 'border .3s, transform .2s'
|
||||
// border: hover.value ? '2px solid rgba(255,255,255,.5)' : '2px solid rgba(255,255,255,0)'
|
||||
}}
|
||||
data-transportable={props.block.link && !props.block.link.startsWith('id:') ? '1' : ''}
|
||||
|
@ -69,7 +69,7 @@ export default defineComponent({
|
|||
// 小组件无法合并
|
||||
if (!link) return
|
||||
//游戏不能合并
|
||||
if (props.block.w !== 1) return
|
||||
if (props.block.w === 2 && props.block.h === 1) return
|
||||
const oldIdx = layout.currentPage.list.findIndex((el) => el.id === dragging.id)
|
||||
if (oldIdx < 0) return
|
||||
const oldBlock = layout.currentPage.list[oldIdx]
|
||||
|
@ -79,7 +79,10 @@ export default defineComponent({
|
|||
if (!oldBlock || oldBlock.link.startsWith('id:')) return
|
||||
if (link.startsWith('id:')) {
|
||||
// 本身就是文件夹
|
||||
console.log(123)
|
||||
|
||||
const id = link.slice(3)
|
||||
|
||||
const dir = layout.state.dir[id]
|
||||
if (!dir) return
|
||||
dir.list.push(toRaw(oldBlock))
|
||||
|
@ -88,6 +91,7 @@ export default defineComponent({
|
|||
} else {
|
||||
// 本身不是文件夹
|
||||
const id = props.block.id
|
||||
|
||||
layout.state.dir[id] = {
|
||||
label: props.block.label,
|
||||
list: [toRaw(props.block), toRaw(oldBlock)]
|
||||
|
|
|
@ -33,6 +33,23 @@ export default defineComponent({
|
|||
})
|
||||
return () => (
|
||||
<div class="p-4 flex flex-col gap-y-1 ">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
快捷栏
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整快捷栏功能</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<SettingItem
|
||||
v-slots={{
|
||||
label: () => <div>快捷栏开关</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
|||
import { message, Modal, Table } from 'ant-design-vue'
|
||||
import request from '@/utils/request'
|
||||
import db from '@/db'
|
||||
import clsx from 'clsx'
|
||||
|
||||
addIcons(MdInbox)
|
||||
export interface Feedback {
|
||||
|
@ -43,11 +44,19 @@ export default defineComponent(() => {
|
|||
const list = [img1, img2, img3]
|
||||
return () => (
|
||||
<div class={'p-4 ' + (isGame.value ? 'text-white' : 'text-black/60')}>
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<span class="text-red-500 ">*</span>
|
||||
问题描述
|
||||
<div class="flex justify-between items-start">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
侧边栏
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整侧边栏布局</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="cursor-pointer text-[14px]"
|
||||
onClick={async () => {
|
||||
|
@ -113,6 +122,16 @@ export default defineComponent(() => {
|
|||
历史反馈
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
<div>
|
||||
<span class="text-red-500 ">*</span>
|
||||
问题描述
|
||||
</div>
|
||||
<div
|
||||
class={
|
||||
'mt-2 relative appearance-none rounded-lg h-[124px] ' +
|
||||
|
@ -177,7 +196,7 @@ export default defineComponent(() => {
|
|||
returnType: 'text'
|
||||
})
|
||||
message.success('提交成功')
|
||||
list.forEach(item=> {
|
||||
list.forEach((item) => {
|
||||
item.value = ''
|
||||
})
|
||||
Object.assign(data, { ...defaultData })
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import useUserStore from '@/user/useUserStore'
|
||||
import useRouterStore from '@/useRouterStore'
|
||||
import { defineComponent } from 'vue'
|
||||
import HeaderSetting from '../header/headerSetting'
|
||||
|
||||
export default defineComponent(() => {
|
||||
const router = useRouterStore()
|
||||
const user = useUserStore()
|
||||
return () => <>{router.path === 'custom-header' ? <HeaderSetting></HeaderSetting> : null}</>
|
||||
})
|
|
@ -16,6 +16,23 @@ export default defineComponent({
|
|||
})
|
||||
return () => (
|
||||
<div class="p-4 flex flex-col ">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
重置
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>恢复默认设置</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<SettingItem
|
||||
v-slots={{
|
||||
label: () => <div>重置</div>
|
||||
|
@ -34,7 +51,7 @@ export default defineComponent({
|
|||
{open.value && (
|
||||
<div
|
||||
class={clsx(
|
||||
'w-[300px] h-[210px] absolute rounded-2xl right-[-310px] z-10 ',
|
||||
'w-[300px] h-[210px] absolute top-0 rounded-2xl right-[-310px] z-10 ',
|
||||
isGame.value ? 'bg-[#2c2e3e]' : 'bg-white'
|
||||
)}
|
||||
style={
|
||||
|
|
|
@ -3,6 +3,8 @@ import useSettingsStore from '@/settings/useSettingsStore'
|
|||
import { Select, Slider, Switch, type SelectProps } from 'ant-design-vue'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import useSearchConfigStore from '../header/search/useSearchConfigStore'
|
||||
import clsx from 'clsx'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
|
@ -16,6 +18,23 @@ export default defineComponent({
|
|||
)
|
||||
return () => (
|
||||
<div class="p-4">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
搜索
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整搜索样式</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<SettingItem
|
||||
noRoundedB
|
||||
v-slots={{
|
||||
|
|
|
@ -11,6 +11,23 @@ export default defineComponent({
|
|||
const layout = useLayoutStore()
|
||||
return () => (
|
||||
<div class="p-4 flex flex-col gap-y-4 ">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
侧边栏
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整侧边栏布局</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class={'p-5 bg-[#000000]/[.05] rounded-lg w-full grid grid-rows-1 grid-cols-2 gap-x-3'}
|
||||
>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Select, Slider, Switch, type SelectProps } from 'ant-design-vue'
|
|||
import { defineComponent, ref } from 'vue'
|
||||
import useSearchConfigStore from '../header/search/useSearchConfigStore'
|
||||
import clsx from 'clsx'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
const list: {
|
||||
label: string
|
||||
value: TimeUnit
|
||||
|
@ -41,6 +42,23 @@ export default defineComponent({
|
|||
)
|
||||
return () => (
|
||||
<div class="p-4">
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
时间
|
||||
</span>
|
||||
<span class={'text-[13px] text-[#666] '}>调整时间样式</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<SettingItem
|
||||
v-slots={{
|
||||
label: () => <div>显示时间</div>
|
||||
|
|
|
@ -72,6 +72,7 @@ export default defineComponent(() => {
|
|||
const idx = list.findIndex((el) => el.id === dragging.id)
|
||||
if (idx < 0) return
|
||||
const block = list[idx]
|
||||
|
||||
layout.currentPage.list.push(toRaw(block))
|
||||
list.splice(idx, 1)
|
||||
layout.checkDir(dragging.type)
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
import useLayoutStore from '@/layout/useLayoutStore'
|
||||
import useUserStore from '@/user/useUserStore'
|
||||
import useRouterStore from '@/useRouterStore'
|
||||
import clsx from 'clsx'
|
||||
import { computed, defineComponent, ref, Transition } from 'vue'
|
||||
import { MdArrowbackiosnew, HiSolidPlus } from 'oh-vue-icons/icons'
|
||||
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
||||
import { ossBase } from '@/config'
|
||||
import UploadAndCut from '@/utils/UploadAndCut'
|
||||
addIcons(MdArrowbackiosnew, HiSolidPlus)
|
||||
export default defineComponent(() => {
|
||||
const router = useRouterStore()
|
||||
const { profile } = useUserStore()
|
||||
const layout = useLayoutStore()
|
||||
const inputRef = ref<any>()
|
||||
const isGame = computed(() => {
|
||||
return layout.state.current === 0
|
||||
})
|
||||
const list = Array.from({ length: 9 }).map((_, index) => `${ossBase}/admin/${index + 1}.png`)
|
||||
const selectUrl = ref(profile.avatar)
|
||||
const customHeader = ref(profile.avatar)
|
||||
|
||||
return () => (
|
||||
<div class="fixed left-0 bottom-0 z-40 w-full rounded-lg">
|
||||
{/* 背景遮罩 */}
|
||||
<div
|
||||
class="w-full h-screen"
|
||||
onClick={() => {
|
||||
router.replace('')
|
||||
}}
|
||||
></div>
|
||||
{/* 弹框主体 */}
|
||||
<Transition name="settings">
|
||||
<div
|
||||
class={clsx(
|
||||
'absolute left-6 bottom-10 w-[300px] h-[580px] rounded-2xl shadow-2xl flex ',
|
||||
isGame.value ? 'bg-[#2c2e3e] text-white' : 'text-[#000] bg-white'
|
||||
)}
|
||||
style={
|
||||
isGame.value && {
|
||||
backgroundImage: `url('/tab/bg/gameModel.png')`,
|
||||
backgroundSize: '100% 100%'
|
||||
}
|
||||
}
|
||||
>
|
||||
<div class={'w-full h-full flex flex-col px-5 py-1 '}>
|
||||
<div class={'relative flex justify-center w-full font-bold text-[14px] py-2'}>
|
||||
<div
|
||||
class={'left-2 top-1/2 absolute -translate-y-1/2 cursor-pointer'}
|
||||
onClick={() => {
|
||||
router.back()
|
||||
}}
|
||||
>
|
||||
<OhVueIcon name={MdArrowbackiosnew.name} fill="#666"></OhVueIcon>
|
||||
</div>
|
||||
更换头像
|
||||
</div>
|
||||
<div class={'h-[1px] w-full bg-[#d5d5d5] mt-1 mb-3'}></div>
|
||||
<div class={'w-full grid grid-cols-3 gap-3'}>
|
||||
{list.map((item) => {
|
||||
return (
|
||||
<div
|
||||
key={item}
|
||||
class={' cursor-pointer'}
|
||||
onClick={() => {
|
||||
selectUrl.value = item
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={item}
|
||||
class={clsx(
|
||||
'w-full h-full rounded-full border-[2px] ',
|
||||
selectUrl.value === item
|
||||
? 'border-[2px] border-red-500'
|
||||
: 'border-[2px] border-transparent'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{!list.includes(customHeader.value) && customHeader.value && (
|
||||
<div
|
||||
class={' cursor-pointer'}
|
||||
onClick={() => {
|
||||
selectUrl.value = customHeader.value
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={customHeader.value}
|
||||
class={clsx(
|
||||
'w-full h-full rounded-full border-[2px] ',
|
||||
selectUrl.value === customHeader.value
|
||||
? 'border-[2px] border-red-500'
|
||||
: 'border-[2px] border-transparent'
|
||||
)}
|
||||
alt="header"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
class={'flex items-center w-[78px] h-[78px] justify-center bg-[#E5E5E5] rounded-full cursor-pointer'}
|
||||
>
|
||||
<UploadAndCut
|
||||
onUpdate:value={(e) => {
|
||||
customHeader.value = e
|
||||
selectUrl.value = e
|
||||
}}
|
||||
></UploadAndCut>
|
||||
</div>
|
||||
</div>
|
||||
<div class={'flex justify-center w-full'}>
|
||||
<button
|
||||
onClick={() => {
|
||||
profile.avatar = selectUrl.value
|
||||
useUserStore().updateProfile()
|
||||
router.back()
|
||||
}}
|
||||
class={
|
||||
'px-14 mt-14 py-1 bg-[#ff7372] text-white text-[14px] rounded-lg hover:opacity-80'
|
||||
}
|
||||
>
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -0,0 +1,47 @@
|
|||
import useLayoutStore from '@/layout/useLayoutStore'
|
||||
import useUserStore from '@/user/useUserStore'
|
||||
import useRouterStore from '@/useRouterStore'
|
||||
import clsx from 'clsx'
|
||||
import { computed, defineComponent, Transition } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
const router = useRouterStore()
|
||||
const { profile } = useUserStore()
|
||||
const show = computed(() => router.path.startsWith('settings-header'))
|
||||
const layout = useLayoutStore()
|
||||
const isGame = computed(() => {
|
||||
return layout.state.current === 0
|
||||
})
|
||||
return () => (
|
||||
<div class="fixed left-0 bottom-0 z-40 w-full rounded-lg">
|
||||
{/* 背景遮罩 */}
|
||||
{show.value && (
|
||||
<div
|
||||
class="w-full h-screen"
|
||||
onClick={() => {
|
||||
router.replace('')
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
{/* 弹框主体 */}
|
||||
<Transition name="settings">
|
||||
{show.value && (
|
||||
<div
|
||||
class={clsx(
|
||||
'absolute left-6 bottom-10 w-[660px] h-[580px] rounded-2xl shadow-2xl flex',
|
||||
isGame.value ? 'bg-[#2c2e3e] text-white' : 'text-[#000] bg-white'
|
||||
)}
|
||||
style={
|
||||
isGame.value && {
|
||||
backgroundImage: `url('/tab/bg/gameModel.png')`,
|
||||
backgroundSize: '100% 100%'
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -13,8 +13,9 @@ export type SettingStr =
|
|||
| 'dock'
|
||||
| 'reset'
|
||||
| 'fallback'
|
||||
export type CustomStr = 'background'
|
||||
export type RouteStr = '' | `widget-${string}` | `global-${GlobalStr}` | `settings-${SettingStr}`
|
||||
| 'logout'
|
||||
export type CustomStr = 'header'
|
||||
export type RouteStr = '' | `widget-${string}` | `global-${GlobalStr}` | `settings-${SettingStr}` | `custom-${CustomStr}`
|
||||
|
||||
export default defineStore('router', () => {
|
||||
const his = ref<RouteStr[]>([])
|
||||
|
|
|
@ -1,96 +1,192 @@
|
|||
import useRouterStore from '@/useRouterStore'
|
||||
import { Button, Modal, Tag } from 'ant-design-vue'
|
||||
import { defineComponent } from 'vue'
|
||||
import { Button, Select } from 'ant-design-vue'
|
||||
import { computed, defineComponent, ref } from 'vue'
|
||||
import AvatarCircle from './AvatarCircle'
|
||||
import useUserStore from './useUserStore'
|
||||
import { EditOutlined, LoginOutlined, LogoutOutlined } from '@ant-design/icons-vue'
|
||||
import { globalToast } from '@/main'
|
||||
import { LoginOutlined } from '@ant-design/icons-vue'
|
||||
import { FaRegularEdit } from 'oh-vue-icons/icons'
|
||||
import clsx from 'clsx'
|
||||
import useLayoutStore from '@/layout/useLayoutStore'
|
||||
|
||||
const labelStyle = 'w-16'
|
||||
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
||||
import background from '@/layout/background'
|
||||
addIcons(FaRegularEdit)
|
||||
|
||||
export default defineComponent(() => {
|
||||
const router = useRouterStore()
|
||||
const layout = useLayoutStore()
|
||||
const user = useUserStore()
|
||||
const open = ref(false)
|
||||
const isGame = computed(() => {
|
||||
return layout.state.current === 0
|
||||
})
|
||||
return () => (
|
||||
<div class="absolute left-0 top-0 w-full h-full p-4 flex flex-col">
|
||||
<div class="flex justify-center py-4">
|
||||
<div class="w-16 h-16 relative">
|
||||
<AvatarCircle />
|
||||
</div>
|
||||
</div>
|
||||
{user.isLogin && (
|
||||
<div
|
||||
class={clsx(
|
||||
'h-0 flex-grow py-4 px-12 ',
|
||||
layout.state.current === 0 ? 'text-white' : 'text-[#333]'
|
||||
)}
|
||||
>
|
||||
<div class="flex py-2">
|
||||
<div class={labelStyle}>用户名:</div>
|
||||
<div class="w-0 flex-grow overflow-hidden text-ellipsis whitespace-nowrap break-all">
|
||||
{user.profile.username}
|
||||
{user.isLogin ? (
|
||||
<>
|
||||
<div class={'flex flex-col'}>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] font-bold',
|
||||
useLayoutStore().state.current === 0 ? 'text-white' : ' text-[#333]'
|
||||
)}
|
||||
>
|
||||
个人信息
|
||||
</span>
|
||||
<div
|
||||
class={clsx(
|
||||
'w-full h-[1px] bg-black/10 mt-1 mb-2',
|
||||
useLayoutStore().state.current === 0 ? 'bg-white/10' : ' bg-black/10'
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
<div class="flex pl-4 py-4 w-full gap-x-4">
|
||||
<div class="w-16 h-16 rounded-full group overflow-hidden relative">
|
||||
<AvatarCircle />
|
||||
<div
|
||||
onClick={() => {
|
||||
router.go('custom-header')
|
||||
}}
|
||||
class={
|
||||
'absolute hidden left-0 cursor-pointer top-0 opacity-60 rounded-full w-full h-full bg-black z-10 group-hover:flex items-center justify-center'
|
||||
}
|
||||
>
|
||||
<OhVueIcon name={FaRegularEdit.name} fill="#ddd"></OhVueIcon>
|
||||
</div>
|
||||
</div>
|
||||
<div class={'flex flex-col h-full justify-between text-[14px] py-1'}>
|
||||
<div class={'flex gap-x-1 items-center'}>
|
||||
<span class={clsx(' w-[50px]', isGame.value ? 'text-[#fff9]' : 'text-[#666]')}>
|
||||
用户名:
|
||||
</span>
|
||||
<input
|
||||
onBlur={() => {
|
||||
user.updateProfile()
|
||||
}}
|
||||
class={
|
||||
'text-[#666] w-[150px] bg-transparent focus:bg-black/[0.05] border-none outline-none px-1 py-[2px]'
|
||||
}
|
||||
v-model={user.profile.username}
|
||||
></input>
|
||||
</div>
|
||||
<div class={'flex gap-x-1 items-center'}>
|
||||
<span class={clsx(' w-[50px]', isGame.value ? 'text-[#fff9]' : 'text-[#666]')}>
|
||||
性  别:
|
||||
</span>
|
||||
<Select
|
||||
defaultValue={user.profile.gender}
|
||||
v-model={user.profile.gender}
|
||||
class={
|
||||
'w-[150px] bg-transparent appearance-none focus:bg-black/[0.05] overflow-hidden border-none outline-none px-1 py-[2px]'
|
||||
}
|
||||
style={{
|
||||
background: 'transparent !important'
|
||||
}}
|
||||
onChange={(e: any) => {
|
||||
user.profile.gender = e
|
||||
user.updateProfile()
|
||||
}}
|
||||
options={[
|
||||
{
|
||||
label: '男',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '女',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: '未知',
|
||||
value: 0
|
||||
}
|
||||
]}
|
||||
></Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex py-2">
|
||||
<div class={labelStyle}>生日:</div> {user.profile.birthday}
|
||||
<div
|
||||
onClick={() => {
|
||||
open.value = true
|
||||
}}
|
||||
class={
|
||||
'w-full h-[32px] mt-5 cursor-pointer hover:opacity-90 flex items-center justify-center text-[13px] rounded bg-[#e5e5e5] text-[#999]'
|
||||
}
|
||||
>
|
||||
退出登录
|
||||
</div>
|
||||
<div class="flex py-2">
|
||||
<div class={labelStyle}>性别:</div>
|
||||
<Tag color={user.profile.gender === 1 ? 'blue' : user.profile.gender === 2 ? 'red' : 'gray'}>
|
||||
{user.profile.gender === 1 ? '男' : user.profile.gender === 2 ? '女' : '未知'}
|
||||
</Tag>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<LoginOutlined />}
|
||||
size="large"
|
||||
onClick={() => {
|
||||
router.go('global-login')
|
||||
}}
|
||||
>
|
||||
登录
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{open.value && (
|
||||
<div
|
||||
class={clsx(
|
||||
'w-[300px] h-[210px] absolute top-0 rounded-2xl right-[-310px] z-10 ',
|
||||
isGame.value ? 'bg-[#2c2e3e]' : 'bg-white'
|
||||
)}
|
||||
style={
|
||||
isGame.value
|
||||
? {
|
||||
backgroundImage: `url('/tab/bg/addBorder.png')`,
|
||||
backgroundSize: '100% 100%',
|
||||
backgroundColor: '#2c2e3e'
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
<div
|
||||
class={'flex flex-col w-full h-full p-7 border-b-[1px] items-center justify-between'}
|
||||
>
|
||||
<span class={isGame.value ? '' : ''}>退出登录</span>
|
||||
<div
|
||||
class={clsx('w-full h-[1px]', isGame.value ? ' bg-white/20' : 'bg-black/20')}
|
||||
></div>
|
||||
<span
|
||||
class={clsx(
|
||||
'text-[14px] leading-[20px] mb-2 text-center',
|
||||
isGame.value ? 'text-[#fff9]' : 'text-[#666]'
|
||||
)}
|
||||
>
|
||||
退出登录将会失去多端数据云同步等功能,是否继续?
|
||||
</span>
|
||||
<div class={'flex justify-between w-full'}>
|
||||
<button
|
||||
onClick={() => {
|
||||
open.value = false
|
||||
}}
|
||||
class={clsx(
|
||||
'w-[118px] rounded-lg py-1 flex justify-center',
|
||||
isGame.value ? 'bg-white/20' : 'bg-black/20 text-white'
|
||||
)}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
user.logout()
|
||||
open.value = false
|
||||
router.replace('')
|
||||
}}
|
||||
class={clsx(
|
||||
'w-[118px] rounded-lg py-1 flex justify-center ',
|
||||
isGame.value ? 'bg-[#ff7372]' : 'bg-[#ff7372] text-white'
|
||||
)}
|
||||
>
|
||||
退出
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<div class="flex justify-around items-center my-10">
|
||||
{user.isLogin ? (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
router.go('global-login')
|
||||
}}
|
||||
icon={<EditOutlined />}
|
||||
type="primary"
|
||||
>
|
||||
修改个人信息
|
||||
</Button>
|
||||
<Button
|
||||
type="text"
|
||||
class={'text-[#999] hover:text-[#999]'}
|
||||
icon={<LogoutOutlined />}
|
||||
onClick={() => {
|
||||
Modal.confirm({
|
||||
title: '退出登录',
|
||||
content: '确定要退出登录吗?',
|
||||
onOk: () => {
|
||||
router.go('')
|
||||
user.logout()
|
||||
globalToast.success('已退出登录')
|
||||
}
|
||||
})
|
||||
}}
|
||||
>
|
||||
退出登录
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<LoginOutlined />}
|
||||
size="large"
|
||||
onClick={() => {
|
||||
router.go('global-login')
|
||||
}}
|
||||
>
|
||||
登录
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div >
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -137,10 +137,19 @@ export default defineStore('user', () => {
|
|||
Object.assign(layout.state.dock, remoteData.value.dock)
|
||||
Object.assign(layout.state.dir, remoteData.value.dir)
|
||||
}
|
||||
const updateProfile = () => {
|
||||
request('PUT', '/api/profile', {
|
||||
returnType: 'text',
|
||||
data: {
|
||||
...profile
|
||||
}
|
||||
})
|
||||
}
|
||||
return {
|
||||
token,
|
||||
profile,
|
||||
isLogin,
|
||||
updateProfile,
|
||||
logout,
|
||||
coverageData,
|
||||
comineData
|
||||
|
|
|
@ -158,7 +158,7 @@ export default defineComponent({
|
|||
</div>
|
||||
</Modal>
|
||||
<div
|
||||
class="w-full h-full bg-white flex items-center justify-center"
|
||||
class="w-full h-full flex items-center justify-center"
|
||||
onClick={() => {
|
||||
if (useUserStore().isLogin) {
|
||||
inputRef.value?.click?.()
|
||||
|
|
Loading…
Reference in New Issue