完成视频小组件
This commit is contained in:
parent
c1ac61c3fd
commit
56429b19a4
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -34,7 +34,13 @@ export const WidgetItem = defineComponent({
|
||||||
'text-black/80': !isGame.value
|
'text-black/80': !isGame.value
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{props.content.label}
|
{props.content.name === 'gameVideo'
|
||||||
|
? useLayoutStore().state.current === 0
|
||||||
|
? '游戏视频'
|
||||||
|
: useLayoutStore().state.current === 1
|
||||||
|
? '学习视频'
|
||||||
|
: '娱乐视频'
|
||||||
|
: props.content.label}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class={clsx('text-[12px]', {
|
class={clsx('text-[12px]', {
|
||||||
|
@ -42,7 +48,13 @@ export const WidgetItem = defineComponent({
|
||||||
'text-black/60': !isGame.value
|
'text-black/60': !isGame.value
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{props.content.description}
|
{props.content.description === 'gameVideoDesc'
|
||||||
|
? useLayoutStore().state.current === 0
|
||||||
|
? '热门游戏视频'
|
||||||
|
: useLayoutStore().state.current === 1
|
||||||
|
? '热门学习视频'
|
||||||
|
: '热门娱乐视频'
|
||||||
|
: props.content.description}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default defineComponent({
|
||||||
const hover = ref(false)
|
const hover = ref(false)
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class="w-full h-full p-[var(--block-padding)] relative rounded-lg "
|
class="w-full h-full p-[var(--block-padding)] relative rounded-lg"
|
||||||
key={props.block.id}
|
key={props.block.id}
|
||||||
id={props.block.id}
|
id={props.block.id}
|
||||||
style={{
|
style={{
|
||||||
|
@ -111,9 +111,8 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class={'w-full h-full relative'}>
|
|
||||||
<div
|
<div
|
||||||
class="w-full h-full overflow-hidden relative cursor-pointer shadow-lg"
|
class="w-full h-full overflow-hidden relative cursor-pointer shadow-lg hover-move"
|
||||||
style={{
|
style={{
|
||||||
borderRadius: `calc(var(--block-radius) * var(--block-size))`
|
borderRadius: `calc(var(--block-radius) * var(--block-size))`
|
||||||
}}
|
}}
|
||||||
|
@ -133,14 +132,13 @@ export default defineComponent({
|
||||||
</div>
|
</div>
|
||||||
{settings.state.showBlockLabel && (
|
{settings.state.showBlockLabel && (
|
||||||
<div
|
<div
|
||||||
class="absolute left-0 -bottom-7 text-sm text-white text-center w-full overflow-hidden text-ellipsis whitespace-nowrap break-all font-bold"
|
class="absolute left-0 -bottom-3 text-sm text-white text-center w-full 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)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,6 +22,7 @@ const defaultLayout: Layout = {
|
||||||
export default defineStore('layout', () => {
|
export default defineStore('layout', () => {
|
||||||
const state = reactive(defaultLayout)
|
const state = reactive(defaultLayout)
|
||||||
const ready = ref(false)
|
const ready = ref(false)
|
||||||
|
|
||||||
db.getItem<Layout>('layout').then((res) => {
|
db.getItem<Layout>('layout').then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
Object.assign(state, res)
|
Object.assign(state, res)
|
||||||
|
@ -96,8 +97,16 @@ export default defineStore('layout', () => {
|
||||||
const dir = state.dir[block.link.slice(3)]
|
const dir = state.dir[block.link.slice(3)]
|
||||||
if (dir) return dir.label
|
if (dir) return dir.label
|
||||||
}
|
}
|
||||||
|
// 处理不同的组件的名称
|
||||||
|
if (block.name === 'gameVideo') {
|
||||||
|
console.log(state.currentPage);
|
||||||
|
console.log(block);
|
||||||
|
|
||||||
|
return state.current === 0 ? '游戏视频' : state.current === 1 ? '学习视频' : '娱乐视频'
|
||||||
|
}
|
||||||
return block.label || ''
|
return block.label || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeBackground = (url: string) => {
|
const changeBackground = (url: string) => {
|
||||||
state.content[state.current].background = url
|
state.content[state.current].background = url
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* 生成随机数
|
||||||
|
* @param min 最小值
|
||||||
|
* @param max 最大值
|
||||||
|
* @returns 随机数
|
||||||
|
*/
|
||||||
|
export function randomNum(min: number, max: number) {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
import useLayoutStore from '@/layout/useLayoutStore'
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
||||||
|
import { computed, defineComponent, onMounted, ref, watch, type CSSProperties } from 'vue'
|
||||||
|
import { FaChevronLeft } from 'oh-vue-icons/icons'
|
||||||
|
import type { CarouselRef } from 'ant-design-vue/es/carousel'
|
||||||
|
import { randomNum } from '@/utils/tool'
|
||||||
|
addIcons(FaChevronLeft)
|
||||||
|
interface Owner {
|
||||||
|
face: string
|
||||||
|
mid: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GameData {
|
||||||
|
_id: string
|
||||||
|
aid: number
|
||||||
|
ctime: number
|
||||||
|
duration: number
|
||||||
|
owner: Owner
|
||||||
|
pic: string
|
||||||
|
rid: string
|
||||||
|
time: string
|
||||||
|
title: string
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
export default defineComponent(() => {
|
||||||
|
const list = ref<GameData[]>([])
|
||||||
|
const currentIndex = ref(-1)
|
||||||
|
|
||||||
|
const current = computed(() => {
|
||||||
|
if (currentIndex.value === -1) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return list.value[currentIndex.value]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => useLayoutStore().state.current,
|
||||||
|
(val) => {
|
||||||
|
const type = val === 0 ? 'game' : val === 1 ? 'study' : 'entertainment'
|
||||||
|
request<GameData[]>('GET', `/api/hotVideo?type=${type}`).then((res) => {
|
||||||
|
list.value = res
|
||||||
|
currentIndex.value = randomNum(0, list.value.length)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
onMounted(() => {
|
||||||
|
setInterval(() => {
|
||||||
|
currentIndex.value = currentIndex.value === list.value.length - 1 ? 0 : currentIndex.value + 1
|
||||||
|
}, 5000)
|
||||||
|
})
|
||||||
|
return () => (
|
||||||
|
<div class="w-full h-full p-2 bg-[#17212d] ">
|
||||||
|
{
|
||||||
|
<div
|
||||||
|
class={'w-full h-full rounded-xl relative group'}
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url('https://uetab.com/countdown-img/pic2.jpg')`,
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition: 'center',
|
||||||
|
backgroundRepeat: 'no-repeat'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class={
|
||||||
|
'absolute bottom-0 left-1/2 -translate-x-1/2 pb-2 w-[300px] flex flex-col text-white '
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span class="text-[14px] text-ellipsis overflow-hidden whitespace-nowrap">
|
||||||
|
{current.value?.title}
|
||||||
|
</span>
|
||||||
|
<span class="text-[12px] opacity-60">{current.value?.owner.name}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
|
currentIndex.value =
|
||||||
|
currentIndex.value === 0 ? list.value.length - 1 : currentIndex.value - 1
|
||||||
|
}}
|
||||||
|
class="absolute hidden bottom-[20px] group-hover:flex items-center justify-center left-[0px] w-[22px] h-[22px] bg-white/30 rounded"
|
||||||
|
>
|
||||||
|
<OhVueIcon name={FaChevronLeft.name} class={'text-white/80'}></OhVueIcon>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
currentIndex.value =
|
||||||
|
currentIndex.value === list.value.length - 1 ? 0 : currentIndex.value + 1
|
||||||
|
}}
|
||||||
|
class="absolute hidden bottom-[20px] group-hover:flex items-center justify-center right-[0px] rotate-180 w-[22px] h-[22px] bg-white/30 rounded"
|
||||||
|
>
|
||||||
|
<OhVueIcon name={FaChevronLeft.name} class={'text-white/80'}></OhVueIcon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -0,0 +1,18 @@
|
||||||
|
import asyncLoader from '@/utils/asyncLoader'
|
||||||
|
import type { Widget } from '..'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'gameVideo',
|
||||||
|
label: 'gameVideo',
|
||||||
|
description: 'gameVideoDesc',
|
||||||
|
icon: '/icons/game_video.png',
|
||||||
|
modal: null,
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
w: 4,
|
||||||
|
h: 2,
|
||||||
|
label: '大',
|
||||||
|
component: asyncLoader(() => import('./Large'))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} as Widget
|
|
@ -7,6 +7,7 @@ import eat from './eat'
|
||||||
import discount from './discount'
|
import discount from './discount'
|
||||||
import hotspot from './hotspot'
|
import hotspot from './hotspot'
|
||||||
import constellation from './constellation'
|
import constellation from './constellation'
|
||||||
|
import gameVideo from './gameVideo'
|
||||||
export interface Widget {
|
export interface Widget {
|
||||||
name: string // 小组件类型唯一标识
|
name: string // 小组件类型唯一标识
|
||||||
label: string // 小组件名称
|
label: string // 小组件名称
|
||||||
|
@ -21,4 +22,4 @@ export interface Widget {
|
||||||
}[] // 不同尺寸小组件块
|
}[] // 不同尺寸小组件块
|
||||||
}
|
}
|
||||||
|
|
||||||
export default [calendar, weather, weApply, gameNews, eat, discount, hotspot, constellation] as Widget[]
|
export default [calendar, weather, weApply, gameNews, eat, discount, hotspot, constellation, gameVideo] as Widget[]
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { defineComponent } from 'vue'
|
|
||||||
|
|
||||||
export default defineComponent(() => {
|
|
||||||
return () => (
|
|
||||||
<div class="w-full h-full bg-[#ecfbff] flex flex-col">
|
|
||||||
large
|
|
||||||
</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>
|
|
||||||
)
|
|
||||||
})
|
|
|
@ -1,30 +0,0 @@
|
||||||
import asyncLoader from '@/utils/asyncLoader'
|
|
||||||
import type { Widget } from '..'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'gameNews',
|
|
||||||
label: '游戏资讯',
|
|
||||||
description: '游戏资讯',
|
|
||||||
icon: '/icons/game_news_icon.png',
|
|
||||||
modal: asyncLoader(() => import('./Modal')),
|
|
||||||
list: [
|
|
||||||
{
|
|
||||||
w: 2,
|
|
||||||
h: 1,
|
|
||||||
label: '小',
|
|
||||||
component: asyncLoader(() => import('./Small'))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
w: 2,
|
|
||||||
h: 2,
|
|
||||||
label: '中',
|
|
||||||
component: asyncLoader(() => import('./Middle'))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
w: 4,
|
|
||||||
h: 2,
|
|
||||||
label: '大',
|
|
||||||
component: asyncLoader(() => import('./Large'))
|
|
||||||
}
|
|
||||||
]
|
|
||||||
} as Widget
|
|
|
@ -1,34 +0,0 @@
|
||||||
import useLayoutStore from '@/layout/useLayoutStore'
|
|
||||||
import request from '@/utils/request'
|
|
||||||
import { defineStore } from 'pinia'
|
|
||||||
import { computed, ref, watch } from 'vue'
|
|
||||||
|
|
||||||
type HotType = {
|
|
||||||
desc: string
|
|
||||||
hotScore: string
|
|
||||||
index: number
|
|
||||||
picurl: string
|
|
||||||
title: string
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
export const PlatformList = new Map<string, string>([
|
|
||||||
['baidu', '百度'],
|
|
||||||
['weibo', '微博'],
|
|
||||||
['bilibili', 'B站']
|
|
||||||
] as const)
|
|
||||||
|
|
||||||
export default defineStore('video', () => {
|
|
||||||
const videoList = ref([])
|
|
||||||
const layout = useLayoutStore()
|
|
||||||
const type = ref('baidu')
|
|
||||||
const getNews = async (type: string) => {
|
|
||||||
const res = request('GET', `/api/hotList?type=${type}`)
|
|
||||||
}
|
|
||||||
watch(
|
|
||||||
() => layout.state.current,
|
|
||||||
(val) => {
|
|
||||||
console.log('videoList', val)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return {}
|
|
||||||
})
|
|
Loading…
Reference in New Issue