diff --git a/src/App.vue b/src/App.vue index 1fac3f3..517c4e9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,11 +3,16 @@ - - - - - + + + + + + + + + + @@ -18,7 +23,7 @@ import ViewerLayout from '@/views/ViewerLayout.vue' import ManageLayout from '@/views/ManageLayout.vue' import { useRoute } from 'vue-router' -import { NConfigProvider, NMessageProvider, NNotificationProvider, zhCN, dateZhCN, useOsTheme, darkTheme, NElement } from 'naive-ui' +import { NConfigProvider, NMessageProvider, NNotificationProvider, zhCN, dateZhCN, useOsTheme, darkTheme, NElement, NSpin } from 'naive-ui' import { computed, onMounted, ref } from 'vue' import { useStorage } from '@vueuse/core' import { ThemeType, UserInfo } from './api/api-models' @@ -34,6 +39,7 @@ const layout = computed(() => { document.title = route.meta.title + ' · 管理 · VTsuru' return 'manage' } else { + document.title = route.meta.title + ' · VTsuru' return '' } }) diff --git a/src/api/api-models.ts b/src/api/api-models.ts index 491030e..d7420cb 100644 --- a/src/api/api-models.ts +++ b/src/api/api-models.ts @@ -151,12 +151,59 @@ export enum ThemeType { Light = 'light', Dark = 'dark', } +export interface VideoCollectCreateModel { + id?: string + name: string + description: string + endAt: number + maxVideoCount: number +} export interface VideoCollectTable{ id: string + shortId: string name: string - title: string description: string createAt: number endAt: number - + isFinish: boolean + videoCount: number + maxVideoCount: number + owner: UserInfo +} +export interface VideoCollectVideo { + id: string + title: string + description: string + publistTime: number + ownerName: string + ownerUId: number + cover: string + length: number + watched?: boolean +} +export enum VideoFrom{ + Collect, + Spam +} +export enum VideoStatus +{ + Pending, + Accepted, + Rejected, +} +export interface VideoSender{ + sendAt: number + sender?: string + senderId?: number + description?: string + from: VideoFrom +} +export interface VideoInfo { + bvid: string + senders: VideoSender[] + status: VideoStatus +} +export interface VideoCollectDetail { + table: VideoCollectTable + videos: { info: VideoInfo; video: VideoCollectVideo }[] } diff --git a/src/components/VideoCollectInfoCard.vue b/src/components/VideoCollectInfoCard.vue new file mode 100644 index 0000000..0975d91 --- /dev/null +++ b/src/components/VideoCollectInfoCard.vue @@ -0,0 +1,69 @@ + + + + + + + 已结束 + 进行中 + + {{ item.name }} + + + + + + + + + + + + {{ item.description }} + + + + + + + + + {{ item.videoCount }} / {{ item.maxVideoCount }} + + 已征集数量 / 最大征集数量 + + + + + + + + + 剩余 + + 结束于 + + + + + + + diff --git a/src/router/index.ts b/src/router/index.ts index d6bbcde..e10ff2f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -22,6 +22,24 @@ const routes: Array = [ name: 'resetPassword', component: () => import('@/views/ChangePasswordView.vue'), }, + { + path: '/video-collect/:id', + name: 'video-collect', + component: () => import('@/views/VideoCollectPublic.vue'), + meta: { + title: '推荐 · 视频征集', + keepAlive: true, + }, + }, + { + path: '/video-collect/list/:id', + name: 'video-collect-list', + component: () => import('@/views/VideoCollectListView.vue'), + meta: { + title: '结果 · 视频征集', + keepAlive: true, + }, + }, { path: '/user/:id', name: 'user', @@ -148,8 +166,26 @@ const routes: Array = [ keepAlive: true, }, }, + { + path: 'video-collect/:id', + name: 'manage-videoCollect-Detail', + component: () => import('@/views/manage/VideoCollectDetailView.vue'), + meta: { + title: '详情 · 视频征集', + keepAlive: true, + parent: 'manage-videoCollect', + }, + }, ], }, + { + path: '/:pathMatch(.*)*', + name: 'notfound', + component: import('@/views/NotfoundView.vue'), + meta: { + title: '页面不存在', + }, + }, ] const router = createRouter({ diff --git a/src/views/AboutView.vue b/src/views/AboutView.vue index 4915684..00b4a42 100644 --- a/src/views/AboutView.vue +++ b/src/views/AboutView.vue @@ -33,6 +33,7 @@ import { NButton, NCard, NDivider, NLayoutContent, NSpace, NText, NTimeline, NTi 更新日志 + diff --git a/src/views/IndexView.vue b/src/views/IndexView.vue index 0cf809c..671efb0 100644 --- a/src/views/IndexView.vue +++ b/src/views/IndexView.vue @@ -35,7 +35,7 @@ const functions = [ }, { name: '视频征集', - desc: '创建用来收集视频链接的页面, 可以从动态爬取, 也可以提前对视频进行筛选 (开发中)', + desc: '创建用来收集视频链接的页面, 可以从动态爬取, 也可以提前对视频进行筛选', icon: Lottery24Filled, }, { diff --git a/src/views/ManageLayout.vue b/src/views/ManageLayout.vue index 95bb46a..390fcf7 100644 --- a/src/views/ManageLayout.vue +++ b/src/views/ManageLayout.vue @@ -215,7 +215,7 @@ onMounted(() => { { - + + + + + + diff --git a/src/views/NotfoundView.vue b/src/views/NotfoundView.vue new file mode 100644 index 0000000..fb5b07b --- /dev/null +++ b/src/views/NotfoundView.vue @@ -0,0 +1,13 @@ + + + + + + + 返回首页 + + + + diff --git a/src/views/VerifyView.vue b/src/views/VerifyView.vue index 29f9058..f28e1b2 100644 --- a/src/views/VerifyView.vue +++ b/src/views/VerifyView.vue @@ -1,31 +1,23 @@ + + + + + + 视频征集表 | {{ videoDetail.table.name }} + + + + + + + + + + 只会显示已通过的视频 + + + + + 共 [{{ formatSecondsToTime(totalTime) }}] + + 已观看 [{{ formatSecondsToTime(watchedTime) }}] + + + 共 {{ acceptVideos?.length }} 条 + + 已观看 {{ watchedVideos.length }} 条 + + + 已观看全部视频 + + + + + + + + + + {{ item.video.title }} + + + + + + + {{ item.video.description }} + + + {{ item.video.description }} + + + + + + {{ formatSeconds(item.video.length) }} + + + + {{ item.video.ownerName }} + + + + + + + + + + diff --git a/src/views/VideoCollectPublic.vue b/src/views/VideoCollectPublic.vue new file mode 100644 index 0000000..34855ea --- /dev/null +++ b/src/views/VideoCollectPublic.vue @@ -0,0 +1,96 @@ + + + + + + + + + 视频征集 + + + {{ table.owner?.name }} + + + + + + + + + + + 推荐视频 + + + + + + diff --git a/src/views/manage/DashboardView.vue b/src/views/manage/DashboardView.vue index 3905c41..6599f2a 100644 --- a/src/views/manage/DashboardView.vue +++ b/src/views/manage/DashboardView.vue @@ -18,6 +18,7 @@ const newEmailAddress = ref('') const newEmailVerifyCode = ref('') const canSendEmailVerifyCode = ref(true) +const oldPassword = ref('') const newPassword = ref('') const newPassword2 = ref('') const isLoading = ref(false) diff --git a/src/views/manage/VideoCollectDetailView.vue b/src/views/manage/VideoCollectDetailView.vue index e69de29..80ea734 100644 --- a/src/views/manage/VideoCollectDetailView.vue +++ b/src/views/manage/VideoCollectDetailView.vue @@ -0,0 +1,398 @@ + + + + + {{ '< 返回' }} + + + 分享 + 更新 + {{ videoDetail.table.isFinish ? '开启表' : '关闭表' }} + + + 删除 + + 确定删除表? 此操作无法撤销 + + + + + + + 分享 + 更新 + {{ videoDetail.table.isFinish ? '开启表' : '关闭表' }} + + + 删除 + + 确定删除表? 此操作无法撤销 + + + + + 已通过时长: {{ formatSeconds(new List(acceptVideos).Sum((v) => v?.video.length ?? 0)) }} + + + + + + 未审核 + + + {{ paddingVideos.length }} + + + + + + + 通过 + + + {{ acceptVideos.length }} + + + + + + + 拒绝 + + + {{ rejectVideos.length }} + + + + + + + + + + + + + + + + + + + + + + + + + 最低为一小时 + + + + 更新 + + + + + diff --git a/src/views/manage/VideoCollectManageView.vue b/src/views/manage/VideoCollectManageView.vue index 6ad5658..8b5e407 100644 --- a/src/views/manage/VideoCollectManageView.vue +++ b/src/views/manage/VideoCollectManageView.vue @@ -1,49 +1,176 @@ - + + 新建征集表 + - - - - - + + + + + + + + + + + + + + + + + + + 最低为一小时 + + + + 创建 + + + +