From 16303af983645da2fe32d2ecb8321b7707debdbd Mon Sep 17 00:00:00 2001 From: ForgQi <34411314+ForgQi@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:54:14 +0800 Subject: [PATCH] Bumping version --- app/history/page.tsx | 13 +-- app/job/page.tsx | 85 ++++++++++++++++++ app/layout.tsx | 11 ++- app/lib/utils/index.tsx | 16 +++- app/styles/Home.module.css | 139 ++++++++++++++++++++++++++++ app/styles/globals.css | 79 ++++++++++++++++ app/ui/layout.js | 179 ------------------------------------- biliup/__init__.py | 2 +- biliup/engine/upload.py | 3 - biliup/web/__init__.py | 17 +++- 10 files changed, 346 insertions(+), 198 deletions(-) create mode 100644 app/job/page.tsx create mode 100644 app/styles/Home.module.css create mode 100644 app/styles/globals.css delete mode 100644 app/ui/layout.js diff --git a/app/history/page.tsx b/app/history/page.tsx index f2600d7..8cdbf32 100644 --- a/app/history/page.tsx +++ b/app/history/page.tsx @@ -19,6 +19,7 @@ import 'xgplayer/dist/index.min.css'; import FlvPlugin from "xgplayer-flv"; import FlvJsPlugin from 'xgplayer-flv.js' import Players from "@/app/ui/Player"; +import {humDate} from "@/app/lib/utils"; export default function Home() { const { Header, Footer, Sider, Content } = Layout; @@ -96,20 +97,10 @@ export default function Home() { >
{ - const updateTime = new Date(res.updateTime * 1000) - //日期 - const DD = String(updateTime.getDate()).padStart(2, '0'); // 获取日 - const MM = String(updateTime.getMonth() + 1).padStart(2, '0'); //获取月份,1 月为 0 - const yyyy = updateTime.getFullYear(); // 获取年 - - // 时间 - const hh = String(updateTime.getHours()).padStart(2, '0'); //获取当前小时数(0-23) - const mm = String(updateTime.getMinutes()).padStart(2, '0'); //获取当前分钟数(0-59) - const ss = String(updateTime.getSeconds()).padStart(2, '0'); //获取当前秒数(0-59) return { ...res, size: (res.size / 1024 / 1024).toFixed(2) + ' MB', - updateTime: yyyy + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss + updateTime: humDate(res.updateTime) } })} /> diff --git a/app/job/page.tsx b/app/job/page.tsx new file mode 100644 index 0000000..60dcb6e --- /dev/null +++ b/app/job/page.tsx @@ -0,0 +1,85 @@ +'use client' + +import {Layout, Nav, Table, Typography} from "@douyinfe/semi-ui"; +import useSWR from "swr"; +import {fetcher, FileList} from "@/app/lib/api-streamer"; +import {JSXElementConstructor, Key, PromiseLikeOfReactNode, ReactElement, ReactNode, ReactPortal, + useState +} from "react"; +import {IconCustomerSupport, IconVideoListStroked} from "@douyinfe/semi-icons"; +import {humDate} from "@/app/lib/utils"; + +export default function Home() { + const {Header, Footer, Sider, Content} = Layout; + const {data: data, error, isLoading} = useSWR("/v1/streamer-info", fetcher); + if (isLoading) { + return (<>Loading); + } + const {Text} = Typography; + const columns = [ + { + title: '标题', + dataIndex: 'title', + render: (text: any, record: any, index: any) => { + return ( + {text} + ); + } + }, { + title: '名称', + dataIndex: 'name', + }, { + title: '链接', + dataIndex: 'url', + }, + { + title: '封面', + dataIndex: 'live_cover_path', + }, + { + title: '更新日期', + dataIndex: 'date', + render: (text: any, record: any, index: any) => { + return (<>{humDate(text)}); + }, + sorter: (a: any, b: any) => (a.updateTime - b.updateTime > 0 ? 1 : -1), + }, + ]; + const expandRowRender = (record: any, index: number | undefined) => { + return <>文件列表:{record.files.map((it: { id: Key | null | undefined; file: string | number | boolean | ReactElement> | Iterable | ReactPortal | PromiseLikeOfReactNode | null | undefined; }) => { + return
  文件名:{it.file}
; + })}; + }; + return (<> +
+ +
+ +
+
+ + + ); +} diff --git a/app/layout.tsx b/app/layout.tsx index d8132db..06de160 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -6,7 +6,7 @@ import styles from "./page.module.css"; import {SetStateAction, useCallback, useMemo, useState} from "react"; import Link from "next/link"; import { - IconCloudStroked, + IconCloudStroked, IconCustomerSupport, IconDoubleChevronLeft, IconDoubleChevronRight, IconMoon, @@ -63,7 +63,13 @@ export default function RootLayout({children,}: { children: React.ReactNode }) { padding: '4px' }}> }, - // {itemKey: 'Job', text: '投稿管理', icon: }, + {itemKey: 'job', text: '直播历史', icon:
}, // { // text: '任务平台', // icon: , @@ -84,6 +90,7 @@ export default function RootLayout({children,}: { children: React.ReactNode }) { dashboard: "/dashboard", streamers: "/streamers", "upload-manager": "/upload-manager", + job: "/job", }; if (!routerMap[props.itemKey]) { return itemElement; diff --git a/app/lib/utils/index.tsx b/app/lib/utils/index.tsx index f40b63b..f564d45 100644 --- a/app/lib/utils/index.tsx +++ b/app/lib/utils/index.tsx @@ -39,4 +39,18 @@ export const registerMediaQuery = (media: string, { match, unmatch, callInInit = return (): void => mediaQueryList.removeListener(handlerMediaChange); } return () => undefined; -}; \ No newline at end of file +}; + +export const humDate = function (time: number) { + const updateTime = new Date(time * 1000) + //日期 + const DD = String(updateTime.getDate()).padStart(2, '0'); // 获取日 + const MM = String(updateTime.getMonth() + 1).padStart(2, '0'); //获取月份,1 月为 0 + const yyyy = updateTime.getFullYear(); // 获取年 + + // 时间 + const hh = String(updateTime.getHours()).padStart(2, '0'); //获取当前小时数(0-23) + const mm = String(updateTime.getMinutes()).padStart(2, '0'); //获取当前分钟数(0-59) + const ss = String(updateTime.getSeconds()).padStart(2, '0'); + return yyyy + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss; +} \ No newline at end of file diff --git a/app/styles/Home.module.css b/app/styles/Home.module.css new file mode 100644 index 0000000..4d3373d --- /dev/null +++ b/app/styles/Home.module.css @@ -0,0 +1,139 @@ +.shadow { + box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + background-color: var(--semi-color-bg-0); + /*margin-left: 11px;*/ +} + +body[theme-mode=dark] .shadow { + box-shadow: var(--semi-shadow-elevated); +} + +/*.container {*/ +/* padding: 0 2rem;*/ +/*}*/ + +/*.main {*/ +/* min-height: 100vh;*/ +/* padding: 4rem 0;*/ +/* flex: 1;*/ +/* display: flex;*/ +/* flex-direction: column;*/ +/* justify-content: center;*/ +/* align-items: center;*/ +/*}*/ + +/*.footer {*/ +/* display: flex;*/ +/* flex: 1;*/ +/* padding: 2rem 0;*/ +/* border-top: 1px solid #eaeaea;*/ +/* justify-content: center;*/ +/* align-items: center;*/ +/*}*/ + +/*.footer a {*/ +/* display: flex;*/ +/* justify-content: center;*/ +/* align-items: center;*/ +/* flex-grow: 1;*/ +/*}*/ + +/*.title a {*/ +/* color: #0070f3;*/ +/* text-decoration: none;*/ +/*}*/ + +/*.title a:hover,*/ +/*.title a:focus,*/ +/*.title a:active {*/ +/* text-decoration: underline;*/ +/*}*/ + +/*.title {*/ +/* margin: 0;*/ +/* line-height: 1.15;*/ +/* font-size: 4rem;*/ +/*}*/ + +/*.title,*/ +/*.description {*/ +/* text-align: center;*/ +/*}*/ + +/*.description {*/ +/* margin: 4rem 0;*/ +/* line-height: 1.5;*/ +/* font-size: 1.5rem;*/ +/*}*/ + +/*.code {*/ +/* background: #fafafa;*/ +/* border-radius: 5px;*/ +/* padding: 0.75rem;*/ +/* font-size: 1.1rem;*/ +/* font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,*/ +/* Bitstream Vera Sans Mono, Courier New, monospace;*/ +/*}*/ + +/*.grid {*/ +/* display: flex;*/ +/* align-items: center;*/ +/* justify-content: center;*/ +/* flex-wrap: wrap;*/ +/* max-width: 800px;*/ +/*}*/ + +/*.card {*/ +/* margin: 1rem;*/ +/* padding: 1.5rem;*/ +/* text-align: left;*/ +/* color: inherit;*/ +/* text-decoration: none;*/ +/* border: 1px solid #eaeaea;*/ +/* border-radius: 10px;*/ +/* transition: color 0.15s ease, border-color 0.15s ease;*/ +/* max-width: 300px;*/ +/*}*/ + +/*.card:hover,*/ +/*.card:focus,*/ +/*.card:active {*/ +/* color: #0070f3;*/ +/* border-color: #0070f3;*/ +/*}*/ + +/*.card h2 {*/ +/* margin: 0 0 1rem 0;*/ +/* font-size: 1.5rem;*/ +/*}*/ + +/*.card p {*/ +/* margin: 0;*/ +/* font-size: 1.25rem;*/ +/* line-height: 1.5;*/ +/*}*/ + +/*.logo {*/ +/* height: 1em;*/ +/* margin-left: 0.5rem;*/ +/*}*/ + +/*@media (max-width: 600px) {*/ +/* .grid {*/ +/* width: 100%;*/ +/* flex-direction: column;*/ +/* }*/ +/*}*/ + +/*@media (prefers-color-scheme: dark) {*/ +/* .card,*/ +/* .footer {*/ +/* border-color: #222;*/ +/* }*/ +/* .code {*/ +/* background: #111;*/ +/* }*/ +/* .logo img {*/ +/* filter: invert(1);*/ +/* }*/ +/*}*/ diff --git a/app/styles/globals.css b/app/styles/globals.css new file mode 100644 index 0000000..052a39c --- /dev/null +++ b/app/styles/globals.css @@ -0,0 +1,79 @@ +@import '~@douyinfe/semi-ui/dist/css/semi.min.css'; + +.semi-light-scrollbar::-webkit-scrollbar, .semi-light-scrollbar ::-webkit-scrollbar, ::-webkit-scrollbar { + width: 8px; + height: 8px +} + +.semi-light-scrollbar::-webkit-scrollbar-track, .semi-light-scrollbar ::-webkit-scrollbar-track, ::-webkit-scrollbar-track { + background: transparent +} + +.semi-light-scrollbar::-webkit-scrollbar-corner, .semi-light-scrollbar ::-webkit-scrollbar-corner, ::-webkit-scrollbar-corner { + background-color: transparent +} + +.semi-light-scrollbar::-webkit-scrollbar-thumb, .semi-light-scrollbar ::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb { + border-radius: 6px; + background: transparent; + -webkit-transition: all 1s; + transition: all 1s +} + +.semi-light-scrollbar:hover::-webkit-scrollbar-thumb, .semi-light-scrollbar :hover::-webkit-scrollbar-thumb, :hover::-webkit-scrollbar-thumb { + background: var(--semi-color-fill-2) +} + +.semi-light-scrollbar::-webkit-scrollbar-thumb:hover, .semi-light-scrollbar ::-webkit-scrollbar-thumb:hover, ::-webkit-scrollbar-thumb:hover { + background: var(--semi-color-fill-1) +} + +body::-webkit-scrollbar, html::-webkit-scrollbar { + width: 8px; + height: 8px +} + +body::-webkit-scrollbar-track, html::-webkit-scrollbar-track { + background: transparent +} + +body::-webkit-scrollbar-corner, html::-webkit-scrollbar-corner { + background-color: transparent +} + +body::-webkit-scrollbar-thumb, html::-webkit-scrollbar-thumb { + border-radius: 6px; + background: var(--semi-color-fill-2) +} + +body::-webkit-scrollbar-thumb:hover, html::-webkit-scrollbar-thumb:hover { + background: var(--semi-color-fill-1) +} + +html, +body { + padding: 0; + margin: 0; + color: var(--semi-color-text-0); + background-color: var(--semi-color-bg-0); + /*font-family: var(font-family);*/ +} + +/*a {*/ +/* color: inherit;*/ +/* text-decoration: none;*/ +/*}*/ + +/** {*/ +/* box-sizing: border-box;*/ +/*}*/ + +/*@media (prefers-color-scheme: dark) {*/ +/* html {*/ +/* color-scheme: dark;*/ +/* }*/ +/* body {*/ +/* color: white;*/ +/* background: black;*/ +/* }*/ +/*}*/ diff --git a/app/ui/layout.js b/app/ui/layout.js deleted file mode 100644 index 807083a..0000000 --- a/app/ui/layout.js +++ /dev/null @@ -1,179 +0,0 @@ -import {Button, Layout as SeLayout} from '@douyinfe/semi-ui'; -import {Nav} from '@douyinfe/semi-ui'; -import { - IconMoon, - IconSun, - IconCloudStroked, - IconSemiLogo, - IconUserCardVideo, - IconDoubleChevronLeft, - IconDoubleChevronRight, IconVideoListStroked -} from '@douyinfe/semi-icons'; -import Link from "next/link"; -import {useCallback, useMemo, useState} from "react"; -import styles from '../styles/Home.module.css'; -import { useRouter } from 'next/router'; - -export default function Layout({children}) { - const {Header, Footer, Sider, Content} = SeLayout; - const router = useRouter(); - - const renderWrapper = useCallback(({ itemElement, isSubNav, isInSubNav, props }) => { - const routerMap = { - home: "/", - history: "/history", - dashboard: "/dashboard", - streamers: "/streamers", - "upload-manager": "/upload-manager", - }; - if(!routerMap[props.itemKey]) { - return itemElement; - } - return ( - - {itemElement} - - ); - // return itemElement; - }, []); - let initOpenKeys = []; - console.log("slice(1)", router.pathname.slice(1)); - if (router.pathname.slice(1) === 'streamers' || router.pathname.slice(1) === 'history') { - initOpenKeys = ['manager']; - } - const [openKeys, setOpenKeys] = useState(initOpenKeys); - const [selectedKeys, setSelectedKeys] = useState([router.pathname.slice(1)]); - const [isCollapsed, setIsCollapsed] = useState(false); - const items = useMemo(() =>[ - {itemKey: 'manager', text: '录播管理', - items: [{itemKey: 'streamers', text: '直播管理'}, {itemKey: 'history', text: '历史记录'}], - icon:
}, - {itemKey: 'upload-manager', text: '投稿管理', icon:
}, - // {itemKey: 'Job', text: '投稿管理', icon: }, - // { - // text: '任务平台', - // icon: , - // itemKey: 'Job', - // items: [{itemKey: 'About', text: '任务管理'}, {itemKey: 'Dashboard', text: '用户任务查询'}], - // }, - ].map(value => { - value.text =
value.itemKey === key) || (selectedKeys.some(key=> openKeys.some(o=> isSub(key, o))) && openKeys.some(key => value.itemKey === key)) ? 'var(--semi-color-text-0)' : 'var(--semi-color-text-2)', - fontWeight: 600 - }}>{value.text}
- return value; - }), [openKeys, selectedKeys]); - // const [navStyle, setNavStyle] = useState({ height: '100%' }); - const onSelect = data => { - setSelectedKeys([...data.selectedKeys]); - }; - const onOpenChange = data => { - console.log('trigger onOpenChange: ', data); - setOpenKeys([...data.openKeys]); - }; - let navStyle = isCollapsed ? { height: '100%', overflow: 'visible' } : { height: '100%' }; - const onCollapseChange = useCallback( () => { - setIsCollapsed(!isCollapsed); - }, [isCollapsed]); - const [mode, setMode] = useState('light'); - - return ( - <> - - - - - - {children} - - - - ) -} - -function footer(mode, setMode) { - const switchMode = () => { - const body = document.body; - if (body.hasAttribute('theme-mode')) { - body.removeAttribute('theme-mode'); - setMode('light'); - } else { - body.setAttribute('theme-mode', 'dark'); - setMode('dark'); - } - }; - return ( - -