Compare commits
2 Commits
4f571eed13
...
d7557dc318
| Author | SHA1 | Date |
|---|---|---|
|
|
d7557dc318 | |
|
|
583b296ace |
|
|
@ -19,6 +19,7 @@
|
||||||
"ali-oss": "^6.21.0",
|
"ali-oss": "^6.21.0",
|
||||||
"ant-design-vue": "4.x",
|
"ant-design-vue": "4.x",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
|
|
@ -41,6 +42,7 @@
|
||||||
"@rushstack/eslint-patch": "^1.8.0",
|
"@rushstack/eslint-patch": "^1.8.0",
|
||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.4",
|
||||||
"@types/ali-oss": "^6.16.11",
|
"@types/ali-oss": "^6.16.11",
|
||||||
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/node": "^20.14.5",
|
"@types/node": "^20.14.5",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@types/ua-parser-js": "^0.7.39",
|
"@types/ua-parser-js": "^0.7.39",
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -2,8 +2,13 @@ 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://btab.oss-cn-hangzhou.aliyuncs.com'
|
? 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||||
: 'http://btab.oss-cn-hangzhou.aliyuncs.com'
|
: 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||||
|
|
||||||
|
// 前端地址
|
||||||
|
export const frontAddress = import.meta.env.PROD
|
||||||
|
? 'http://goosetab.com'
|
||||||
|
: 'http://goosetab.com'
|
||||||
|
|
||||||
// oss cdn 加速地址
|
// oss cdn 加速地址
|
||||||
export const ossCdnBase = import.meta.env.PROD ? ossBase : ossBase
|
export const ossCdnBase = import.meta.env.PROD ? ossBase : ossBase
|
||||||
|
|
|
||||||
|
|
@ -154,17 +154,15 @@ export default defineComponent(() => {
|
||||||
</Form>
|
</Form>
|
||||||
<div class="w-full h-0 flex-grow p-6">
|
<div class="w-full h-0 flex-grow p-6">
|
||||||
<div class="w-full h-full relative">
|
<div class="w-full h-full relative">
|
||||||
<Transition>
|
{type.value === 0 ? (
|
||||||
{type.value === 0 ? (
|
<WidgetAdder />
|
||||||
<WidgetAdder />
|
) : type.value === 1 ? (
|
||||||
) : type.value === 1 ? (
|
<HotAdder />
|
||||||
<HotAdder />
|
) : type.value === 2 ? (
|
||||||
) : type.value === 2 ? (
|
<CustomAdder />
|
||||||
<CustomAdder />
|
) : (
|
||||||
) : (
|
<GameAdder />
|
||||||
<GameAdder />
|
)}
|
||||||
)}
|
|
||||||
</Transition>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,11 @@ 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 { Button } from 'ant-design-vue'
|
import { Button } from 'ant-design-vue'
|
||||||
|
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'
|
const URL_ADDRESS = 'http://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||||
interface GameType {
|
interface GameType {
|
||||||
id: string
|
id: string
|
||||||
|
|
@ -18,6 +23,18 @@ interface GameType {
|
||||||
despt: string
|
despt: string
|
||||||
icon: string
|
icon: string
|
||||||
}
|
}
|
||||||
|
interface OtherGame {
|
||||||
|
id: number // 游戏ID
|
||||||
|
category_ids: number[] // 分类ID数组
|
||||||
|
rank: number // 排名
|
||||||
|
name: string // 游戏名称
|
||||||
|
short_description: string // 简短描述
|
||||||
|
description: string // 详细描述
|
||||||
|
url: string // 游戏详情链接
|
||||||
|
icon: string // 图标URL
|
||||||
|
cover_url: string // 封面URL
|
||||||
|
corner_mark: number // 角标标识
|
||||||
|
}
|
||||||
export const GameItem = defineComponent({
|
export const GameItem = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
content: {
|
content: {
|
||||||
|
|
@ -31,7 +48,7 @@ export const GameItem = defineComponent({
|
||||||
const addTo = inject(AddToToken)
|
const addTo = inject(AddToToken)
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={clsx(' w-full h-full rounded-lg flex flex-col justify-between shadow p-4', {
|
class={clsx(' w-full h-full rounded-lg flex flex-col justify-between shadow p-4 relative', {
|
||||||
'bg-white/20': isGame.value,
|
'bg-white/20': isGame.value,
|
||||||
'bg-white/80': !isGame.value
|
'bg-white/80': !isGame.value
|
||||||
})}
|
})}
|
||||||
|
|
@ -39,7 +56,12 @@ export const GameItem = defineComponent({
|
||||||
>
|
>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<img
|
<img
|
||||||
src={props.content.icon.replace('res/game', URL_ADDRESS)}
|
loading="lazy"
|
||||||
|
src={
|
||||||
|
props.content.icon.startsWith('http')
|
||||||
|
? props.content.icon
|
||||||
|
: URL_ADDRESS + '/' + props.content.icon
|
||||||
|
}
|
||||||
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
||||||
style={{
|
style={{
|
||||||
background: props.content.icon
|
background: props.content.icon
|
||||||
|
|
@ -48,7 +70,7 @@ export const GameItem = defineComponent({
|
||||||
|
|
||||||
<div class="px-2 w-0 flex-grow">
|
<div class="px-2 w-0 flex-grow">
|
||||||
<div
|
<div
|
||||||
class={clsx('text text-sm', {
|
class={clsx('text text-sm text-ellipsis overflow-hidden whitespace-nowrap', {
|
||||||
'text-white': isGame.value,
|
'text-white': isGame.value,
|
||||||
'text-black/80': !isGame.value
|
'text-black/80': !isGame.value
|
||||||
})}
|
})}
|
||||||
|
|
@ -78,14 +100,21 @@ export const GameItem = defineComponent({
|
||||||
layout.addBlock(
|
layout.addBlock(
|
||||||
{
|
{
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
link: '',
|
link: !props.content.rom.startsWith('http')
|
||||||
name: props.content.name,
|
? `${frontAddress}/emu/#/home?params=${JSON.stringify({
|
||||||
|
...props.content,
|
||||||
|
rom: ossBase + '/' + props.content.rom
|
||||||
|
})}`
|
||||||
|
: props.content.rom,
|
||||||
|
name: '',
|
||||||
label: props.content.name,
|
label: props.content.name,
|
||||||
icon: '',
|
icon: props.content.icon.startsWith('http')
|
||||||
|
? props.content.icon
|
||||||
|
: URL_ADDRESS + '/' + props.content.icon,
|
||||||
text: '',
|
text: '',
|
||||||
background: '',
|
background: '',
|
||||||
color: '',
|
color: '',
|
||||||
w: 1,
|
w: props.content.rom.startsWith('http') ? 1 : 2,
|
||||||
h: 1
|
h: 1
|
||||||
},
|
},
|
||||||
addTo?.value
|
addTo?.value
|
||||||
|
|
@ -106,21 +135,53 @@ 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 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(
|
watch(
|
||||||
selectType,
|
selectType,
|
||||||
(val) => {
|
(val) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
if (val !== 'yiqiyoo') {
|
||||||
request<GameType[]>('GET', `/api/games?type=${val}`)
|
request<GameType[]>('GET', `/api/games?type=${val}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
appList.value = res
|
appList.value = res
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 200)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Promise.all([fetchGame(1), fetchGame(2), fetchGame(3)]).then((res) => {
|
||||||
|
console.log(res.flat())
|
||||||
|
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 {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}, 200)
|
}, 200)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true
|
immediate: true
|
||||||
|
|
@ -144,7 +205,13 @@ export default defineComponent(() => {
|
||||||
oridinal: 1
|
oridinal: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gma',
|
id: 'yiqiyoo',
|
||||||
|
type: '休闲游戏',
|
||||||
|
attr: 1,
|
||||||
|
oridinal: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gba',
|
||||||
type: '经典GBA',
|
type: '经典GBA',
|
||||||
attr: 3,
|
attr: 3,
|
||||||
oridinal: 3
|
oridinal: 3
|
||||||
|
|
@ -158,10 +225,10 @@ export default defineComponent(() => {
|
||||||
select: (text: string) => (
|
select: (text: string) => (
|
||||||
<button
|
<button
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'px-[20px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
||||||
isGame.value
|
isGame.value
|
||||||
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
: 'text-[#000] bg-[#D6D6D6]'
|
: 'text-white bg-[#D6D6D6] bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
|
|
@ -170,10 +237,10 @@ export default defineComponent(() => {
|
||||||
unSelect: (text: string) => (
|
unSelect: (text: string) => (
|
||||||
<button
|
<button
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'px-[20px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
||||||
isGame.value
|
isGame.value
|
||||||
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
||||||
: 'text-[#000] hover:bg-[#f0ecec]'
|
: 'text-[#666] hover:bg-black/10 bg-black/[0.05] hover:bg-[#f0ecec]'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
|
|
@ -196,9 +263,10 @@ export default defineComponent(() => {
|
||||||
.fill(0)
|
.fill(0)
|
||||||
.map((el, idx) => (
|
.map((el, idx) => (
|
||||||
<div
|
<div
|
||||||
class={
|
class={clsx(
|
||||||
' relative cursor-pointer bg-gray-500 group w-full flex-grow-0 rounded-xl overflow-hidden'
|
' relative cursor-pointer bg-white/20 group w-full flex-grow-0 rounded-lg overflow-hidden',
|
||||||
}
|
isGame.value ? 'bg-white/30 ' : ' bg-[#fff]/70'
|
||||||
|
)}
|
||||||
key={idx}
|
key={idx}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -35,18 +35,35 @@ export const LinkItem = defineComponent({
|
||||||
const addTo = inject(AddToToken)
|
const addTo = inject(AddToToken)
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={clsx(' w-full h-full rounded-lg flex flex-col justify-between shadow p-4', {
|
class={clsx(' w-full h-full rounded-lg relative flex flex-col justify-between shadow p-4', {
|
||||||
'bg-white/20': isGame.value,
|
'bg-white/20': isGame.value,
|
||||||
'bg-white/80': !isGame.value
|
'bg-white/80': !isGame.value
|
||||||
})}
|
})}
|
||||||
key={props.content.name}
|
key={props.content.name}
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
window.open(props.content.url, '_blank')
|
||||||
|
}}
|
||||||
|
class={
|
||||||
|
'h-0 w-0 absolute right-0 top-0 border-t-[38px] cursor-pointer border-l-[38px] group border-t-[#fff1e2] hover:border-t-[#ffaa4e] border-l-transparent'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class={
|
||||||
|
'rotate-45 top-[-35px] scale-90 text-[#999] group-hover:text-white text-[12px] absolute right-0 whitespace-nowrap'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<img
|
<img
|
||||||
src={props.content.icon}
|
src={props.content.icon}
|
||||||
|
loading="lazy"
|
||||||
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
||||||
style={{
|
style={{
|
||||||
background: props.content.background,
|
background: props.content.background
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -82,10 +99,10 @@ export const LinkItem = defineComponent({
|
||||||
layout.addBlock(
|
layout.addBlock(
|
||||||
{
|
{
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
link: '',
|
link: props.content.url,
|
||||||
name: props.content.name,
|
name: props.content.name,
|
||||||
label: props.content.name,
|
label: props.content.name,
|
||||||
icon: '',
|
icon: props.content.icon,
|
||||||
text: '',
|
text: '',
|
||||||
background: '',
|
background: '',
|
||||||
color: '',
|
color: '',
|
||||||
|
|
@ -150,10 +167,10 @@ export default defineComponent(() => {
|
||||||
select: (text: string) => (
|
select: (text: string) => (
|
||||||
<button
|
<button
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'px-[20px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap ',
|
||||||
isGame.value
|
isGame.value
|
||||||
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
? 'bg-white/30 text-white bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
: 'text-[#000] bg-[#D6D6D6]'
|
: 'text-white bg-[#D6D6D6] bg-gradient-to-b from-[#ffaa4e] to-[#ff6227]'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
|
|
@ -162,10 +179,10 @@ export default defineComponent(() => {
|
||||||
unSelect: (text: string) => (
|
unSelect: (text: string) => (
|
||||||
<button
|
<button
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'px-[20px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
'px-[20px] text-[14px] py-1 items-center justify-center duration-75 shrink-0 flex rounded-2xl whitespace-nowrap',
|
||||||
isGame.value
|
isGame.value
|
||||||
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
? ' text-[#999] bg-white/10 hover:bg-white/20'
|
||||||
: 'text-[#000] hover:bg-[#f0ecec]'
|
: 'text-[#666] hover:bg-black/10 bg-black/[0.05] hover:bg-[#f0ecec]'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
|
|
@ -188,9 +205,10 @@ export default defineComponent(() => {
|
||||||
.fill(0)
|
.fill(0)
|
||||||
.map((el, idx) => (
|
.map((el, idx) => (
|
||||||
<div
|
<div
|
||||||
class={
|
class={clsx(
|
||||||
' relative cursor-pointer bg-gray-500 group w-full flex-grow-0 rounded-xl overflow-hidden'
|
' relative cursor-pointer bg-white/20 group w-full flex-grow-0 rounded-lg overflow-hidden',
|
||||||
}
|
isGame.value ? 'bg-white/30 ' : ' bg-[#fff]/70'
|
||||||
|
)}
|
||||||
key={idx}
|
key={idx}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,13 @@ export default defineComponent({
|
||||||
const link = props.block.link
|
const link = props.block.link
|
||||||
// 小组件无法合并
|
// 小组件无法合并
|
||||||
if (!link) return
|
if (!link) return
|
||||||
|
//游戏不能合并
|
||||||
|
if (props.block.w !== 1) return
|
||||||
const oldIdx = layout.currentPage.list.findIndex((el) => el.id === dragging.id)
|
const oldIdx = layout.currentPage.list.findIndex((el) => el.id === dragging.id)
|
||||||
if (oldIdx < 0) return
|
if (oldIdx < 0) return
|
||||||
const oldBlock = layout.currentPage.list[oldIdx]
|
const oldBlock = layout.currentPage.list[oldIdx]
|
||||||
|
//游戏不能合并
|
||||||
|
if (oldBlock.w !== 1) return
|
||||||
// 文件夹不能移入文件夹
|
// 文件夹不能移入文件夹
|
||||||
if (!oldBlock || oldBlock.link.startsWith('id:')) return
|
if (!oldBlock || oldBlock.link.startsWith('id:')) return
|
||||||
if (link.startsWith('id:')) {
|
if (link.startsWith('id:')) {
|
||||||
|
|
@ -132,7 +136,7 @@ export default defineComponent({
|
||||||
</div>
|
</div>
|
||||||
{settings.state.showBlockLabel && (
|
{settings.state.showBlockLabel && (
|
||||||
<div
|
<div
|
||||||
class="absolute left-0 -bottom-3 text-sm text-white text-center w-full overflow-hidden text-ellipsis whitespace-nowrap break-all font-bold"
|
class="absolute left-1/2 -translate-x-1/2 -bottom-3 text-sm text-white text-center w-[172px] overflow-hidden text-ellipsis whitespace-nowrap break-all font-bold"
|
||||||
style="text-shadow: 0 0 4px rgba(0,0,0,.6)"
|
style="text-shadow: 0 0 4px rgba(0,0,0,.6)"
|
||||||
>
|
>
|
||||||
{layout.getLabel(props.block)}
|
{layout.getLabel(props.block)}
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,51 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const menu = useMenuStore()
|
const menu = useMenuStore()
|
||||||
return () => (
|
if (props.block.w === 1 && props.block.h === 1) {
|
||||||
<div
|
return () => (
|
||||||
class="w-full h-full flex justify-center items-center font-bold bg-cover bg-center bg-no-repeat"
|
<div
|
||||||
onContextmenu={(e) => {
|
class="w-full h-full flex justify-center items-center font-bold bg-cover bg-center bg-no-repeat"
|
||||||
e.preventDefault()
|
onContextmenu={(e) => {
|
||||||
menu.open(props.block)
|
e.preventDefault()
|
||||||
}}
|
menu.open(props.block)
|
||||||
style={{
|
}}
|
||||||
backgroundColor: props.block.background || 'white',
|
onClick={() => {
|
||||||
color: props.block.color || 'black',
|
window.open(props.block.link, '_blank')
|
||||||
backgroundImage: props.block.icon ? `url('${props.block.icon}')` : '',
|
}}
|
||||||
fontSize: props.dock ? '16px' : props.brief ? '12px' : 'calc(var(--block-size) / 5)'
|
style={{
|
||||||
}}
|
backgroundColor: props.block.background || 'white',
|
||||||
>
|
color: props.block.color || 'black',
|
||||||
<div>{props.brief ? props.block.text[0] : props.block.text}</div>
|
backgroundImage: props.block.icon ? `url('${props.block.icon}')` : '',
|
||||||
</div>
|
fontSize: props.dock ? '16px' : props.brief ? '12px' : 'calc(var(--block-size) / 5)'
|
||||||
)
|
}}
|
||||||
|
>
|
||||||
|
<div>{props.brief ? props.block.text[0] : props.block.text}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return () => (
|
||||||
|
<div
|
||||||
|
class="w-full h-full flex justify-between px-3 items-center font-bold bg-cover bg-center bg-no-repeat"
|
||||||
|
onContextmenu={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
menu.open(props.block)
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
window.open(props.block.link, '_blank')
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url('/bg/game.webp')`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img src={props.block.icon} class={'w-[50px] h-[50px] rounded-lg'} alt="game icon" />
|
||||||
|
<div class={'flex-1 text-white flex justify-center'}>
|
||||||
|
<span class={'w-[70px] text-ellipsis overflow-hidden whitespace-nowrap'}>
|
||||||
|
{props.block.label}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<img src="/icons/gameicon.webp" alt="game_icon" class={'absolute right-0 bottom-0 w-[36px]'} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,19 @@
|
||||||
export function randomNum(min: number, max: number) {
|
export function randomNum(min: number, max: number) {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 生成一个长度在 0 到 n 之间的随机字符串。
|
||||||
|
* @param n 最大字符串长度。
|
||||||
|
* @returns 随机生成的字符串。
|
||||||
|
*/
|
||||||
|
export function generateRandomString(n: number): string {
|
||||||
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
const length = Math.floor(Math.random() * (n + 1));
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue