diff --git a/.tokeignore b/.tokeignore
index 0c4d337..aafc28c 100644
--- a/.tokeignore
+++ b/.tokeignore
@@ -2,4 +2,5 @@ data
*.json
*.svg
*.txt
-*.md
\ No newline at end of file
+*.md
+*config*
\ No newline at end of file
diff --git a/deno.json b/deno.json
index 43d84de..fcee853 100644
--- a/deno.json
+++ b/deno.json
@@ -1,20 +1,21 @@
{
- "lock": false,
- "workspace": [
- "./packages/crawler",
- "./packages/frontend",
- "./packages/backend",
- "./packages/core"
- ],
- "nodeModulesDir": "auto",
- "tasks": {
- "crawler": "deno task --filter 'crawler' all"
- },
- "fmt": {
- "useTabs": true,
- "lineWidth": 120,
- "indentWidth": 4,
- "semiColons": true,
- "proseWrap": "always"
- }
+ "lock": false,
+ "workspace": ["./packages/crawler", "./packages/frontend", "./packages/backend", "./packages/core"],
+ "nodeModulesDir": "auto",
+ "tasks": {
+ "crawler": "deno task --filter 'crawler' all"
+ },
+ "fmt": {
+ "useTabs": true,
+ "lineWidth": 120,
+ "indentWidth": 4,
+ "semiColons": true,
+ "proseWrap": "always"
+ },
+ "imports": {
+ "@astrojs/node": "npm:@astrojs/node@^9.1.3",
+ "@astrojs/svelte": "npm:@astrojs/svelte@^7.0.8",
+ "@core/db/": "./packages/core/db/",
+ "date-fns": "npm:date-fns@^4.1.0"
+ }
}
diff --git a/packages/crawler/db/pgConfig.ts b/packages/core/db/pgConfig.ts
similarity index 75%
rename from packages/crawler/db/pgConfig.ts
rename to packages/core/db/pgConfig.ts
index 5410760..adea921 100644
--- a/packages/crawler/db/pgConfig.ts
+++ b/packages/core/db/pgConfig.ts
@@ -8,6 +8,7 @@ if (unsetVars.length > 0) {
const databaseHost = Deno.env.get("DB_HOST")!;
const databaseName = Deno.env.get("DB_NAME")!;
+const databaseNameCred = Deno.env.get("DB_NAME_CRED")!;
const databaseUser = Deno.env.get("DB_USER")!;
const databasePassword = Deno.env.get("DB_PASSWORD")!;
const databasePort = Deno.env.get("DB_PORT")!;
@@ -19,3 +20,11 @@ export const postgresConfig = {
user: databaseUser,
password: databasePassword,
};
+
+export const postgresConfigCred = {
+ hostname: databaseHost,
+ port: parseInt(databasePort),
+ database: databaseNameCred,
+ user: databaseUser,
+ password: databasePassword,
+}
\ No newline at end of file
diff --git a/packages/crawler/db/init.ts b/packages/crawler/db/init.ts
index a1835b0..33bc3c6 100644
--- a/packages/crawler/db/init.ts
+++ b/packages/crawler/db/init.ts
@@ -1,5 +1,5 @@
import { Pool } from "https://deno.land/x/postgres@v0.19.3/mod.ts";
-import { postgresConfig } from "db/pgConfig.ts";
+import { postgresConfig } from "@core/db/pgConfig.ts";
const pool = new Pool(postgresConfig, 12);
diff --git a/packages/frontend/README.md b/packages/frontend/README.md
deleted file mode 100644
index 0eb9af9..0000000
--- a/packages/frontend/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Astro Starter Kit: Basics
-
-```sh
-deno create astro@latest -- --template basics
-```
-
-[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
-[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
-[](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
-
-> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
-
-
-
-## 🚀 Project Structure
-
-Inside of your Astro project, you'll see the following folders and files:
-
-```text
-/
-├── public/
-│ └── favicon.svg
-├── src/
-│ ├── layouts/
-│ │ └── Layout.astro
-│ └── pages/
-│ └── index.astro
-└── package.json
-```
-
-To learn more about the folder structure of an Astro project, refer to
-[our guide on project structure](https://docs.astro.build/en/basics/project-structure/).
-
-## 🧞 Commands
-
-All commands are run from the root of the project, from a terminal:
-
-| Command | Action |
-| :--------------------- | :----------------------------------------------- |
-| `deno install` | Installs dependencies |
-| `deno dev` | Starts local dev server at `localhost:4321` |
-| `deno build` | Build your production site to `./dist/` |
-| `deno preview` | Preview your build locally, before deploying |
-| `deno astro ...` | Run CLI commands like `astro add`, `astro check` |
-| `deno astro -- --help` | Get help using the Astro CLI |
-
-## 👀 Want to learn more?
-
-Feel free to check [our documentation](https://docs.astro.build) or jump into our
-[Discord server](https://astro.build/chat).
diff --git a/packages/frontend/astro.config.mjs b/packages/frontend/astro.config.mjs
index e6619b2..79ca8e0 100644
--- a/packages/frontend/astro.config.mjs
+++ b/packages/frontend/astro.config.mjs
@@ -1,13 +1,24 @@
// @ts-check
import { defineConfig } from "astro/config";
+import tailwind from "@astrojs/tailwind";
// https://astro.build/config
+import tsconfigPaths from "vite-tsconfig-paths";
+import node from "@astrojs/node";
+import svelte from "@astrojs/svelte";
+
export default defineConfig({
+ output: "server",
+ adapter: node({
+ mode: "standalone",
+ }),
+ integrations: [tailwind(), svelte()],
vite: {
server: {
fs: {
allow: [".", "../../"],
},
},
+ plugins: [tsconfigPaths()],
},
});
diff --git a/packages/frontend/deno.json b/packages/frontend/deno.json
new file mode 100644
index 0000000..675c374
--- /dev/null
+++ b/packages/frontend/deno.json
@@ -0,0 +1,8 @@
+{
+ "name": "@cvsa/frontend",
+ "tasks": {
+ "preview": "bun run astro preview",
+ "build": "bun run astro build"
+ },
+ "exports": "./main.ts"
+}
diff --git a/packages/frontend/main.ts b/packages/frontend/main.ts
new file mode 100644
index 0000000..f6ef10d
--- /dev/null
+++ b/packages/frontend/main.ts
@@ -0,0 +1 @@
+export const VERSION = "1.2.6";
\ No newline at end of file
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 8761ba2..377d360 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -1,14 +1,23 @@
{
- "name": "frontend",
- "type": "module",
- "version": "0.0.1",
- "scripts": {
- "dev": "astro dev",
- "build": "astro build",
- "preview": "astro preview",
- "astro": "astro"
- },
- "dependencies": {
- "astro": "^5.5.5"
- }
+ "name": "frontend",
+ "type": "module",
+ "version": "0.0.1",
+ "scripts": {
+ "dev": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview",
+ "astro": "astro"
+ },
+ "dependencies": {
+ "@astrojs/tailwind": "^6.0.2",
+ "astro": "^5.5.5",
+ "autoprefixer": "^10.4.21",
+ "pg": "^8.11.11",
+ "postcss": "^8.5.3",
+ "tailwindcss": "^3.0.24",
+ "vite-tsconfig-paths": "^5.1.4"
+ },
+ "devDependencies": {
+ "@types/pg": "^8.11.11"
+ }
}
diff --git a/packages/frontend/src/assets/TitleBar Mobile Dark.svg b/packages/frontend/src/assets/TitleBar Mobile Dark.svg
new file mode 100644
index 0000000..3b1a7e5
--- /dev/null
+++ b/packages/frontend/src/assets/TitleBar Mobile Dark.svg
@@ -0,0 +1,7 @@
+
+
+ Created with Pixso.
+
+
+
+
diff --git a/packages/frontend/src/assets/TitleBar Mobile Light.svg b/packages/frontend/src/assets/TitleBar Mobile Light.svg
new file mode 100644
index 0000000..365e6a4
--- /dev/null
+++ b/packages/frontend/src/assets/TitleBar Mobile Light.svg
@@ -0,0 +1,7 @@
+
+
+ Created with Pixso.
+
+
+
+
diff --git a/packages/frontend/src/assets/TitleBar-Dark.svg b/packages/frontend/src/assets/TitleBar-Dark.svg
new file mode 100644
index 0000000..02f0398
--- /dev/null
+++ b/packages/frontend/src/assets/TitleBar-Dark.svg
@@ -0,0 +1,15 @@
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/assets/TitleBar-Light.svg b/packages/frontend/src/assets/TitleBar-Light.svg
new file mode 100644
index 0000000..92482e0
--- /dev/null
+++ b/packages/frontend/src/assets/TitleBar-Light.svg
@@ -0,0 +1,15 @@
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/assets/astro.svg b/packages/frontend/src/assets/astro.svg
deleted file mode 100644
index 8cf8fb0..0000000
--- a/packages/frontend/src/assets/astro.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/packages/frontend/src/assets/background.svg b/packages/frontend/src/assets/background.svg
deleted file mode 100644
index 4b2be0a..0000000
--- a/packages/frontend/src/assets/background.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/packages/frontend/src/assets/header-logo-dark.svg b/packages/frontend/src/assets/header-logo-dark.svg
new file mode 100644
index 0000000..002540f
--- /dev/null
+++ b/packages/frontend/src/assets/header-logo-dark.svg
@@ -0,0 +1,15 @@
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/assets/header-logo-light.svg b/packages/frontend/src/assets/header-logo-light.svg
new file mode 100644
index 0000000..acc0c15
--- /dev/null
+++ b/packages/frontend/src/assets/header-logo-light.svg
@@ -0,0 +1,15 @@
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/assets/标题-浅色.svg b/packages/frontend/src/assets/标题-浅色.svg
new file mode 100644
index 0000000..77e3e1e
--- /dev/null
+++ b/packages/frontend/src/assets/标题-浅色.svg
@@ -0,0 +1,15 @@
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/assets/标题-深色.svg b/packages/frontend/src/assets/标题-深色.svg
new file mode 100644
index 0000000..a24984d
--- /dev/null
+++ b/packages/frontend/src/assets/标题-深色.svg
@@ -0,0 +1,15 @@
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/components/CloseIcon.svelte b/packages/frontend/src/components/CloseIcon.svelte
new file mode 100644
index 0000000..cb98947
--- /dev/null
+++ b/packages/frontend/src/components/CloseIcon.svelte
@@ -0,0 +1,12 @@
+
+
+
diff --git a/packages/frontend/src/components/DarkModeImage.svelte b/packages/frontend/src/components/DarkModeImage.svelte
new file mode 100644
index 0000000..aa4caeb
--- /dev/null
+++ b/packages/frontend/src/components/DarkModeImage.svelte
@@ -0,0 +1,41 @@
+
+
+
\ No newline at end of file
diff --git a/packages/frontend/src/components/MenuIcon.svelte b/packages/frontend/src/components/MenuIcon.svelte
new file mode 100644
index 0000000..1c74e68
--- /dev/null
+++ b/packages/frontend/src/components/MenuIcon.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Created with Pixso.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/components/SearchBox.svelte b/packages/frontend/src/components/SearchBox.svelte
new file mode 100644
index 0000000..52d8a1a
--- /dev/null
+++ b/packages/frontend/src/components/SearchBox.svelte
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
diff --git a/packages/frontend/src/components/SearchIcon.svelte b/packages/frontend/src/components/SearchIcon.svelte
new file mode 100644
index 0000000..d23c8be
--- /dev/null
+++ b/packages/frontend/src/components/SearchIcon.svelte
@@ -0,0 +1,12 @@
+
+
+
\ No newline at end of file
diff --git a/packages/frontend/src/components/TitleBar.astro b/packages/frontend/src/components/TitleBar.astro
new file mode 100644
index 0000000..aa0963e
--- /dev/null
+++ b/packages/frontend/src/components/TitleBar.astro
@@ -0,0 +1,30 @@
+---
+import astroLogoLight from "@assets/标题-浅色.svg";
+import astroLogoDark from "@assets/标题-深色.svg";
+import DarkModeImage from "@components/DarkModeImage.svelte";
+import SearchBox from "@components/SearchBox.svelte";
+import TitleBarMobile from "@components/TitleBarMobile.svelte";
+---
+
+
+
+
diff --git a/packages/frontend/src/components/TitleBarMobile.svelte b/packages/frontend/src/components/TitleBarMobile.svelte
new file mode 100644
index 0000000..5a8754b
--- /dev/null
+++ b/packages/frontend/src/components/TitleBarMobile.svelte
@@ -0,0 +1,47 @@
+
+
+
+ {#if !showSearchBox}
+
+
+
+
+ {/if}
+ {#if showSearchBox}
+
+ {/if}
+
(showSearchBox = !showSearchBox)}
+ >
+ {#if showSearchBox}
+
+ {:else}
+
+ {/if}
+
+
diff --git a/packages/frontend/src/components/Welcome.astro b/packages/frontend/src/components/Welcome.astro
index 52e0333..04130ae 100644
--- a/packages/frontend/src/components/Welcome.astro
+++ b/packages/frontend/src/components/Welcome.astro
@@ -1,210 +1,10 @@
---
-import astroLogo from '../assets/astro.svg';
-import background from '../assets/background.svg';
+import TitleBar from "@components/TitleBar.astro";
---
-
-
-
+
+ 正在施工中……
+ 在搜索栏输入BV号或AV号,可以查询目前数据库收集到的信息~
+
diff --git a/packages/frontend/src/content/about.md b/packages/frontend/src/content/about.md
new file mode 100644
index 0000000..8c2506a
--- /dev/null
+++ b/packages/frontend/src/content/about.md
@@ -0,0 +1,60 @@
+# 关于「中V档案馆」
+
+「中V档案馆」是一个旨在收录与展示「中文歌声合成作品」及有关信息的网站。
+
+## 创建背景与关联工作
+
+纵观整个互联网,对于「中文歌声合成」或「中文虚拟歌手」(常简称为中V或VC)相关信息进行较为系统、全面地整理收集的主要有以下几个网站:
+
+- [萌娘百科](https://zh.moegirl.org.cn/):
+ 收录了大量中V歌曲及歌姬的信息,呈现形式为传统维基(基于[MediaWiki](https://www.mediawiki.org/))。
+- [VCPedia](https://vcpedia.cn/):
+ 由原萌娘百科中文歌声合成编辑团队的部分成员搭建,专属于中文歌声合成相关内容的信息集成站点[^1],呈现形式为传统维基(基于[MediaWiki](https://www.mediawiki.org/))。
+- [VocaDB](https://vocadb.net/): 一个围绕 Vocaloid、UTAU 和其他歌声合成器的协作数据库,其中包含艺术家、唱片、PV
+ 等[^2],其中包含大量中文歌声合成作品。
+- [天钿Daily](https://tdd.bunnyxt.com/):一个VC相关数据交流与分享的网站。致力于VC相关数据交流,定期抓取VC相关数据,选取有意义的纬度展示。[^3]
+
+上述网站中,或多或少存在一些不足,例如:
+
+- 萌娘百科、VCPedia受限于传统维基,绝大多数内容依赖人工编辑。
+- VocaDB基于结构化数据库构建,由此可以依赖程序生成一些信息,但**条目收录**仍然完全依赖人工完成。
+- VocaDB主要专注于元数据展示,少有关于歌曲、作者等的描述性的文字,也缺乏描述性的背景信息。
+- 天钿Daily只展示歌曲的统计数据及历史趋势,没有关于歌曲其它信息的收集。
+
+因此,**中V档案馆**吸取前人经验,克服上述网站的不足,希望做到:
+
+- 歌曲收录(指发现歌曲并创建条目)的完全自动化
+- 歌曲元信息提取的高度自动化
+- 歌曲统计数据收集的完全自动化
+- 在程序辅助的同时欢迎并鼓励贡献者参与编辑(主要为描述性内容)或纠错
+- 在适当的许可声明下,引用来自上述源的数据,使内容更加全面、丰富。
+
+## 技术架构
+
+参见[CVSA文档](https://cvsa.gitbook.io/)。
+
+## 开放许可
+
+受本文以[CC BY-NC-SA 4.0协议](https://creativecommons.org/licenses/by-nc-sa/4.0/)提供。
+
+### 数据库
+
+中V档案馆使用[PostgreSQL](https://postgresql.org)作为数据库,我们承诺定期导出数据库转储 (dump)
+文件并公开,其内容遵从以下协议或条款:
+
+- 数据库中的事实性数据,根据适用法律,不构成受版权保护的内容。中V档案馆放弃一切可能的权利([CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/))。
+- 对于数据库中有原创性的内容(如贡献者编辑的描述性内容),如无例外,以[CC BY 4.0协议](https://creativecommons.org/licenses/by/4.0/)提供。
+- 对于引用、摘编或改编自萌娘百科、VCPedia的内容,以与原始协议(CC BY-NC-SA 3.0
+ CN)兼容的协议[CC BY-NC-SA 4.0协议](https://creativecommons.org/licenses/by-nc-sa/4.0/)提供,并注明原始协议 。
+ > 根据原始协议第四条第2项内容,CC BY-NC-SA 4.0协议为与原始协议具有相同授权要素的后续版本(“可适用的协议”)。
+- 中V档案馆文档使用[CC BY 4.0协议](https://creativecommons.org/licenses/by/4.0/)。
+
+### 软件代码
+
+用于构建中V档案馆的软件代码在[AGPL 3.0](https://www.gnu.org/licenses/agpl-3.0.html)许可证下公开,参见[LICENSE](./LICENSE)
+
+[^1]: 引用自[VCPedia](https://vcpedia.cn/%E9%A6%96%E9%A1%B5),于[知识共享 署名-非商业性使用-相同方式共享 3.0中国大陆 (CC BY-NC-SA 3.0 CN) 许可协议](https://creativecommons.org/licenses/by-nc-sa/3.0/cn/)下提供。
+
+[^2]: 翻译自[VocaDB](https://vocadb.net/),于[CC BY 4.0协议](https://creativecommons.org/licenses/by/4.0/)下提供。
+
+[^3]: 引用自[关于 - 天钿Daily](https://tdd.bunnyxt.com/about)
diff --git a/packages/frontend/src/layouts/Layout.astro b/packages/frontend/src/layouts/Layout.astro
index e455c61..e33cf4b 100644
--- a/packages/frontend/src/layouts/Layout.astro
+++ b/packages/frontend/src/layouts/Layout.astro
@@ -1,22 +1,15 @@
-
-
-
-
-
-
-
- Astro Basics
-
-
-
-
-
+---
+import "../styles/global.css";
+---
-
+
+
+
+
+
+ CVSA 前端
+
+
+
+
+
diff --git a/packages/frontend/src/pages/404.astro b/packages/frontend/src/pages/404.astro
new file mode 100644
index 0000000..2410b5c
--- /dev/null
+++ b/packages/frontend/src/pages/404.astro
@@ -0,0 +1,10 @@
+---
+import Layout from '@layouts/Layout.astro';
+---
+
+
+
+ 404
+ 咦……页面去哪里了(゚Д゚≡゚д゚)!?
+
+
diff --git a/packages/frontend/src/pages/about.astro b/packages/frontend/src/pages/about.astro
new file mode 100644
index 0000000..8f50a8e
--- /dev/null
+++ b/packages/frontend/src/pages/about.astro
@@ -0,0 +1,15 @@
+---
+import TitleBar from "@components/TitleBar.astro";
+import Layout from '@layouts/Layout.astro';
+import {Content as AboutContent} from '../content/about.md';
+import "../styles/content.css";
+---
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/frontend/src/pages/index.astro b/packages/frontend/src/pages/index.astro
index c04f360..2dffcbe 100644
--- a/packages/frontend/src/pages/index.astro
+++ b/packages/frontend/src/pages/index.astro
@@ -1,9 +1,6 @@
---
-import Welcome from '../components/Welcome.astro';
-import Layout from '../layouts/Layout.astro';
-
-// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build
-// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh.
+import Welcome from '@components/Welcome.astro';
+import Layout from '@layouts/Layout.astro';
---
diff --git a/packages/frontend/src/pages/song/[id]/info.astro b/packages/frontend/src/pages/song/[id]/info.astro
new file mode 100644
index 0000000..f6fd40b
--- /dev/null
+++ b/packages/frontend/src/pages/song/[id]/info.astro
@@ -0,0 +1,200 @@
+---
+import Layout from "@layouts/Layout.astro";
+import TitleBar from "@components/TitleBar.astro";
+import pg from "pg";
+import { format } from 'date-fns';
+import { zhCN } from 'date-fns/locale';
+
+const databaseHost = process.env.DB_HOST
+const databaseName = process.env.DB_NAME
+const databaseUser = process.env.DB_USER
+const databasePassword = process.env.DB_PASSWORD
+const databasePort = process.env.DB_PORT
+
+const postgresConfig = {
+ hostname: databaseHost,
+ port: parseInt(databasePort!),
+ database: databaseName,
+ user: databaseUser,
+ password: databasePassword,
+};
+
+// 路由参数
+const { id } = Astro.params;
+const { Client } = pg;
+const client = new Client(postgresConfig);
+await client.connect();
+
+// 数据库查询函数
+async function getVideoMetadata(aid: number) {
+ const res = await client.query("SELECT * FROM bilibili_metadata WHERE aid = $1", [aid]);
+ if (res.rows.length <= 0) {
+ return null;
+ }
+ const row = res.rows[0];
+ if (row) {
+ return row;
+ }
+ return {};
+}
+
+async function getVideoSnapshots(aid: number) {
+ const res = await client.query("SELECT * FROM video_snapshot WHERE aid = $1 ORDER BY created_at DESC", [
+ aid,
+ ]);
+ if (res.rows.length <= 0) {
+ return null;
+ }
+ return res.rows;
+}
+
+async function getAidFromBV(bv: string) {
+ const res = await client.query("SELECT aid FROM bilibili_metadata WHERE bvid = $1", [bv]);
+ if (res.rows.length <= 0) {
+ return null;
+ }
+ const row = res.rows[0];
+ if (row && row.aid) {
+ return Number(row.aid);
+ }
+ return null;
+}
+
+async function getVideoAid(id: string) {
+ if (id.startsWith("av")) {
+ return parseInt(id.slice(2));
+ } else if (id.startsWith("BV")) {
+ return getAidFromBV(id);
+ }
+ return parseInt(id);
+}
+
+// 获取数据
+if (!id) {
+ Astro.response.status = 404;
+ client.end();
+ return new Response(null, { status: 404 });
+}
+const aid = await getVideoAid(id);
+if (!aid || isNaN(aid)) {
+ Astro.response.status = 404;
+ client.end();
+ return new Response(null, { status: 404 });
+}
+const videoInfo = await getVideoMetadata(aid);
+const snapshots = await getVideoSnapshots(aid);
+client.end();
+
+interface Snapshot {
+ created_at: Date;
+ views: number;
+ danmakus: number;
+ replies: number;
+ coins: number;
+ likes: number;
+ favorites: number;
+ shares: number;
+ id: number;
+}
+---
+
+
+
+
+
+
+
+
+
基本信息
+
+
+
+
+ ID
+ {videoInfo?.id}
+
+
+ AID
+ {videoInfo?.aid}
+
+
+ BVID
+ {videoInfo?.bvid}
+
+
+ 标题
+ {videoInfo?.title}
+
+
+ 描述
+ {videoInfo?.description}
+
+
+ UID
+ {videoInfo?.uid}
+
+
+ 标签
+ {videoInfo?.tags}
+
+
+ 发布时间
+ {videoInfo?.published_at ? format(new Date(videoInfo.published_at), 'yyyy-MM-dd HH:mm:ss', { locale: zhCN }) : '-'}
+
+
+ 时长 (秒)
+ {videoInfo?.duration}
+
+
+ 创建时间
+ {videoInfo?.created_at ? format(new Date(videoInfo.created_at), 'yyyy-MM-dd HH:mm:ss', { locale: zhCN }) : '-'}
+
+
+ 封面
+ {videoInfo?.cover_url ? videoInfo.cover_url : '-'}
+
+
+
+
+
+
+
+
播放量历史数据
+ {snapshots && snapshots.length > 0 ? (
+
+
+
+
+ 创建时间
+ 观看
+ 硬币
+ 点赞
+ 收藏
+ 分享
+ 弹幕
+ 评论
+
+
+
+ {snapshots.map((snapshot: Snapshot) => (
+
+ {format(new Date(snapshot.created_at), 'yyyy-MM-dd HH:mm:ss', { locale: zhCN })}
+ {snapshot.views}
+ {snapshot.coins}
+ {snapshot.likes}
+ {snapshot.favorites}
+ {snapshot.shares}
+ {snapshot.danmakus}
+ {snapshot.replies}
+
+ ))}
+
+
+
+ ) : (
+
暂无历史数据。
+ )}
+
+
+
+
diff --git a/packages/frontend/src/styles/content.css b/packages/frontend/src/styles/content.css
new file mode 100644
index 0000000..74c9bd1
--- /dev/null
+++ b/packages/frontend/src/styles/content.css
@@ -0,0 +1,76 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.content {
+ @apply text-gray-800 dark:text-zinc-100;
+
+ h1,
+ h2,
+ h3,
+ h4 {
+ @apply font-bold text-gray-900 dark:text-white my-4;
+ }
+
+ h1 {
+ @apply text-3xl;
+ }
+
+ h2 {
+ @apply text-2xl;
+ }
+
+ h3 {
+ @apply text-xl;
+ }
+
+ h4 {
+ @apply text-lg;
+ }
+
+ p {
+ @apply my-4;
+ }
+
+ a {
+ @apply text-blue-500 hover:text-blue-700 dark:hover:text-blue-400 underline;
+ }
+
+ ul,
+ ol {
+ @apply list-disc list-inside my-4;
+ }
+
+ li {
+ @apply my-2;
+ }
+
+ blockquote {
+ @apply border-l-4 border-gray-300 pl-4 italic my-4;
+ }
+
+ code {
+ @apply bg-gray-100 text-gray-800 rounded px-1 duration-300;
+ }
+
+ pre {
+ @apply bg-gray-100 p-4 rounded overflow-x-auto my-4 duration-300 h-0;
+ }
+
+ table {
+ @apply w-full border-collapse my-4;
+ }
+
+ th,
+ td {
+ @apply border border-gray-300 p-2;
+ }
+
+ th {
+ @apply bg-gray-200 font-bold;
+ }
+ ul li p,
+ ol li p {
+ @apply inline;
+ }
+}
\ No newline at end of file
diff --git a/packages/frontend/src/styles/global.css b/packages/frontend/src/styles/global.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/packages/frontend/src/styles/global.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js
new file mode 100644
index 0000000..b34cf45
--- /dev/null
+++ b/packages/frontend/tailwind.config.js
@@ -0,0 +1,8 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+};
diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json
index a9210e6..bee52b7 100644
--- a/packages/frontend/tsconfig.json
+++ b/packages/frontend/tsconfig.json
@@ -1,5 +1,16 @@
{
- "extends": "astro/tsconfigs/strict",
- "include": [".astro/types.d.ts", "**/*"],
- "exclude": ["dist"]
+ "extends": "astro/tsconfigs/strict",
+ "include": [".astro/types.d.ts", "**/*"],
+ "exclude": ["dist"],
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@components/*": ["src/components/*"],
+ "@layouts/*": ["src/layouts/*"],
+ "@utils/*": ["src/utils/*"],
+ "@assets/*": ["src/assets/*"],
+ "@styles": ["src/styles/*"],
+ "@core/*": ["../core/*"]
+ }
+ }
}