feat: 添加 API 模块并更新项目配置

- 新增 `src/apis/index.ts` 文件,用于管理与塞壬唱片官网 API 的交互
- 在 `Home.vue` 中添加 API 调用逻辑,获取并打印专辑数据
- 更新 `vite.config.ts`,添加路径别名配置
- 在 `package.json` 中添加 `@types/node` 依赖
- 调整 `Playing.vue` 和 `App.vue` 的布局样式
- 更新 `manifest.json` 中的安全策略,允许连接到 API
This commit is contained in:
Astrian Zheng 2025-05-24 10:52:32 +10:00
parent 51185b6ff0
commit a6ab9aacb5
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
8 changed files with 116 additions and 7 deletions

18
package-lock.json generated
View File

@ -17,6 +17,7 @@
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "^22.15.21",
"@vitejs/plugin-vue": "^5.2.1",
"typescript": "~5.6.2",
"vite": "^6.0.1",
@ -1234,6 +1235,16 @@
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.15.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz",
"integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/@vitejs/plugin-vue": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
@ -2359,6 +2370,13 @@
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"devOptional": true,
"license": "MIT"
},
"node_modules/vite": {
"version": "6.3.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",

View File

@ -22,6 +22,7 @@
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "^22.15.21",
"@vitejs/plugin-vue": "^5.2.1",
"typescript": "~5.6.2",
"vite": "^6.0.1",

View File

@ -21,7 +21,7 @@
},
"permissions": ["tabs", "webRequest"],
"content_security_policy": {
"extension_pages": "default-src 'self'; script-src 'self' http://localhost:5173; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:5173;",
"extension_pages": "default-src 'self'; script-src 'self' http://localhost:5173; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:5173 https://monster-siren.hypergryph.com;",
"sandbox": "sandbox"
}
}

View File

@ -4,11 +4,14 @@ import Playing from './components/Playing.vue'
</script>
<template>
<div class="flex overflow-hidden flex-1 w-screen h-screen">
<Sidebar />
<div class="flex-1 bg-[#070909]">
<Playing />
<RouterView />
<div class="w-screen h-screen overflow-hidden">
<div class="flex flex-1 w-full h-full">
<Sidebar />
<div class="flex-1 bg-[#070909] w-full overflow-y-auto">
<RouterView />
</div>
</div>
<Playing />
</div>
</template>

69
src/apis/index.ts Normal file
View File

@ -0,0 +1,69 @@
import axios from 'axios'
const msrInstance = axios.create({
baseURL: 'https://monster-siren.hypergryph.com/api/',
})
type SongList = {
list: Song[]
}
type Song = {
cid: string
name: string
albumCid: string
sourceUrl?: string
lyricUrl?: string | null
mvUrl?: string | null
mvCoverUrl?: string | null
artists: string[]
}
type Album = {
cid: string
name: string
intro?: string
belong?: string
coverUrl: string
coverDeUrl?: string
artistes: string[]
}
type AlbumList = Album[]
interface ApiResponse {
code: number
msg: string
data: unknown
}
export default {
async getSongs() {
const songs: {
data: ApiResponse
} = await msrInstance.get('songs')
if (songs.data.code !== 0) { throw new Error(`Cannot get songs: ${songs.data.msg}`) }
return { songs: songs.data.data as { list: SongList } }
},
async getSong(cid: string) {
const song: {
data: ApiResponse
} = await msrInstance.get(`song/${cid}`)
if (song.data.code!== 0) { return new Error(`Cannot get song: ${song.data.msg}`) }
return { song: song.data.data as Song }
},
async getAlbums() {
const albums: {
data: ApiResponse
} = await msrInstance.get('albums')
if (albums.data.code!== 0) { throw new Error(`Cannot get albums: ${albums.data.msg}`) }
return albums.data.data as AlbumList
},
async getAlbum(cid: string) {
const album: {
data: ApiResponse
} = await msrInstance.get(`album/${cid}/data`)
if (album.data.code!== 0) { throw new Error(`Cannot get album: ${album.data.msg}`) }
return album.data.data as Album
}
}

View File

@ -1,3 +1,5 @@
<template>
<div class="bg-[#070909a7] backdrop-blur-3xl h-16 shadow-[0px_-1px_1rem_0px_rgba(0,0,0,0.1)] border-b border-b-[#1c1c1c]"></div>
<div class="bg-[#070909a7] backdrop-blur-3xl h-16 shadow-[0px_-1px_1rem_0px_rgba(0,0,0,0.1)] border-t border-t-[#1c1c1c] sticky bottom-0 w-full">
</div>
</template>

View File

@ -1,3 +1,13 @@
<script setup lang="ts">
import apis from '../apis'
import { onMounted } from 'vue'
onMounted(async () => {
const res = await apis.getAlbums()
console.log(res)
})
</script>
<template>
<div class="text-white">hello</div>
</template>

View File

@ -1,6 +1,7 @@
import tailwindcss from '@tailwindcss/vite'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import path from "node:path"
// https://vite.dev/config/
export default defineConfig({
@ -25,4 +26,9 @@ export default defineConfig({
},
},
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
}
})