完善设置项

This commit is contained in:
expdsn 2024-10-30 19:07:10 +08:00
parent bcd9534a34
commit bc06db113a
10 changed files with 339 additions and 96 deletions

View File

@ -2,8 +2,8 @@ export const aIUrl = 'https://metaso.cn/?s=uitab&referrer_s=uitab&q='
export const translateUrl = 'https://fanyi.baidu.com/mtpe-individual/multimodal?lang=zh2en&query=' export const translateUrl = 'https://fanyi.baidu.com/mtpe-individual/multimodal?lang=zh2en&query='
// oss地址 // oss地址
export const ossBase = import.meta.env.PROD export const ossBase = import.meta.env.PROD
? 'http://newfatfox.oss-cn-beijing.aliyuncs.com' ? 'https://oss.goosetab.com'
: 'http://newfatfox.oss-cn-beijing.aliyuncs.com' : 'https://oss.goosetab.com'
// 前端地址 // 前端地址
export const frontAddress = import.meta.env.PROD export const frontAddress = import.meta.env.PROD

View File

@ -0,0 +1,61 @@
import SettingItem from '@/settings/SettingItem'
import useSettingsStore from '@/settings/useSettingsStore'
import { Select, Switch } from 'ant-design-vue'
import clsx from 'clsx'
import { defineComponent } from 'vue'
import useLayoutStore from '../useLayoutStore'
export default defineComponent({
name: 'SiderSetting',
props: {},
setup() {
const settings = useSettingsStore()
const layout = useLayoutStore()
return () => (
<div class="p-4 flex flex-col gap-y-1 ">
<SettingItem
v-slots={{
label: () => <div></div>
}}
>
<Switch
checked={settings.state.showDock === ''}
onUpdate:checked={(e) => {
if (e) settings.state.showDock = ''
else settings.state.showDock = 'show'
}}
/>
</SettingItem>{' '}
<SettingItem
v-slots={{
label: () => <div></div>
}}
>
<Switch
checked={settings.state.showDock === 'auto'}
onUpdate:checked={(e) => {
if (e) settings.state.showDock = 'auto'
else settings.state.showDock = 'show'
}}
/>
</SettingItem>{' '}
<div class={'flex flex-col text-[#333]'}>
<span class={'font-bold'}></span>
<p class={'text-[12px] text-[#999]'}></p>
<div class={'w-full h-[1px] bg-[#ddd] mt-2'}></div>
<div class={'w-full grid grid-rows-5 grid-cols-2 gap-2 p-2'}>
{layout.state.dockLabels.split('').map((val, idx) => (
<div class="w-full flex gap-x-4">
<span>{idx + 1}</span>
<div class={'flex-1 bg-slate-50 rounded'}>
</div>
</div>
))}
</div>
</div>
</div>
)
}
})

25
src/layout/grid/Reset.tsx Normal file
View File

@ -0,0 +1,25 @@
import SettingItem from '@/settings/SettingItem'
import useSettingsStore from '@/settings/useSettingsStore'
import { Button, Switch } from 'ant-design-vue'
import clsx from 'clsx'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'SiderSetting',
props: {},
setup() {
const settings = useSettingsStore()
return () => (
<div class="p-4 flex flex-col ">
<SettingItem
v-slots={{
label: () => <div></div>
}}
>
<Button type="primary"></Button>
</SettingItem>
<p class={"text-[#666] text-[12px]"}></p>
</div>
)
}
})

View File

