完成经典即玩小游戏
This commit is contained in:
parent
775ba48259
commit
d0ed386313
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -34,7 +34,7 @@ const layout = useLayoutStore()
|
|||
<SettingsOverlay />
|
||||
<SettingsButton />
|
||||
<Sider />
|
||||
<LoginModal v-if="router.path !== 'global-login'"/>
|
||||
<LoginModal v-if="router.path === 'global-login'"/>
|
||||
<Grid v-if="layout.ready" />
|
||||
<Dock />
|
||||
<div class="fixed z-40 right-[14%] top-8">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import CategoryTab from '@/utils/CategoryTab'
|
||||
import request from '@/utils/request'
|
||||
import { computed, defineComponent, inject, ref, watch } from 'vue'
|
||||
import { computed, defineComponent, inject, ref, watch } from 'vue'
|
||||
import clsx from 'clsx'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import { AddToToken } from './AdderPage'
|
||||
|
@ -9,9 +9,9 @@ import { frontAddress, ossBase } from '@/config'
|
|||
import dayjs from 'dayjs'
|
||||
import { generateRandomString } from '@/utils/tool'
|
||||
import MD5 from 'crypto-js/md5'
|
||||
const SECRET = 'A1Cv12olxT12dOE3xA1vPA=='
|
||||
const URL_ADDRESS = 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||
interface GameType {
|
||||
export const SECRET = 'A1Cv12olxT12dOE3xA1vPA=='
|
||||
export const URL_ADDRESS = 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||
export interface GameType {
|
||||
id: string
|
||||
name: string
|
||||
rom: string
|
||||
|
@ -21,7 +21,7 @@ interface GameType {
|
|||
despt: string
|
||||
icon: string
|
||||
}
|
||||
interface OtherGame {
|
||||
export interface OtherGame {
|
||||
id: number // 游戏ID
|
||||
category_ids: number[] // 分类ID数组
|
||||
rank: number // 排名
|
||||
|
@ -33,6 +33,32 @@ interface OtherGame {
|
|||
cover_url: string // 封面URL
|
||||
corner_mark: number // 角标标识
|
||||
}
|
||||
export const DefautGameTypeList = [
|
||||
{
|
||||
id: 'fc',
|
||||
type: '经典红白机',
|
||||
attr: 0,
|
||||
oridinal: 0
|
||||
},
|
||||
{
|
||||
id: 'md',
|
||||
type: '经典世嘉',
|
||||
attr: 1,
|
||||
oridinal: 1
|
||||
},
|
||||
{
|
||||
id: 'yiqiyoo',
|
||||
type: '休闲游戏',
|
||||
attr: 1,
|
||||
oridinal: 2
|
||||
},
|
||||
{
|
||||
id: 'gba',
|
||||
type: '经典GBA',
|
||||
attr: 3,
|
||||
oridinal: 3
|
||||
}
|
||||
]
|
||||
export const GameItem = defineComponent({
|
||||
props: {
|
||||
content: {
|
||||
|
@ -100,9 +126,9 @@ export const GameItem = defineComponent({
|
|||
id: uuid(),
|
||||
link: !props.content.rom.startsWith('http')
|
||||
? `${frontAddress}/emu/#/home?params=${JSON.stringify({
|
||||
...props.content,
|
||||
rom: ossBase + '/' + props.content.rom
|
||||
})}`
|
||||
...props.content,
|
||||
rom: ossBase + '/' + props.content.rom
|
||||
})}`
|
||||
: props.content.rom,
|
||||
name: '',
|
||||
label: props.content.name,
|
||||
|
@ -188,32 +214,7 @@ export default defineComponent(() => {
|
|||
<div class={'w-full h-full flex flex-col gap-y-4'}>
|
||||
<div class={'w-full '}>
|
||||
<CategoryTab
|
||||
list={[
|
||||
{
|
||||
id: 'fc',
|
||||
type: '经典红白机',
|
||||
attr: 0,
|
||||
oridinal: 0
|
||||
},
|
||||
{
|
||||
id: 'md',
|
||||
type: '经典世嘉',
|
||||
attr: 1,
|
||||
oridinal: 1
|
||||
},
|
||||
{
|
||||
id: 'yiqiyoo',
|
||||
type: '休闲游戏',
|
||||
attr: 1,
|
||||
oridinal: 2
|
||||
},
|
||||
{
|
||||
id: 'gba',
|
||||
type: '经典GBA',
|
||||
attr: 3,
|
||||
oridinal: 3
|
||||
}
|
||||
]}
|
||||
list={DefautGameTypeList}
|
||||
selectType={selectType.value}
|
||||
onUpdate:type={(e) => {
|
||||
selectType.value = e
|
||||
|
|
|
@ -10,6 +10,7 @@ import useTomatoStore, { musicList } from '@/widgets/work/useTomatoStore'
|
|||
import Search from '../header/search'
|
||||
import { Modal, Tooltip } from 'ant-design-vue'
|
||||
import { formatSeconds } from '@/utils/tool'
|
||||
import clsx from 'clsx'
|
||||
export const DefaultPageSetting = [
|
||||
{
|
||||
name: '游戏',
|
||||
|
@ -55,7 +56,6 @@ export default defineComponent(() => {
|
|||
watch(() =>
|
||||
store.remainingTime
|
||||
, (val) => {
|
||||
console.log(val);
|
||||
|
||||
if (val <= 0) {
|
||||
store.stopTomatoTime()
|
||||
|
@ -123,28 +123,33 @@ export default defineComponent(() => {
|
|||
}}>确定</button>
|
||||
</div>
|
||||
</Modal>
|
||||
{
|
||||
Array.from({ length: 60 }).map((_, idx) => (
|
||||
<div class={"bg-white w-[30px] h-[5px] absolute mt-[-2.5px] top-1/2"} style={{
|
||||
transformOrigin: '250px',
|
||||
borderRadius: '3px',
|
||||
transform: `rotateZ(${idx * 6}deg)`
|
||||
<div class={"w-full h-full absolute z-0 rotate-90"}>
|
||||
{
|
||||
Array.from({ length: 60 }).map((_, idx) => (
|
||||
<div class={clsx(" w-[30px] h-[5px] absolute mt-[-2.5px] top-1/2",
|
||||
(((60 * 15 - store.remainingTime) / 15) >= idx) ? "bg-white" : "bg-white/50"
|
||||
)} style={{
|
||||
transformOrigin: '250px',
|
||||
borderRadius: '3px',
|
||||
transform: `rotateZ(${idx * 6}deg)`
|
||||
|
||||
}}>
|
||||
}}>
|
||||
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
))
|
||||
}
|
||||
<div class={"w-[500px] flex justify-center flex-col items-center gap-y-3 h-full text-white "}>
|
||||
<span class={"text-[24px] leading-[36px]"}>专注中</span>
|
||||
<span class={"font-din text-[82px] font-bold leading-[115px]"}>{!store.state.isStart ? '15:00' : formatSeconds(store.remainingTime)}</span>
|
||||
<div class={"relative"}>
|
||||
<div class={"aboslute w-[370px]"}>
|
||||
<div class={"aboslute w-[370px] z-10"}>
|
||||
<Search isMini></Search>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class={"w-full flex gap-x-4 justify-center mt-5"}>
|
||||
<div class={"w-full flex gap-x-4 justify-center z-[1] mt-5"}>
|
||||
<Tooltip title={"返回工作模式"}>
|
||||
<div
|
||||
onClick={() => {
|
||||
|
|
|
@ -14,7 +14,7 @@ export default defineComponent({
|
|||
const router = useRouterStore()
|
||||
return () => (
|
||||
<div
|
||||
class="absolute left-0 -bottom-2 translate-y-full w-full rounded-lg bg-white/60 backdrop-blur shadow-lg p-4 flex flex-wrap gap-4"
|
||||
class="absolute left-0 -bottom-2 z-10 translate-y-full w-full rounded-lg bg-white/60 backdrop-blur shadow-lg p-4 flex flex-wrap gap-4"
|
||||
v-outside-click={() => {
|
||||
search.showSearchConfig = false
|
||||
}}
|
||||
|
|
|
@ -11,7 +11,7 @@ export default defineComponent(() => {
|
|||
const settings = useSettingsStore()
|
||||
return () =>
|
||||
settings.state.showHistory && (
|
||||
<div class="absolute left-0 -bottom-2 translate-y-full w-full rounded-lg bg-white/60 backdrop-blur shadow-lg p-4">
|
||||
<div class="absolute left-0 -bottom-2 translate-y-full w-full rounded-lg z-10 bg-white/60 backdrop-blur shadow-lg p-4">
|
||||
{searchConfig.history.map((item, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
|
|
|
@ -1,9 +1,167 @@
|
|||
import { frontAddress, ossBase } from '@/config'
|
||||
import { DefautGameTypeList, SECRET, type GameType, type OtherGame } from '@/layout/adder/GameAdder'
|
||||
import request from '@/utils/request'
|
||||
import { generateRandomString } from '@/utils/tool'
|
||||
import clsx from 'clsx'
|
||||
import { MD5 } from 'crypto-js'
|
||||
import dayjs from 'dayjs'
|
||||
import { ref, watch } from 'vue'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
const selectType = ref('fc')
|
||||
const appList = ref<GameType[]>([])
|
||||
const hoverId = ref(0)
|
||||
const loading = ref(false)
|
||||
const fetchGame = async (page: number) => {
|
||||
const parems = `nonce=${generateRandomString(8)}&pid=PIDc8uT24mpo×tamp=${dayjs().unix()}`
|
||||
const sign = MD5(parems + SECRET).toString()
|
||||
const response = await fetch(
|
||||
`https://ge.yiqiyoo.com/game/v2/third-part/games?${parems}&sign=${sign}&paginate.limit=99&paginate.page=${page}`
|
||||
)
|
||||
const res = await response.json()
|
||||
return res.data.items
|
||||
}
|
||||
watch(
|
||||
selectType,
|
||||
(val) => {
|
||||
console.log(val);
|
||||
appList.value = []
|
||||
loading.value = true
|
||||
|
||||
if (val !== 'yiqiyoo') {
|
||||
request<GameType[]>('GET', `/api/games?type=${val}`)
|
||||
.then((res) => {
|
||||
appList.value = res
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
} else {
|
||||
try {
|
||||
Promise.all([fetchGame(1)]).then((res) => {
|
||||
const resData = res.flat() as OtherGame[]
|
||||
appList.value = resData.map((el) => ({
|
||||
id: el.id.toString(),
|
||||
name: el.name,
|
||||
despt: el.short_description,
|
||||
icon: el.icon,
|
||||
rom: el.url,
|
||||
playstation: el.url,
|
||||
hot: el.rank,
|
||||
category: el.category_ids[0].toString()
|
||||
}))
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
return () => (
|
||||
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
|
||||
large
|
||||
<div class="w-full h-full bg-[#ecfbff] flex flex-col backdrop-blur-sm p-[8px]" style={{
|
||||
background: 'rgba(23,33,45,.6)'
|
||||
}}
|
||||
onClick={() => {
|
||||
|
||||
}}
|
||||
>
|
||||
<div class={"w-full h-full rounded-2xl backdrop-blur-lg px-4 flex flex-col"} style={{
|
||||
background: 'rgba(23,33,46,.8)'
|
||||
}}>
|
||||
<div class={"w-full flex justify-between items-center"}>
|
||||
<div class={"flex gap-x-2 h-[36px]"}>
|
||||
{
|
||||
DefautGameTypeList.map(item => (
|
||||
<div
|
||||
onClick={() => {
|
||||
selectType.value = item.id
|
||||
}}
|
||||
class={clsx("flex items-center jusitfy-center relative py-4 text-[13px]",
|
||||
selectType.value === item.id ? "text-[#589fff]" : " text-[#589fffcc]"
|
||||
)} >
|
||||
{item.type}
|
||||
{
|
||||
selectType.value === item.id &&
|
||||
<div class={"bg-[#589fff] w-[22px] h-[4px] absolute top-0 left-1/2 -translate-x-1/2"} style={{
|
||||
borderRadius: '0 0 12px 12px',
|
||||
|
||||
}}></div>
|
||||
}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<span class={"text-[#ddd]/70 text-[14px]"}>查看更多</span>
|
||||
|
||||
</div>
|
||||
{
|
||||
!loading.value &&
|
||||
|
||||
<div class={"flex-1 h-0 w-full overflow-y-auto scrollbar-hide"}>
|
||||
<div class={"w-full flex flex-col"}>
|
||||
{
|
||||
appList.value.filter((_, index) => index < 10).map((item, idx) => (
|
||||
<div class={"flex items-center gap-x-2 pl-[8px] py-[4px] rounded-lg"}
|
||||
onMouseenter={() => {
|
||||
hoverId.value = idx
|
||||
}}
|
||||
style={{
|
||||
background: hoverId.value === idx ? "rgba(61,80,105,.8)" : "transparent"
|
||||
}}>
|
||||
<div class={clsx("w-[22px] h-[22px] bg-white/10 flex items-center justify-center rounded",
|
||||
idx === 0 ? "text-red-500" : idx === 1 ? "text-orange-500" : idx === 2 ? "text-yellow-400" : "text-white"
|
||||
)}>{idx + 1}</div>
|
||||
<div class={"flex flex-1"}>
|
||||
{
|
||||
hoverId.value === idx ?
|
||||
<div class={"w-full h-full flex justify-between pr-4 items-center"}>
|
||||
<div class={"flex gap-x-3"}>
|
||||
<img
|
||||
class={"w-[36px] h-[36px] rounded "}
|
||||
src={item.icon.startsWith('http')
|
||||
? item.icon
|
||||
: ossBase + '/' + item.icon}></img>
|
||||
<div class={"flex flex-col"}>
|
||||
<span class={"w-[150px] text-[13px] text-white text-ellipsis whitespace-nowrap overflow-hidden"}>{item.name}</span>
|
||||
<span class={"w-[150px] text-[13px] text-white/50 text-ellipsis whitespace-nowrap overflow-hidden"}>{item.despt}</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
window.open(
|
||||
!item.rom.startsWith('http')
|
||||
? `${frontAddress}/emu/#/home?params=${JSON.stringify({
|
||||
...item,
|
||||
rom: ossBase + '/' + item.rom
|
||||
})}`
|
||||
: item.rom,
|
||||
)
|
||||
|
||||
}}
|
||||
class={"bg-[#317aff] w-[76px] h-[26px] rounded text-white text-[12px]"}>立即游玩</button>
|
||||
</div> :
|
||||
<div class={"w-full h-full flex gap-x-4"}>
|
||||
<span class={"w-[80px] text-[13px] text-white text-ellipsis whitespace-nowrap overflow-hidden"}>{item.name}</span>
|
||||
<span class={"w-[180px] text-[13px] text-white/50 text-ellipsis whitespace-nowrap overflow-hidden"}>{item.despt}</span>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
|
||||
return () => (
|
||||
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
|
||||
middle
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -1,12 +0,0 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => (
|
||||
<div
|
||||
class="w-full h-full bg-red-50 flex "
|
||||
style={{
|
||||
background: 'linear-gradient(180deg,#dcefff 0%,#e7ecff 100%)'
|
||||
}}
|
||||
></div>
|
||||
)
|
||||
})
|
|
@ -1,14 +0,0 @@
|
|||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent(() => {
|
||||
return () => (
|
||||
<div
|
||||
class="w-full h-full items-center pl-3 gap-x-2 flex py-3 text-white"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg,#5996ff 0%,#4862ff 100%)'
|
||||
}}
|
||||
>
|
||||
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -3,23 +3,11 @@ import type { Widget } from '..'
|
|||
|
||||
export default {
|
||||
name: 'gameNews',
|
||||
label: '游戏资讯',
|
||||
description: '游戏资讯',
|
||||
icon: '/tab/icons/game_news_icon.png',
|
||||
modal: asyncLoader(() => import('./Modal')),
|
||||
label: '经典即玩游戏',
|
||||
description: '经典即玩游戏',
|
||||
icon: '/tab/icons/classicPlay.png',
|
||||
modal: null,
|
||||
list: [
|
||||
{
|
||||
w: 2,
|
||||
h: 1,
|
||||
label: '小',
|
||||
component: asyncLoader(() => import('./Small'))
|
||||
},
|
||||
{
|
||||
w: 2,
|
||||
h: 2,
|
||||
label: '中',
|
||||
component: asyncLoader(() => import('./Middle'))
|
||||
},
|
||||
{
|
||||
w: 4,
|
||||
h: 2,
|
||||
|
|
|
@ -9,6 +9,7 @@ import hotspot from './hotspot'
|
|||
import constellation from './constellation'
|
||||
import gameVideo from './gameVideo'
|
||||
import work from './work'
|
||||
import game from './game'
|
||||
export interface Widget {
|
||||
name: string // 小组件类型唯一标识
|
||||
label: string // 小组件名称
|
||||
|
@ -23,4 +24,4 @@ export interface Widget {
|
|||
}[] // 不同尺寸小组件块
|
||||
}
|
||||
|
||||
export default [calendar, weather, weApply, gameNews, eat, discount, hotspot, constellation, gameVideo, work] as Widget[]
|
||||
export default [game, calendar, weather, weApply, gameNews, eat, discount, hotspot, constellation, gameVideo, work] as Widget[]
|
||||
|
|
|
@ -8,17 +8,18 @@ export default {
|
|||
icon: '/tab/icons/work/tomato_work_icon.png',
|
||||
modal: asyncLoader(() => import('./Modal')),
|
||||
list: [
|
||||
{
|
||||
w: 4,
|
||||
h: 2,
|
||||
label: '大',
|
||||
component: asyncLoader(() => import('./Large'))
|
||||
},
|
||||
{
|
||||
w: 2,
|
||||
h: 1,
|
||||
label: '小',
|
||||
component: asyncLoader(() => import('./Small'))
|
||||
},
|
||||
{
|
||||
w: 4,
|
||||
h: 2,
|
||||
label: '大',
|
||||
component: asyncLoader(() => import('./Large'))
|
||||
}
|
||||
|
||||
]
|
||||
} as Widget
|
||||
|
|
Loading…
Reference in New Issue