添加网址导航-缺少搜索功能
This commit is contained in:
parent
e8d0a236dd
commit
ade0c79a3c
|
@ -81,6 +81,7 @@ export default defineComponent(() => {
|
||||||
const isGame = computed(() => layout.state.current === 0)
|
const isGame = computed(() => layout.state.current === 0)
|
||||||
const store = useAdderPageStore()
|
const store = useAdderPageStore()
|
||||||
const addTo = ref(layout.state.currentPage)
|
const addTo = ref(layout.state.currentPage)
|
||||||
|
|
||||||
provide(AddToToken, addTo)
|
provide(AddToToken, addTo)
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
store.type = 1
|
store.type = 1
|
||||||
|
@ -145,7 +146,27 @@ export default defineComponent(() => {
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Input.Search class="w-[200px]" placeholder="搜索组件或网站" />
|
<Input.Search
|
||||||
|
onSearch={(e) => {
|
||||||
|
if (store.type === 1) {
|
||||||
|
store.search(e)
|
||||||
|
} else if (store.type === 0) {
|
||||||
|
store.widgetSearchWords = e
|
||||||
|
} else if (store.type === 3) {
|
||||||
|
store.gameSearch = e
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
class="w-[220px]"
|
||||||
|
placeholder={
|
||||||
|
store.type === 0
|
||||||
|
? '搜索想要添加的组件'
|
||||||
|
: store.type === 1
|
||||||
|
? '搜索想要添加的网址导航'
|
||||||
|
: store.type === 2
|
||||||
|
? ''
|
||||||
|
: '搜索想要添加的游戏'
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
<div class="w-full h-0 flex-grow p-6">
|
<div class="w-full h-0 flex-grow p-6">
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { frontAddress, ossBase } from '@/config'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { generateRandomString } from '@/utils/tool'
|
import { generateRandomString } from '@/utils/tool'
|
||||||
import MD5 from 'crypto-js/md5'
|
import MD5 from 'crypto-js/md5'
|
||||||
|
import useAdderPageStore from './useAdderPageStore'
|
||||||
export const SECRET = 'A1Cv12olxT12dOE3xA1vPA=='
|
export const SECRET = 'A1Cv12olxT12dOE3xA1vPA=='
|
||||||
export const URL_ADDRESS = 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
export const URL_ADDRESS = 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||||
export interface GameType {
|
export interface GameType {
|
||||||
|
@ -126,9 +127,9 @@ export const GameItem = defineComponent({
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
link: !props.content.rom.startsWith('http')
|
link: !props.content.rom.startsWith('http')
|
||||||
? `${frontAddress}/emu/#/home?params=${JSON.stringify({
|
? `${frontAddress}/emu/#/home?params=${JSON.stringify({
|
||||||
...props.content,
|
...props.content,
|
||||||
rom: ossBase + '/' + props.content.rom
|
rom: ossBase + '/' + props.content.rom
|
||||||
})}`
|
})}`
|
||||||
: props.content.rom,
|
: props.content.rom,
|
||||||
name: '',
|
name: '',
|
||||||
label: props.content.name,
|
label: props.content.name,
|
||||||
|
@ -159,6 +160,7 @@ export default defineComponent(() => {
|
||||||
const isGame = computed(() => layout.state.current === 0)
|
const isGame = computed(() => layout.state.current === 0)
|
||||||
const appList = ref<GameType[]>([])
|
const appList = ref<GameType[]>([])
|
||||||
const selectType = ref('fc')
|
const selectType = ref('fc')
|
||||||
|
const store = useAdderPageStore()
|
||||||
const fetchGame = async (page: number) => {
|
const fetchGame = async (page: number) => {
|
||||||
const parems = `nonce=${generateRandomString(8)}&pid=PIDc8uT24mpo×tamp=${dayjs().unix()}`
|
const parems = `nonce=${generateRandomString(8)}&pid=PIDc8uT24mpo×tamp=${dayjs().unix()}`
|
||||||
const sign = MD5(parems + SECRET).toString()
|
const sign = MD5(parems + SECRET).toString()
|
||||||
|
@ -169,11 +171,11 @@ export default defineComponent(() => {
|
||||||
return res.data.items
|
return res.data.items
|
||||||
}
|
}
|
||||||
watch(
|
watch(
|
||||||
selectType,
|
[selectType, () => store.gameSearch],
|
||||||
(val) => {
|
(val) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if (val !== 'yiqiyoo') {
|
if (val[0] !== 'yiqiyoo') {
|
||||||
request<GameType[]>('GET', `/api/games?type=${val}`)
|
request<GameType[]>('GET', `/api/games?type=${val[0]}&keyword=${val[1]}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
appList.value = res
|
appList.value = res
|
||||||
})
|
})
|
||||||
|
@ -212,41 +214,44 @@ export default defineComponent(() => {
|
||||||
)
|
)
|
||||||
return () => (
|
return () => (
|
||||||
<div class={'w-full h-full flex flex-col gap-y-4'}>
|
<div class={'w-full h-full flex flex-col gap-y-4'}>
|
||||||
<div class={'w-full '}>
|
{!store.gameSearch && (
|
||||||
<CategoryTab
|
<div class={'w-full '}>
|
||||||
list={DefautGameTypeList}
|
<CategoryTab
|
||||||
selectType={selectType.value}
|
list={DefautGameTypeList}
|
||||||
onUpdate:type={(e) => {
|
selectType={selectType.value}
|
||||||
selectType.value = e
|
onUpdate:type={(e) => {
|
||||||
}}
|
selectType.value = e
|
||||||
v-slots={{
|
}}
|
||||||
select: (text: string) => (
|
v-slots={{
|
||||||
<button
|
select: (text: string) => (
|
||||||
class={clsx(
|
<button
|
||||||
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
class={clsx(
|
||||||
isGame.value
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
||||||
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
isGame.value
|
||||||
: 'text-white bg-[#D6D6D6] bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
)}
|
: 'text-white bg-[#D6D6D6] bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
>
|
)}
|
||||||
{text}
|
>
|
||||||
</button>
|
{text}
|
||||||
),
|
</button>
|
||||||
unSelect: (text: string) => (
|
),
|
||||||
<button
|
unSelect: (text: string) => (
|
||||||
class={clsx(
|
<button
|
||||||
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
class={clsx(
|
||||||
isGame.value
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
||||||
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
isGame.value
|
||||||
: 'text-[#666] hover:bg-black/10 bg-black/[0.05] hover:bg-[#f0ecec]'
|
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
||||||
)}
|
: 'text-[#666] hover:bg-black/10 bg-black/[0.05] hover:bg-[#f0ecec]'
|
||||||
>
|
)}
|
||||||
{text}
|
>
|
||||||
</button>
|
{text}
|
||||||
)
|
</button>
|
||||||
}}
|
)
|
||||||
></CategoryTab>
|
}}
|
||||||
</div>
|
></CategoryTab>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div class={'h-0 flex-1 w-full'}>
|
<div class={'h-0 flex-1 w-full'}>
|
||||||
<div class={'w-full h-full overflow-y-scroll scrollbar-hide'}>
|
<div class={'w-full h-full overflow-y-scroll scrollbar-hide'}>
|
||||||
{!loading.value ? (
|
{!loading.value ? (
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
import CategoryTab from '@/utils/CategoryTab'
|
import CategoryTab from '@/utils/CategoryTab'
|
||||||
import request from '@/utils/request'
|
import { computed, defineComponent, inject } from 'vue'
|
||||||
import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue'
|
|
||||||
import type { BackgroundType } from '../background/BackgroundSwtich'
|
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import useLayoutStore from '../useLayoutStore'
|
import useLayoutStore from '../useLayoutStore'
|
||||||
import { AddToToken } from './AdderPage'
|
import { AddToToken } from './AdderPage'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
import useAdderPageStore, { type HotAppType } from './useAdderPageStore'
|
||||||
|
|
||||||
interface HotAppCategoryType {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
ordinal: number
|
|
||||||
}
|
|
||||||
interface HotAppType {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
url: string
|
|
||||||
ordinal: number
|
|
||||||
desc: string
|
|
||||||
icon: string
|
|
||||||
background: string
|
|
||||||
}
|
|
||||||
export const LinkItem = defineComponent({
|
export const LinkItem = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
content: {
|
content: {
|
||||||
|
@ -34,10 +19,13 @@ export const LinkItem = defineComponent({
|
||||||
const addTo = inject(AddToToken)
|
const addTo = inject(AddToToken)
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={clsx(' w-full h-full rounded-lg relative flex flex-col justify-between overflow-hidden shadow p-4', {
|
class={clsx(
|
||||||
'bg-white/20': isGame.value,
|
' w-full h-full rounded-lg relative flex flex-col justify-between overflow-hidden shadow p-4',
|
||||||
'bg-white/80': !isGame.value
|
{
|
||||||
})}
|
'bg-white/20': isGame.value,
|
||||||
|
'bg-white/80': !isGame.value
|
||||||
|
}
|
||||||
|
)}
|
||||||
key={props.content.name}
|
key={props.content.name}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -110,6 +98,9 @@ export const LinkItem = defineComponent({
|
||||||
},
|
},
|
||||||
addTo?.value
|
addTo?.value
|
||||||
)
|
)
|
||||||
|
if (addTo?.value) {
|
||||||
|
layout.state.currentPage = addTo?.value
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
添加
|
添加
|
||||||
|
@ -122,78 +113,55 @@ export const LinkItem = defineComponent({
|
||||||
|
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
const layout = useLayoutStore()
|
const layout = useLayoutStore()
|
||||||
const loading = ref(false)
|
|
||||||
const isGame = computed(() => layout.state.current === 0)
|
const isGame = computed(() => layout.state.current === 0)
|
||||||
const appList = ref<HotAppType[]>([])
|
|
||||||
const categoryList = ref<BackgroundType[]>([])
|
|
||||||
const selectType = ref('')
|
|
||||||
onMounted(() => {
|
|
||||||
request<HotAppCategoryType[]>('GET', '/api/app/hotAppTypes').then((res) => {
|
|
||||||
categoryList.value = res.map((el) => ({
|
|
||||||
id: el.id,
|
|
||||||
oridinal: el.ordinal,
|
|
||||||
type: el.name,
|
|
||||||
attr: 0
|
|
||||||
}))
|
|
||||||
|
|
||||||
selectType.value = res[0].id
|
const store = useAdderPageStore()
|
||||||
})
|
|
||||||
})
|
|
||||||
watch(selectType, (val) => {
|
|
||||||
loading.value = true
|
|
||||||
|
|
||||||
request<HotAppType[]>('GET', `/api/app/hotApps?hotAppsId=${val}`)
|
|
||||||
.then((res) => {
|
|
||||||
appList.value = res
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
loading.value = false
|
|
||||||
}, 200)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class={'w-full h-full flex flex-col gap-y-4'}>
|
<div class={'w-full h-full flex flex-col gap-y-4'}>
|
||||||
<div class={'w-full '}>
|
{!store.isSearch && (
|
||||||
<CategoryTab
|
<div class={'w-full '}>
|
||||||
list={categoryList.value}
|
<CategoryTab
|
||||||
selectType={selectType.value}
|
list={store.categoryList}
|
||||||
onUpdate:type={(e) => {
|
selectType={store.selectType}
|
||||||
selectType.value = e
|
onUpdate:type={(e) => {
|
||||||
}}
|
store.selectType = e
|
||||||
v-slots={{
|
}}
|
||||||
select: (text: string) => (
|
v-slots={{
|
||||||
<button
|
select: (text: string) => (
|
||||||
class={clsx(
|
<button
|
||||||
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
class={clsx(
|
||||||
isGame.value
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
||||||
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
isGame.value
|
||||||
: 'text-white bg-[#D6D6D6] bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
)}
|
: 'text-white bg-[#D6D6D6] bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
>
|
)}
|
||||||
{text}
|
>
|
||||||
</button>
|
{text}
|
||||||
),
|
</button>
|
||||||
unSelect: (text: string) => (
|
),
|
||||||
<button
|
unSelect: (text: string) => (
|
||||||
class={clsx(
|
<button
|
||||||
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
class={clsx(
|
||||||
isGame.value
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
||||||
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
isGame.value
|
||||||
: 'text-[#666] hover:bg-black/10 bg-black/[0.05] hover:bg-[#f0ecec]'
|
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
||||||
)}
|
: 'text-[#666] hover:bg-black/10 bg-black/[0.05] hover:bg-[#f0ecec]'
|
||||||
>
|
)}
|
||||||
{text}
|
>
|
||||||
</button>
|
{text}
|
||||||
)
|
</button>
|
||||||
}}
|
)
|
||||||
></CategoryTab>
|
}}
|
||||||
</div>
|
></CategoryTab>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div class={'h-0 flex-1 w-full'}>
|
<div class={'h-0 flex-1 w-full'}>
|
||||||
<div class={'w-full h-full overflow-y-scroll scrollbar-hide'}>
|
<div class={'w-full h-full overflow-y-scroll scrollbar-hide'}>
|
||||||
{!loading.value ? (
|
{!store.loading ? (
|
||||||
<div class={'w-full grid grid-cols-3 gap-4 '} style="grid-auto-rows: 120px">
|
<div class={'w-full grid grid-cols-3 gap-4 '} style="grid-auto-rows: 120px">
|
||||||
{appList.value.map((el) => (
|
{store.appList.map((el) => (
|
||||||
<LinkItem content={el}></LinkItem>
|
<LinkItem content={el}></LinkItem>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import widgetList, { type Widget } from '@/widgets'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { AddToToken } from './AdderPage'
|
import { AddToToken } from './AdderPage'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
import useAdderPageStore from './useAdderPageStore'
|
||||||
|
|
||||||
export const WidgetItem = defineComponent({
|
export const WidgetItem = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
|
@ -32,10 +33,7 @@ export const WidgetItem = defineComponent({
|
||||||
key={props.content.name}
|
key={props.content.name}
|
||||||
>
|
>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<img
|
<img src={props.content.icon} class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg" />
|
||||||
src={props.content.icon}
|
|
||||||
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
|
||||||
/>
|
|
||||||
<div class="px-2 w-0 flex-grow ">
|
<div class="px-2 w-0 flex-grow ">
|
||||||
<div
|
<div
|
||||||
class={clsx('text text-sm mb-[2px]', {
|
class={clsx('text text-sm mb-[2px]', {
|
||||||
|
@ -120,18 +118,18 @@ export const WidgetItem = defineComponent({
|
||||||
|
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
const layout = useLayoutStore()
|
const layout = useLayoutStore()
|
||||||
|
const store = useAdderPageStore()
|
||||||
return () => (
|
return () => (
|
||||||
<div class="absolute left-0 top-0 w-full h-full overflow-y-auto scrollbar-hide gap-4">
|
<div class="absolute left-0 top-0 w-full h-full overflow-y-auto scrollbar-hide gap-4">
|
||||||
<div class="w-full grid grid-cols-3 grid-flow-row-dense gap-4" style="grid-auto-rows: 120px">
|
<div class="w-full grid grid-cols-3 grid-flow-row-dense gap-4" style="grid-auto-rows: 120px">
|
||||||
{
|
{layout.state.current !== 1
|
||||||
layout.state.current !== 1 ?
|
? widgetList
|
||||||
widgetList.filter(val => val.name !== 'tomato_work').map((el) => (
|
.filter((val) => val.name !== 'tomato_work')
|
||||||
<WidgetItem content={el} key={el.name} />
|
.filter((val) => val.label.includes(store.widgetSearchWords))
|
||||||
)) :
|
.map((el) => <WidgetItem content={el} key={el.name} />)
|
||||||
widgetList.map((el) => (
|
: widgetList
|
||||||
<WidgetItem content={el} key={el.name} />
|
.filter((val) => val.label.includes(store.widgetSearchWords))
|
||||||
))
|
.map((el) => <WidgetItem content={el} key={el.name} />)}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,83 @@
|
||||||
import { defineStore } from "pinia";
|
import request from '@/utils/request'
|
||||||
import { ref } from "vue";
|
import { defineStore } from 'pinia'
|
||||||
|
import { watch } from 'vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import type { BackgroundType } from '../background/BackgroundSwtich'
|
||||||
|
export interface HotAppType {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
ordinal: number
|
||||||
|
desc: string
|
||||||
|
icon: string
|
||||||
|
background: string
|
||||||
|
}
|
||||||
|
export interface HotAppCategoryType {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
ordinal: number
|
||||||
|
}
|
||||||
|
export default defineStore('adderPage', () => {
|
||||||
|
const type = ref(1)
|
||||||
|
const selectType = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
const appList = ref<HotAppType[]>([])
|
||||||
|
const categoryList = ref<BackgroundType[]>([])
|
||||||
|
const isSearch = ref(false)
|
||||||
|
const widgetSearchWords = ref('')
|
||||||
|
const gameSearch = ref('')
|
||||||
|
request<HotAppCategoryType[]>('GET', '/api/app/hotAppTypes').then((res) => {
|
||||||
|
categoryList.value = res.map((el) => ({
|
||||||
|
id: el.id,
|
||||||
|
oridinal: el.ordinal,
|
||||||
|
type: el.name,
|
||||||
|
attr: 0
|
||||||
|
}))
|
||||||
|
|
||||||
export default defineStore("adderPage", () => {
|
selectType.value = res[0].id
|
||||||
const type = ref(1)
|
})
|
||||||
return {
|
watch(selectType, (val) => {
|
||||||
type
|
getApps(val)
|
||||||
|
})
|
||||||
|
const getApps = (_selectType: string) => {
|
||||||
|
loading.value = true
|
||||||
|
request<HotAppType[]>('GET', `/api/app/hotApps?hotAppsId=${_selectType}`)
|
||||||
|
.then((res) => {
|
||||||
|
appList.value = res
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 200)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const search = (keywords: string) => {
|
||||||
|
if (keywords === '') {
|
||||||
|
isSearch.value = false
|
||||||
|
getApps(selectType.value)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
})
|
isSearch.value = true
|
||||||
|
request<HotAppType[]>('GET', `/api/app/hotApp/search?keyword=${keywords}`)
|
||||||
|
.then((res) => {
|
||||||
|
appList.value = res
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 200)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
widgetSearchWords,
|
||||||
|
categoryList,
|
||||||
|
appList,
|
||||||
|
loading,
|
||||||
|
selectType,
|
||||||
|
search,
|
||||||
|
isSearch,
|
||||||
|
gameSearch
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue