Compare commits
4 Commits
feat/front
...
main
Author | SHA1 | Date | |
---|---|---|---|
92c3c8eefe | |||
497ea031d8 | |||
39ca394a56 | |||
0bd1771f35 |
9
packages/core/db/schema.d.ts
vendored
9
packages/core/db/schema.d.ts
vendored
@ -8,7 +8,7 @@ export interface BiliUserType {
|
|||||||
|
|
||||||
export interface VideoSnapshotType {
|
export interface VideoSnapshotType {
|
||||||
id: number;
|
id: number;
|
||||||
created_at: string;
|
created_at: Date;
|
||||||
views: number;
|
views: number;
|
||||||
coins: number;
|
coins: number;
|
||||||
likes: number;
|
likes: number;
|
||||||
@ -35,9 +35,9 @@ export interface SnapshotScheduleType {
|
|||||||
id: number;
|
id: number;
|
||||||
aid: number;
|
aid: number;
|
||||||
type?: string;
|
type?: string;
|
||||||
created_at: string;
|
created_at: Date;
|
||||||
started_at?: string;
|
started_at?: Date;
|
||||||
finished_at?: string;
|
finished_at?: Date;
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ export interface UserType {
|
|||||||
password: string;
|
password: string;
|
||||||
unq_id: string;
|
unq_id: string;
|
||||||
role: string;
|
role: string;
|
||||||
|
created_at: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BiliVideoMetadataType {
|
export interface BiliVideoMetadataType {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@cvsa/core",
|
"name": "@cvsa/core",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "0.0.7",
|
"version": "0.0.10",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun --env-file=.env.test run vitest",
|
"test": "bun --env-file=.env.test run vitest",
|
||||||
"build": "bun build ./index.ts --target node --outdir ./dist"
|
"build": "bun build ./index.ts --target node --outdir ./dist"
|
||||||
|
@ -7,6 +7,7 @@ import { aidExists as idExists } from "@/lib/db/bilibili_metadata/aidExists";
|
|||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { BiliVideoMetadataType, VideoSnapshotType } from "@cvsa/core";
|
import { BiliVideoMetadataType, VideoSnapshotType } from "@cvsa/core";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
|
import { DateTime } from "luxon";
|
||||||
|
|
||||||
const MetadataRow = ({ title, desc }: { title: string; desc: string | number | undefined | null }) => {
|
const MetadataRow = ({ title, desc }: { title: string; desc: string | number | undefined | null }) => {
|
||||||
if (!desc) return <></>;
|
if (!desc) return <></>;
|
||||||
@ -104,18 +105,16 @@ export default async function VideoInfoPage({ params }: { params: Promise<{ id:
|
|||||||
title="发布时间"
|
title="发布时间"
|
||||||
desc={
|
desc={
|
||||||
videoInfo.published_at
|
videoInfo.published_at
|
||||||
? format(new Date(videoInfo.published_at), "yyyy-MM-dd HH:mm:ss", {
|
? DateTime.fromJSDate(videoInfo.published_at).toFormat(
|
||||||
locale: zhCN
|
"yyyy-MM-dd HH:mm:ss"
|
||||||
})
|
)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<MetadataRow title="时长 (秒)" desc={videoInfo.duration} />
|
<MetadataRow title="时长 (秒)" desc={videoInfo.duration} />
|
||||||
<MetadataRow
|
<MetadataRow
|
||||||
title="创建时间"
|
title="创建时间"
|
||||||
desc={format(new Date(videoInfo.created_at), "yyyy-MM-dd HH:mm:ss", {
|
desc={DateTime.fromJSDate(videoInfo.created_at).toFormat("yyyy-MM-dd HH:mm:ss")}
|
||||||
locale: zhCN
|
|
||||||
})}
|
|
||||||
/>
|
/>
|
||||||
<MetadataRow title="封面" desc={videoInfo?.cover_url} />
|
<MetadataRow title="封面" desc={videoInfo?.cover_url} />
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -142,11 +141,11 @@ export default async function VideoInfoPage({ params }: { params: Promise<{ id:
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{snapshots.map((snapshot) => (
|
{snapshots.map((snapshot) => (
|
||||||
<tr key={snapshot.created_at}>
|
<tr key={snapshot.id}>
|
||||||
<td className="border dark:border-zinc-500 px-4 py-2">
|
<td className="border dark:border-zinc-500 px-4 py-2">
|
||||||
{format(new Date(snapshot.created_at), "yyyy-MM-dd HH:mm:ss", {
|
{DateTime.fromJSDate(snapshot.created_at).toFormat(
|
||||||
locale: zhCN
|
"yyyy-MM-dd HH:mm:ss"
|
||||||
})}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="border dark:border-zinc-500 px-4 py-2">{snapshot.views}</td>
|
<td className="border dark:border-zinc-500 px-4 py-2">{snapshot.views}</td>
|
||||||
<td className="border dark:border-zinc-500 px-4 py-2">{snapshot.coins}</td>
|
<td className="border dark:border-zinc-500 px-4 py-2">{snapshot.coins}</td>
|
||||||
|
@ -6,6 +6,7 @@ import { LogoutButton } from "./LogoutButton";
|
|||||||
import { numeric } from "yup-numeric";
|
import { numeric } from "yup-numeric";
|
||||||
import { getTranslations } from "next-intl/server";
|
import { getTranslations } from "next-intl/server";
|
||||||
import HeaderServer from "@/components/shell/HeaderServer";
|
import HeaderServer from "@/components/shell/HeaderServer";
|
||||||
|
import { DateTime } from "luxon";
|
||||||
|
|
||||||
const uidSchema = numeric().integer().min(0);
|
const uidSchema = numeric().integer().min(0);
|
||||||
|
|
||||||
@ -17,9 +18,7 @@ const SignupTime: React.FC<SignupTimeProps> = ({ user }: SignupTimeProps) => {
|
|||||||
return (
|
return (
|
||||||
<p className="mt-4">
|
<p className="mt-4">
|
||||||
于
|
于
|
||||||
{format(new Date(user.createdAt), "yyyy-MM-dd HH:mm:ss", {
|
{DateTime.fromJSDate(user.createdAt).toFormat("yyyy-MM-dd HH:mm:ss")}
|
||||||
locale: zhCN
|
|
||||||
})}
|
|
||||||
注册。
|
注册。
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { format } from "date-fns";
|
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import type { VideoInfoData } from "@cvsa/core";
|
import type { VideoInfoData } from "@cvsa/core";
|
||||||
|
import { DateTime } from "luxon";
|
||||||
|
|
||||||
const StatRow = ({ title, description }: { title: string; description?: number }) => {
|
const StatRow = ({ title, description }: { title: string; description?: number }) => {
|
||||||
return (
|
return (
|
||||||
@ -51,7 +51,7 @@ const VideoInfo = async ({ id }: { id: string }) => {
|
|||||||
{data.bvid} · av{data.aid}
|
{data.bvid} · av{data.aid}
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<span>发布于 {format(new Date(data.pubdate * 1000), "yyyy-MM-dd HH:mm:ss")}</span>
|
<span>发布于 {DateTime.fromSeconds(data.pubdate).toFormat("yyyy-MM-dd HH:mm:ss")}</span>
|
||||||
<br />
|
<br />
|
||||||
<span>播放:{(data.stat?.view ?? 0).toLocaleString()}</span> ·{" "}
|
<span>播放:{(data.stat?.view ?? 0).toLocaleString()}</span> ·{" "}
|
||||||
<span>弹幕:{(data.stat?.danmaku ?? 0).toLocaleString()}</span>
|
<span>弹幕:{(data.stat?.danmaku ?? 0).toLocaleString()}</span>
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
"name": "next",
|
"name": "next",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cvsa/backend": "^0.5.3",
|
"@cvsa/backend": "^0.5.3",
|
||||||
"@cvsa/core": "^0.0.7",
|
"@cvsa/core": "0.0.10",
|
||||||
"@mdx-js/loader": "^3.1.0",
|
"@mdx-js/loader": "^3.1.0",
|
||||||
"@mdx-js/react": "^3.1.0",
|
"@mdx-js/react": "^3.1.0",
|
||||||
"@next/mdx": "^15.3.3",
|
"@next/mdx": "^15.3.3",
|
||||||
|
"@types/luxon": "^3.6.2",
|
||||||
"@types/mdx": "^2.0.13",
|
"@types/mdx": "^2.0.13",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
@ -16,6 +17,7 @@
|
|||||||
"fumadocs-mdx": "^11.6.6",
|
"fumadocs-mdx": "^11.6.6",
|
||||||
"i18next": "^25.2.1",
|
"i18next": "^25.2.1",
|
||||||
"jotai": "^2.12.5",
|
"jotai": "^2.12.5",
|
||||||
|
"luxon": "^3.6.1",
|
||||||
"next": "^15.3.3",
|
"next": "^15.3.3",
|
||||||
"next-intl": "^4.1.0",
|
"next-intl": "^4.1.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
@ -47,7 +49,7 @@
|
|||||||
|
|
||||||
"@cvsa/backend": ["@cvsa/backend@0.5.3", "", { "dependencies": { "@rabbit-company/argon2id": "^2.1.0", "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", "limiter": "^3.0.0", "postgres": "^3.4.5", "rate-limit-redis": "^4.2.0", "yup": "^1.6.1", "zod": "^3.24.3" } }, "sha512-RzGjarU2TOzD6/d6qikE4xd/ZqNQl3jOYtgfJg5kbWFuiXnOgEC9QBTi+adzjmaWFrcpuYck6ooWpg4eT3s43g=="],
|
"@cvsa/backend": ["@cvsa/backend@0.5.3", "", { "dependencies": { "@rabbit-company/argon2id": "^2.1.0", "hono": "^4.7.8", "hono-rate-limiter": "^0.4.2", "ioredis": "^5.6.1", "limiter": "^3.0.0", "postgres": "^3.4.5", "rate-limit-redis": "^4.2.0", "yup": "^1.6.1", "zod": "^3.24.3" } }, "sha512-RzGjarU2TOzD6/d6qikE4xd/ZqNQl3jOYtgfJg5kbWFuiXnOgEC9QBTi+adzjmaWFrcpuYck6ooWpg4eT3s43g=="],
|
||||||
|
|
||||||
"@cvsa/core": ["@cvsa/core@0.0.7", "", { "dependencies": { "@koshnic/ratelimit": "^1.0.3", "chalk": "^5.4.1", "ioredis": "^5.6.1", "logform": "^2.7.0", "postgres": "^3.4.5", "winston": "^3.17.0" } }, "sha512-j2Ksg+ZquHqKPew1JZxw0Q9yckFnzdd8y+DnmVT+OW18j+pKcduB9j0qqBywQGHxGuDYVOGLiPlf+IBXfqQWTg=="],
|
"@cvsa/core": ["@cvsa/core@0.0.10", "", { "dependencies": { "@koshnic/ratelimit": "^1.0.3", "chalk": "^5.4.1", "ioredis": "^5.6.1", "logform": "^2.7.0", "postgres": "^3.4.5", "winston": "^3.17.0" } }, "sha512-8gjSNRyLZcybLiFSUZFPc4nJsLQ7YO8lZSAEFJidyUA3a6CbB/UUC4G5jqWyWJ7xDA39w7szqpbVYKX3fb6W3g=="],
|
||||||
|
|
||||||
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
|
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
|
||||||
|
|
||||||
@ -275,6 +277,8 @@
|
|||||||
|
|
||||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
|
"@types/luxon": ["@types/luxon@3.6.2", "", {}, "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw=="],
|
||||||
|
|
||||||
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
||||||
|
|
||||||
"@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="],
|
"@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="],
|
||||||
@ -763,6 +767,8 @@
|
|||||||
|
|
||||||
"lru-cache": ["lru-cache@11.1.0", "", {}, "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A=="],
|
"lru-cache": ["lru-cache@11.1.0", "", {}, "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A=="],
|
||||||
|
|
||||||
|
"luxon": ["luxon@3.6.1", "", {}, "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ=="],
|
||||||
|
|
||||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||||
|
|
||||||
"markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="],
|
"markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="],
|
||||||
|
@ -6,7 +6,7 @@ export interface User {
|
|||||||
username: string;
|
username: string;
|
||||||
nickname: string | null;
|
nickname: string | null;
|
||||||
role: string;
|
role: string;
|
||||||
createdAt: string;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserProfile extends User {
|
export interface UserProfile extends User {
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cvsa/backend": "^0.5.3",
|
"@cvsa/backend": "^0.5.3",
|
||||||
"@cvsa/core": "^0.0.7",
|
"@cvsa/core": "0.0.10",
|
||||||
"@mdx-js/loader": "^3.1.0",
|
"@mdx-js/loader": "^3.1.0",
|
||||||
"@mdx-js/react": "^3.1.0",
|
"@mdx-js/react": "^3.1.0",
|
||||||
"@next/mdx": "^15.3.3",
|
"@next/mdx": "^15.3.3",
|
||||||
|
"@types/luxon": "^3.6.2",
|
||||||
"@types/mdx": "^2.0.13",
|
"@types/mdx": "^2.0.13",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
@ -22,6 +23,7 @@
|
|||||||
"fumadocs-mdx": "^11.6.6",
|
"fumadocs-mdx": "^11.6.6",
|
||||||
"i18next": "^25.2.1",
|
"i18next": "^25.2.1",
|
||||||
"jotai": "^2.12.5",
|
"jotai": "^2.12.5",
|
||||||
|
"luxon": "^3.6.1",
|
||||||
"next": "^15.3.3",
|
"next": "^15.3.3",
|
||||||
"next-intl": "^4.1.0",
|
"next-intl": "^4.1.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
|
Loading…
Reference in New Issue
Block a user