@ -0,0 +1,92 @@
import SettingItem from '@/settings/SettingItem'
import useSettingsStore from '@/settings/useSettingsStore'
import { Switch } from 'ant-design-vue'
import clsx from 'clsx'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'SiderSetting',
props: {},
setup() {
const settings = useSettingsStore()
return () => (
<div class="p-4 flex flex-col gap-y-4 ">
<div
class={'p-5 bg-[#000000]/[.05] rounded-lg w-full grid grid-rows-1 grid-cols-2 gap-x-3'}
>
<div class={'flex flex-col gap-y-2 items-center w-full'}>
<div
onClick={() => {
settings.state.siderDirection = 'left'
}}
class={clsx(
'bg-white flex flex-col h-[92px] w-full p-3 justify-between rounded-lg cursor-pointer border-[1px] ',
settings.state.siderDirection === 'left' ? 'border-[#ffa94d]' : 'border-transparent'
)}
>
<div class={'bg-[#E5E5E5] w-[25px] h-[18px] rounded'}></div>
<div class={'bg-[#E5E5E5] w-[25px] h-[18px] rounded'}></div>
<div class={'bg-[#E5E5E5] w-[25px] h-[18px] rounded'}></div>
</div>
<button
onClick={() => {
settings.state.siderDirection = 'left'
}}
class={clsx(
'px-7 py-1 rounded text-[14px]',
settings.state.siderDirection === 'left'
? 'bg-[#ffa94d] text-white'
: 'bg-[#E5E5E5] text-[#999]'
)}
>
</button>
</div>
<div class={'flex flex-col gap-y-2 items-center'}>
<div
onClick={() => {
settings.state.siderDirection = 'right'
}}
class={clsx(
'bg-white flex items-end w-full flex-col h-[92px] p-3 justify-between rounded-lg cursor-pointer border-[1px] ',
settings.state.siderDirection === 'right'
? 'border-[#ffa94d]'
: 'border-transparent'
)}
>
<div class={'bg-[#E5E5E5] w-[25px] h-[18px] rounded'}></div>
<div class={'bg-[#E5E5E5] w-[25px] h-[18px] rounded'}></div>
<div class={'bg-[#E5E5E5] w-[25px] h-[18px] rounded'}></div>
</div>
<button
onClick={() => {
settings.state.siderDirection = 'right'
}}
class={clsx(
'px-7 py-1 rounded text-[14px]',
settings.state.siderDirection === 'right'
? 'bg-[#ffa94d] text-white'
: 'bg-[#E5E5E5] text-[#999]'
)}
>
</button>
</div>
</div>
<SettingItem
v-slots={{
label: () => <div></div>
}}
>
<Switch
checked={settings.state.showSider === 'auto'}
onUpdate:checked={(e) => {
if (e) settings.state.showSider = 'auto'
else settings.state.showSider = 'show'
}}
/>
</SettingItem>{' '}
</div>
)
}
})

View File

@ -8,13 +8,13 @@ export default defineComponent({
setup() { setup() {
const time = useTimeStore() const time = useTimeStore()
const text = computed(() => { const text = computed(() => {
if (!useSettingsStore().state.timeOptions.includes('12hour')) { const is24h = useSettingsStore().state.timeOptions.includes('12hour')
return { const hasSec = useSettingsStore().state.timeOptions.includes('second')
timeStr: `${time.date.getHours()}:${time.date.getMinutes()}:${time.date.getSeconds()}`, let h = time.date.getHours()
dateStr: `${time.date.getMonth() + 1}${time.date.getDate()}` if (is24h) {
} h = h % 12 // 转换成12小时制
h = h ? h : 12 // 0点要转换成12
} }
const h = time.date.getHours()
const hour = h < 10 ? '0' + h : h const hour = h < 10 ? '0' + h : h
const m = time.date.getMinutes() const m = time.date.getMinutes()
const minute = m < 10 ? '0' + m : m const minute = m < 10 ? '0' + m : m
@ -22,7 +22,7 @@ export default defineComponent({
const second = s < 10 ? '0' + s : s const second = s < 10 ? '0' + s : s
const dateStr = `${time.date.getMonth() + 1}${time.date.getDate()}` const dateStr = `${time.date.getMonth() + 1}${time.date.getDate()}`
return { return {
timeStr: `${hour}:${minute}:${second}`, timeStr: hasSec ? `${hour}:${minute}:${second}` : `${hour}:${minute}`,
dateStr dateStr
} }
}) })

View File

@ -2,11 +2,14 @@ import { defineComponent, ref, watch } from 'vue'
import useLayoutStore from '../useLayoutStore' import useLayoutStore from '../useLayoutStore'
import { OhVueIcon, addIcons } from 'oh-vue-icons' import { OhVueIcon, addIcons } from 'oh-vue-icons'
import { MdVideogameassetTwotone, MdWorkhistoryTwotone, MdStarsTwotone } from 'oh-vue-icons/icons' import { MdVideogameassetTwotone, MdWorkhistoryTwotone, MdStarsTwotone } from 'oh-vue-icons/icons'
import useSettingsStore from '@/settings/useSettingsStore'
import clsx from 'clsx'
addIcons(MdVideogameassetTwotone, MdWorkhistoryTwotone, MdStarsTwotone) addIcons(MdVideogameassetTwotone, MdWorkhistoryTwotone, MdStarsTwotone)
export default defineComponent(() => { export default defineComponent(() => {
const hover = ref(false) const hover = ref(false)
const settings = useSettingsStore()
const selected = ref<0 | 1 | 2>(0) const selected = ref<0 | 1 | 2>(0)
const layout = useLayoutStore() const layout = useLayoutStore()
watch( watch(
@ -33,46 +36,68 @@ export default defineComponent(() => {
fill-opacity={hover.value ? 1 : 0} fill-opacity={hover.value ? 1 : 0}
fill={hover.value ? 'rgba(0,0,0,.4)' : 'transparent'} fill={hover.value ? 'rgba(0,0,0,.4)' : 'transparent'}
/> />
<text <text x={'0.28'} y={'0.42'} font-size={'0.22'} class="transition-all" fill="white">
x={hover.value ? '0.23' : '0.28'}
y={hover.value ? '0.6' : '0.42'}
font-size={hover.value ? '0.26' : '0.22'}
class="transition-all"
fill="white"
>
{layout.state.current === 0 ? '游戏' : layout.state.current === 1 ? '工作' : '休闲'} {layout.state.current === 0 ? '游戏' : layout.state.current === 1 ? '工作' : '休闲'}
</text> </text>
<text <text x="0.28" y="0.72" font-size="0.22" class="transition-all" fill={'white'}>
x="0.28"
y="0.68"
font-size="0.22"
class="transition-all"
fill={hover.value ? 'transparent' : 'white'}
>
</text> </text>
</svg> </svg>
{/* 转盘 */} {/* 转盘 */}
<div <div
class={ class={clsx(
'w-[200px] h-[200px] absolute -left-[72px] -top-[72px] rounded-full overflow-hidden transition-all ' + 'w-[200px] h-[200px] absolute -top-[72px] rounded-full overflow-hidden transition-all ',
(hover.value ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0') settings.state.siderDirection === 'left'
} ? 'left-[-72px] -top-[72px]'
: 'right-[-72px] bottom-[72px]',
settings.state.siderDirection === 'left'
? hover.value
? 'scale-100 rotate-0 opacity-100'
: 'scale-0 -rotate-90 opacity-0'
: hover.value
? 'scale-100 rotate-0 opacity-100'
: 'scale-0 rotate-90 opacity-0'
)}
style="transform-origin: 54% 54%; filter: drop-shadow(0 0 4px rgba(0,0,0,.4));transition-duration:.3s; transition-timing-function: cubic-bezier(.4,0,.2,1)" style="transform-origin: 54% 54%; filter: drop-shadow(0 0 4px rgba(0,0,0,.4));transition-duration:.3s; transition-timing-function: cubic-bezier(.4,0,.2,1)"
> >
<div class="absolute left-[105px] top-[18px] text-white text-[13px] flex flex-col items-center pointer-events-none"> <div
class={clsx(
'absolute top-[18px] text-white text-[13px] z-20 flex flex-col items-center pointer-events-none',
settings.state.siderDirection === 'right' ? 'right-[105px]' : 'left-[105px] '
)}
>
<OhVueIcon name="md-videogameasset-twotone" fill="white" scale={1.3} /> <OhVueIcon name="md-videogameasset-twotone" fill="white" scale={1.3} />
</div> </div>
<div class="absolute left-[150px] top-[80px] text-white text-[13px] flex flex-col items-center pointer-events-none"> <div
class={clsx(
'absolute top-[80px] text-white text-[13px] z-20 flex flex-col items-center pointer-events-none',
settings.state.siderDirection === 'right' ? 'right-[150px] ' : 'left-[150px] '
)}
>
<OhVueIcon name="md-workhistory-twotone" fill="white" scale={1.3} /> <OhVueIcon name="md-workhistory-twotone" fill="white" scale={1.3} />
</div> </div>
<div class="absolute left-[105px] top-[140px] text-white text-[13px] flex flex-col items-center pointer-events-none"> <div
class={clsx(
'absolute text-white text-[13px] flex flex-col z-20 items-center pointer-events-none',
settings.state.siderDirection === 'right'
? 'right-[105px] top-[140px]'
: 'left-[105px] top-[140px]'
)}
>
<OhVueIcon name="md-stars-twotone" fill="white" scale={1.3} /> <OhVueIcon name="md-stars-twotone" fill="white" scale={1.3} />
</div> </div>
<svg width="200" height="200" class="w-full h-full" viewBox="0 0 240 240"> <svg
width="200"
height="200"
class={clsx(
'w-full h-full ',
settings.state.siderDirection === 'right' && 'scale-x-[-1]'
)}
viewBox="0 0 240 240"
>
<g> <g>
<path <path
fill="rgba(0,0,0,.6)" fill="rgba(0,0,0,.6)"

View File

@ -7,6 +7,8 @@ import useRouterStore from '@/useRouterStore'
import useLayoutStore from '../useLayoutStore' import useLayoutStore from '../useLayoutStore'
import useUserStore from '@/user/useUserStore' import useUserStore from '@/user/useUserStore'
import AvatarCircle from '@/user/AvatarCircle' import AvatarCircle from '@/user/AvatarCircle'
import clsx from 'clsx'
import useSettingsStore from '@/settings/useSettingsStore'
initIcons() initIcons()
addIcons(PxHeadset, PxAddBox, PxCheck) addIcons(PxHeadset, PxAddBox, PxCheck)
@ -59,7 +61,9 @@ export default defineComponent(() => {
const selected = ref(icons[0]) const selected = ref(icons[0])
const router = useRouterStore() const router = useRouterStore()
const layout = useLayoutStore() const layout = useLayoutStore()
const settings = useSettingsStore()
const user = useUserStore() const user = useUserStore()
const show = ref(false)
const label = ref('') const label = ref('')
watch( watch(
selected, selected,
@ -71,70 +75,95 @@ export default defineComponent(() => {
return () => ( return () => (
<Transition> <Transition>
{layout.ready && ( {layout.ready && (
<div class="fixed left-6 top-1/2 -translate-y-1/2 h-[600px] z-30"> <div
<div class="w-[56px] h-full rounded-[28px] bg-black/70 backdrop-blur flex flex-col justify-between items-center"> class={clsx(
<ModeSwitch /> 'w-[130px] min-h-[620px] hover:bg-red-10 z-20 fixed top-1/2 -translate-y-1/2 bottom-0 ',
<div class="w-full h-[64px]" /> settings.state.siderDirection === 'left' ? 'left-0' : 'right-0'
<div class="w-full h-0 flex-grow overflow-auto relative no-scrollbar"> )}
<TransitionGroup> onMouseleave={() => {
{layout.currentMode.pages.map((el, idx) => ( show.value = false
<Item }}
key={idx} onMouseenter={() => {
name={el.name} show.value = true
label={el.label} }}
idx={idx} >
active={layout.state.currentPage === idx} <div
onClick={() => { class={clsx(
layout.state.currentPage = idx 'fixed top-1/2 -translate-y-1/2 h-[600px] z-30 duration-150',
}} settings.state.siderDirection === 'left'
/> ? settings.state.showSider === 'auto' && !show.value
))} ? '-left-14'
</TransitionGroup> : 'left-6'
<Transition> : settings.state.showSider === 'auto' && !show.value
{layout.currentMode.pages.length > 0 && ( ? '-right-14'
<div : 'right-6'
class="absolute w-full h-[56px] rounded-lg bg-white/40 left-0 transition-all" )}
style={{ >
transitionDuration: '.3s', <div class="w-[56px] h-full rounded-[28px] bg-black/70 backdrop-blur flex flex-col justify-between items-center">
top: `${layout.state.currentPage * 56}px` <ModeSwitch />
}} <div class="w-full h-[64px]" />
/> <div class="w-full h-0 flex-grow overflow-auto relative no-scrollbar">
)} <TransitionGroup>
</Transition> {layout.currentMode.pages.map((el, idx) => (
<Item
key={idx}
name={el.name}
label={el.label}
idx={idx}
active={layout.state.currentPage === idx}
onClick={() => {
layout.state.currentPage = idx
}}
/>
))}
</TransitionGroup>
<Transition>
{layout.currentMode.pages.length > 0 && (
<div
class="absolute w-full h-[56px] rounded-lg bg-white/40 left-0 transition-all"
style={{
transitionDuration: '.3s',
top: `${layout.state.currentPage * 56}px`
}}
/>
)}
</Transition>
</div>
<div class="w-full h-4" />
<Item
name="px-add-box"
label="添加"
onClick={() => {
showEdit.value = true
}}
/>
<Item
name="px-headset"
label="反馈"
onClick={() => {
router.go('settings-fallback')
}}
/>
<div
class="w-[56px] h-[56px] rounded-full border-white border-[2px] border-solid overflow-hidden cursor-pointer"
onClick={() => {
if (user.isLogin) {
router.go('settings-user')
} else {
router.go('global-login')
}
}}
>
<AvatarCircle />
</div>
</div> </div>
<div class="w-full h-4" /> {/* 添加页面 */}
<Item
name="px-add-box"
label="添加"
onClick={() => {
showEdit.value = true
}}
/>
<Item
name="px-headset"
label="反馈"
onClick={() => {
router.go('settings-fallback')
}}
/>
<div
class="w-[56px] h-[56px] rounded-full border-white border-[2px] border-solid overflow-hidden cursor-pointer"
onClick={() => {
if (user.isLogin) {
router.go('settings-user')
} else {
router.go('global-login')
}
}}
>
<AvatarCircle />
</div>
</div>
{/* 添加页面 */}
<Transition name="page-adder">
{showEdit.value && ( {showEdit.value && (
<div <div
class="absolute left-[70px] bottom-0 w-56 rounded-lg p-4 bg-white/40 backdrop-blur shadow-lg" class={clsx(
'absolute bottom-0 w-56 rounded-lg p-4 bg-white/40 backdrop-blur shadow-lg',
settings.state.siderDirection === 'left' ? 'left-[70px]' : 'right-[70px]'
)}
v-outside-click={() => { v-outside-click={() => {
showEdit.value = false showEdit.value = false
}} }}
@ -176,7 +205,7 @@ export default defineComponent(() => {
</div> </div>
</div> </div>
)} )}
</Transition> </div>
</div> </div>
)} )}
</Transition> </Transition>

View File

@ -6,6 +6,9 @@ import ThemeProvider from '@/utils/ThemeProvider'
import BlockSettings from '@/layout/grid/BlockSettings' import BlockSettings from '@/layout/grid/BlockSettings'
import SearchSetting from '@/layout/grid/SearchSetting' import SearchSetting from '@/layout/grid/SearchSetting'
import TimeSetting from '@/layout/grid/TimeSetting' import TimeSetting from '@/layout/grid/TimeSetting'
import SiderSetting from '@/layout/grid/SiderSetting'
import DockSetting from '@/layout/grid/DockSetting'
import Reset from '@/layout/grid/Reset'
export default defineComponent(() => { export default defineComponent(() => {
const router = useRouterStore() const router = useRouterStore()
@ -23,6 +26,12 @@ export default defineComponent(() => {
<SearchSetting /> <SearchSetting />
) : router.path === 'settings-time' ? ( ) : router.path === 'settings-time' ? (
<TimeSetting /> <TimeSetting />
) : router.path === 'settings-sider' ? (
<SiderSetting />
) : router.path === 'settings-dock' ? (
<DockSetting />
) : router.path === 'settings-reset' ? (
<Reset />
) : null} ) : null}
</ThemeProvider> </ThemeProvider>
</div> </div>

View File

@ -28,7 +28,9 @@ export default defineStore(
// 搜索 // 搜索
searchWidth: 30, searchWidth: 30,
searchRadius: 12, searchRadius: 12,
searchOpacity: 0.75 searchOpacity: 0.75,
// 侧边栏
siderDirection: 'left' as 'left' | 'right',
}) })
return { state, blockInner: computed(() => state.blockSize - 2 * state.blockPadding) } return { state, blockInner: computed(() => state.blockSize - 2 * state.blockPadding) }

View File

@ -51,7 +51,7 @@ export default defineComponent(() => {
onMounted(() => { onMounted(() => {
setInterval(() => { setInterval(() => {
currentIndex.value = currentIndex.value === list.value.length - 1 ? 0 : currentIndex.value + 1 currentIndex.value = currentIndex.value === list.value.length - 1 ? 0 : currentIndex.value + 1
}, 5000) }, 7000)
}) })
return () => ( return () => (
<div class="w-full h-full p-2 bg-[#17212d] "> <div class="w-full h-full p-2 bg-[#17212d] ">
@ -59,7 +59,7 @@ export default defineComponent(() => {
<div <div
class={'w-full h-full rounded-xl relative group'} class={'w-full h-full rounded-xl relative group'}
style={{ style={{
backgroundImage: `url('https://uetab.com/countdown-img/pic2.jpg')`, backgroundImage: `url('${current.value?.pic}')`,
backgroundSize: 'cover', backgroundSize: 'cover',
backgroundPosition: 'center', backgroundPosition: 'center',
backgroundRepeat: 'no-repeat' backgroundRepeat: 'no-repeat'