🐞 fix: 修复一系列问题
This commit is contained in:
parent
e8b69c5ab5
commit
462aab20af
4
.env
4
.env
@ -26,7 +26,7 @@ VITE_DESC_TEXT_OTHER = "哎呀,这都被你发现了( 再点击一次可关
|
|||||||
## 请注意不是 Web端 (JS API),免费申请,每日上限 5000 次
|
## 请注意不是 Web端 (JS API),免费申请,每日上限 5000 次
|
||||||
## 此处提供的服务可能会超量从而无法访问,请自行申请!请自行申请!请自行申请!
|
## 此处提供的服务可能会超量从而无法访问,请自行申请!请自行申请!请自行申请!
|
||||||
## 若此处设为空则调用 教书先生 API https://api.oioweb.cn/doc/weather/GetWeather
|
## 若此处设为空则调用 教书先生 API https://api.oioweb.cn/doc/weather/GetWeather
|
||||||
VITE_WEATHER_KEY = "6c13af6fc30868bee488faf2cc652ab4"
|
VITE_WEATHER_KEY = ""
|
||||||
|
|
||||||
# 建站日期
|
# 建站日期
|
||||||
## 若不需要,请设为空即可
|
## 若不需要,请设为空即可
|
||||||
@ -48,4 +48,4 @@ VITE_SONG_SERVER = "netease"
|
|||||||
# 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
# 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
||||||
VITE_SONG_TYPE = "playlist"
|
VITE_SONG_TYPE = "playlist"
|
||||||
# 播放 ID ( 若无需播放器,请设为空即可 )
|
# 播放 ID ( 若无需播放器,请设为空即可 )
|
||||||
VITE_SONG_ID = "7452421335"
|
VITE_SONG_ID = "9379831714"
|
51
.env.example
Normal file
51
.env.example
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# 站点信息
|
||||||
|
VITE_SITE_NAME = "無名の主页" # 名称
|
||||||
|
VITE_SITE_ANTHOR = "無名" # 作者
|
||||||
|
VITE_SITE_KEYWORDS = "無名,个人主页" # 关键词
|
||||||
|
VITE_SITE_DES = "一个默默无闻的主页" # 站点简介
|
||||||
|
VITE_SITE_URL = "imsyy.top" # 站点地址
|
||||||
|
VITE_SITE_LOGO = "/images/icon/favicon.ico" # 站点主图标
|
||||||
|
VITE_SITE_MAIN_LOGO = "/images/icon/logo.png" # 主页图标
|
||||||
|
VITE_SITE_APPLE_LOGO = "/images/logo/apple-touch-icon.png" # Apple 端图标
|
||||||
|
|
||||||
|
# 简介文本
|
||||||
|
VITE_DESC_HELLO = "Hello World !"
|
||||||
|
VITE_DESC_TEXT = "一个建立于 21 世纪的小站,存活于互联网的边缘"
|
||||||
|
VITE_DESC_HELLO_OTHER = "Oops !"
|
||||||
|
VITE_DESC_TEXT_OTHER = "哎呀,这都被你发现了( 再点击一次可关闭 )"
|
||||||
|
|
||||||
|
# 社交链接
|
||||||
|
## 请在 src/assets/socialLinks.json 文件中配置
|
||||||
|
|
||||||
|
# 网站链接
|
||||||
|
## 请在 src/assets/siteLinks.json 文件中配置
|
||||||
|
## 网站链接的图标名称可前往 https://www.xicons.org 自行挑选并在 src/components/Links/index.vue 中引入
|
||||||
|
|
||||||
|
# 天气 Key
|
||||||
|
## 请前往 高德开放平台注册 Web服务 Key
|
||||||
|
## 请注意不是 Web端 (JS API),免费申请,每日上限 5000 次
|
||||||
|
## 此处提供的服务可能会超量从而无法访问,请自行申请!请自行申请!请自行申请!
|
||||||
|
## 若此处设为空则调用 教书先生 API https://api.oioweb.cn/doc/weather/GetWeather
|
||||||
|
VITE_WEATHER_KEY = ""
|
||||||
|
|
||||||
|
# 建站日期
|
||||||
|
## 若不需要,请设为空即可
|
||||||
|
## 请按照 YYYY-MM-DD 格式填写或者仅填写年份 YYYY
|
||||||
|
VITE_SITE_START = "2020-10-24"
|
||||||
|
|
||||||
|
# ICP 备案号
|
||||||
|
## 若不需要,请设为空即可
|
||||||
|
VITE_SITE_ICP = "豫ICP备2022018134号-1"
|
||||||
|
|
||||||
|
# 歌曲 API 地址
|
||||||
|
## 请参照 https://github.com/xizeyoupan/Meting-API#deno-deploy 进行 API 服务部署
|
||||||
|
## 此处提供的服务可能会超量从而无法访问,请自行部署
|
||||||
|
## 若使用 QQ 音乐歌单,歌曲数量最好不要超出 50 首
|
||||||
|
## 备用:https://api.wuenci.com/meting/api/
|
||||||
|
VITE_SONG_API = "https://api-meting.imsyy.top/api"
|
||||||
|
# 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
|
||||||
|
VITE_SONG_SERVER = "netease"
|
||||||
|
# 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
||||||
|
VITE_SONG_TYPE = "playlist"
|
||||||
|
# 播放 ID ( 若无需播放器,请设为空即可 )
|
||||||
|
VITE_SONG_ID = "9379831714"
|
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -22,6 +22,14 @@ jobs:
|
|||||||
uses: actions/setup-node@v4.0.0
|
uses: actions/setup-node@v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: "18.x"
|
node-version: "18.x"
|
||||||
|
# 复制环境变量文件
|
||||||
|
- name: Copy .env.example
|
||||||
|
run: |
|
||||||
|
if (-not (Test-Path .env)) {
|
||||||
|
Copy-Item .env.example .env
|
||||||
|
} else {
|
||||||
|
Write-Host ".env file already exists. Skipping the copy step."
|
||||||
|
}
|
||||||
# 安装项目依赖
|
# 安装项目依赖
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: npm install
|
run: npm install
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,6 +11,7 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
.env
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
@ -4,6 +4,7 @@ WORKDIR /app
|
|||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install
|
RUN npm install
|
||||||
COPY . .
|
COPY . .
|
||||||
|
RUN [ ! -e ".env" ] && cp .env.example .env || true
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# 最小化镜像
|
# 最小化镜像
|
||||||
|
70
README.md
70
README.md
@ -7,17 +7,17 @@
|
|||||||
|
|
||||||
![無名の主页](/screenshots/main.jpg)
|
![無名の主页](/screenshots/main.jpg)
|
||||||
|
|
||||||
>主页的 Logo 字体已经过压缩,若用本站 Logo 以外的字母会变回默认字体,这里是 [完整字体](https://file.imsyy.top/font/Other/Pacifico-Regular.ttf),若无法下载,可将字体目录下的 `Pacifico-Regular-all.ttf` 进行替换
|
> 主页的 Logo 字体已经过压缩,若用本站 Logo 以外的字母会变回默认字体,这里是 [完整字体](https://file.imsyy.top/font/Other/Pacifico-Regular.ttf),若无法下载,可将字体目录下的 `Pacifico-Regular-all.ttf` 进行替换
|
||||||
|
|
||||||
### Demo
|
### 👀 Demo
|
||||||
|
|
||||||
>由于 CDN 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存
|
> 由于 CDN 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存
|
||||||
|
|
||||||
- [無名の主页](https://www.imsyy.top)
|
- [無名の主页](https://www.imsyy.top)
|
||||||
- [無名の主页 - Dev](https://home-imsyy.vercel.app)
|
- [無名の主页 - Dev](https://home-imsyy.vercel.app)
|
||||||
- [無名の主页 - 备用线路](https://home-5iw.pages.dev)
|
- [無名の主页 - 备用线路](https://home-5iw.pages.dev)
|
||||||
|
|
||||||
### 功能
|
### 🎉 功能
|
||||||
|
|
||||||
- [x] 载入动画
|
- [x] 载入动画
|
||||||
- [x] 站点简介
|
- [x] 站点简介
|
||||||
@ -28,7 +28,7 @@
|
|||||||
- [x] 音乐播放器
|
- [x] 音乐播放器
|
||||||
- [x] 移动端适配
|
- [x] 移动端适配
|
||||||
|
|
||||||
### 自动部署
|
### ⚙️ 自动部署
|
||||||
|
|
||||||
如果遇到构建环境或者打包过程出现错误,则可以采用 `Github Actions` 来进行自动构建
|
如果遇到构建环境或者打包过程出现错误,则可以采用 `Github Actions` 来进行自动构建
|
||||||
|
|
||||||
@ -40,15 +40,15 @@
|
|||||||
|
|
||||||
![步骤2](/screenshots/step2.jpg)
|
![步骤2](/screenshots/step2.jpg)
|
||||||
|
|
||||||
### 手动部署
|
### ⚙️ 手动部署
|
||||||
|
|
||||||
* **安装** [node.js](https://nodejs.org/zh-cn/) **环境**
|
- **安装** [node.js](https://nodejs.org/zh-cn/) **环境**
|
||||||
|
|
||||||
> node > 16.16.0
|
> node > 16.16.0
|
||||||
> npm > 8.15.0
|
> npm > 8.15.0
|
||||||
|
|
||||||
* 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
|
- 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
|
||||||
* 在 `终端` 中输入:
|
- 在 `终端` 中输入:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装 pnpm
|
# 安装 pnpm
|
||||||
@ -63,9 +63,10 @@ pnpm dev
|
|||||||
# 构建
|
# 构建
|
||||||
pnpm build
|
pnpm build
|
||||||
```
|
```
|
||||||
|
|
||||||
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,也可使用 `Vercel` 等托管平台一键导入并自动部署
|
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,也可使用 `Vercel` 等托管平台一键导入并自动部署
|
||||||
|
|
||||||
### Docker 部署
|
### ⚙️ Docker 部署
|
||||||
|
|
||||||
> 安装及配置 Docker 将不在此处说明,请自行解决
|
> 安装及配置 Docker 将不在此处说明,请自行解决
|
||||||
|
|
||||||
@ -76,6 +77,15 @@ docker build -t home .
|
|||||||
docker run -p 12445:12445 -d home
|
docker run -p 12445:12445 -d home
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ⚙️ Vercel 部署
|
||||||
|
|
||||||
|
> 其他部署平台大致相同,在此不做说明
|
||||||
|
|
||||||
|
1. 点击本仓库右上角的 `Fork`,复制本仓库到你的 `GitHub` 账号
|
||||||
|
2. 复制 `/.env.example` 文件并重命名为 `/.env`( 重要 )
|
||||||
|
3. 按需修改 `/.env` 文件中的配置
|
||||||
|
4. 点击 `Deploy`,即可成功部署
|
||||||
|
|
||||||
### 网站链接
|
### 网站链接
|
||||||
|
|
||||||
在 `src/assets/siteLinks.json` 中可以自定义网站链接(以指向自己的网站):
|
在 `src/assets/siteLinks.json` 中可以自定义网站链接(以指向自己的网站):
|
||||||
@ -130,11 +140,10 @@ const siteIcon = {
|
|||||||
|
|
||||||
也可自行更换其他方式
|
也可自行更换其他方式
|
||||||
|
|
||||||
|
|
||||||
### 音乐
|
### 音乐
|
||||||
|
|
||||||
>本项目采用了基于 `MetingJS` 的 `Aplayer` 音乐播放器,可实现快速自定义歌单
|
> 本项目采用了基于 `MetingJS` 的 `Aplayer` 音乐播放器,可实现快速自定义歌单
|
||||||
>*仅支持 **中国大陆地区**
|
> \*仅支持 **中国大陆地区**
|
||||||
|
|
||||||
请在 `.env` 文件中更改歌曲相关参数即可实现自定义歌单列表
|
请在 `.env` 文件中更改歌曲相关参数即可实现自定义歌单列表
|
||||||
|
|
||||||
@ -153,14 +162,14 @@ VITE_SONG_ID = "7452421335"
|
|||||||
|
|
||||||
现采用 `HarmonyOS Sans` 开源字体,采用字体拆分,提升加载速度
|
现采用 `HarmonyOS Sans` 开源字体,采用字体拆分,提升加载速度
|
||||||
|
|
||||||
>由于本站 `CDN` 已开启防盗链,**非本站域名不可访问**,请将字体引入链接更改为下方内容,否则 **自定义字体将失效**
|
> 由于本站 `CDN` 已开启防盗链,**非本站域名不可访问**,请将字体引入链接更改为下方内容,否则 **自定义字体将失效**
|
||||||
>
|
>
|
||||||
>`https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css`
|
> `https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css`
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>旧版方式</summary>
|
<summary>旧版方式</summary>
|
||||||
|
|
||||||
>由于本项目引入了中文字体,需要压缩中文字体以提高网页加载速度( 也可以取消使用中文字体 )
|
> 由于本项目引入了中文字体,需要压缩中文字体以提高网页加载速度( 也可以取消使用中文字体 )
|
||||||
|
|
||||||
#### 中文字体去除繁体
|
#### 中文字体去除繁体
|
||||||
|
|
||||||
@ -188,7 +197,7 @@ make clean all
|
|||||||
|
|
||||||
- 最终可对原字体进行缓加载,**先行加载压缩后的字体**
|
- 最终可对原字体进行缓加载,**先行加载压缩后的字体**
|
||||||
|
|
||||||
>详细信息可前往 [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) 查看原文
|
> 详细信息可前往 [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) 查看原文
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@ -201,12 +210,9 @@ make clean all
|
|||||||
如果想要添加更多的本地图片作为网站背景,可以将图片重命名 `background+数字` 的形式,并在 `src/components/Background/index.vue` 中进行修改:
|
如果想要添加更多的本地图片作为网站背景,可以将图片重命名 `background+数字` 的形式,并在 `src/components/Background/index.vue` 中进行修改:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
// 修改此处 Math.random() 后面的第一个数字为图片的数量
|
// 修改此处 Math.random() 后面的第一个数字为图片的数量
|
||||||
bgUrl.value = `/images/background${Math.floor(
|
bgUrl.value = `/images/background${Math.floor(Math.random() * 10 + 1)}.webp`;
|
||||||
Math.random() * 10 + 1
|
|
||||||
)}.webp`;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -216,20 +222,20 @@ if (type == 0) {
|
|||||||
|
|
||||||
### 技术栈
|
### 技术栈
|
||||||
|
|
||||||
* [Vue](https://cn.vuejs.org/)
|
- [Vue](https://cn.vuejs.org/)
|
||||||
* [Vite](https://vitejs.cn/vite3-cn/)
|
- [Vite](https://vitejs.cn/vite3-cn/)
|
||||||
* [Pinia](https://pinia.vuejs.org/zh/)
|
- [Pinia](https://pinia.vuejs.org/zh/)
|
||||||
* [IconPark](https://iconpark.oceanengine.com/official)
|
- [IconPark](https://iconpark.oceanengine.com/official)
|
||||||
* [xicons](https://xicons.org/)
|
- [xicons](https://xicons.org/)
|
||||||
* [Aplayer](https://aplayer.js.org/)
|
- [Aplayer](https://aplayer.js.org/)
|
||||||
|
|
||||||
### API
|
### API
|
||||||
|
|
||||||
* [小歪 API](https://api.aixiaowai.cn)
|
- [小歪 API](https://api.aixiaowai.cn)
|
||||||
* [搏天 API](https://api.btstu.cn/doc/sjbz.php)
|
- [搏天 API](https://api.btstu.cn/doc/sjbz.php)
|
||||||
* [教书先生 API](https://api.oioweb.cn/doc/weather/GetWeather)
|
- [教书先生 API](https://api.oioweb.cn/doc/weather/GetWeather)
|
||||||
* [高德开放平台](https://lbs.amap.com/)
|
- [高德开放平台](https://lbs.amap.com/)
|
||||||
* [Hitokoto 一言](https://hitokoto.cn/)
|
- [Hitokoto 一言](https://hitokoto.cn/)
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
|
57
auto-imports.d.ts
vendored
Normal file
57
auto-imports.d.ts
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Generated by 'unplugin-auto-import'
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
|
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||||
|
const computed: typeof import('vue')['computed']
|
||||||
|
const createApp: typeof import('vue')['createApp']
|
||||||
|
const customRef: typeof import('vue')['customRef']
|
||||||
|
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||||
|
const defineComponent: typeof import('vue')['defineComponent']
|
||||||
|
const effectScope: typeof import('vue')['effectScope']
|
||||||
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
|
const h: typeof import('vue')['h']
|
||||||
|
const inject: typeof import('vue')['inject']
|
||||||
|
const isProxy: typeof import('vue')['isProxy']
|
||||||
|
const isReactive: typeof import('vue')['isReactive']
|
||||||
|
const isReadonly: typeof import('vue')['isReadonly']
|
||||||
|
const isRef: typeof import('vue')['isRef']
|
||||||
|
const markRaw: typeof import('vue')['markRaw']
|
||||||
|
const nextTick: typeof import('vue')['nextTick']
|
||||||
|
const onActivated: typeof import('vue')['onActivated']
|
||||||
|
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||||
|
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||||
|
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||||
|
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||||
|
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||||
|
const onMounted: typeof import('vue')['onMounted']
|
||||||
|
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||||
|
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||||
|
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||||
|
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||||
|
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||||
|
const onUpdated: typeof import('vue')['onUpdated']
|
||||||
|
const provide: typeof import('vue')['provide']
|
||||||
|
const reactive: typeof import('vue')['reactive']
|
||||||
|
const readonly: typeof import('vue')['readonly']
|
||||||
|
const ref: typeof import('vue')['ref']
|
||||||
|
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||||
|
const resolveDirective: typeof import('vue')['resolveDirective']
|
||||||
|
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||||
|
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||||
|
const shallowRef: typeof import('vue')['shallowRef']
|
||||||
|
const toRaw: typeof import('vue')['toRaw']
|
||||||
|
const toRef: typeof import('vue')['toRef']
|
||||||
|
const toRefs: typeof import('vue')['toRefs']
|
||||||
|
const triggerRef: typeof import('vue')['triggerRef']
|
||||||
|
const unref: typeof import('vue')['unref']
|
||||||
|
const useAttrs: typeof import('vue')['useAttrs']
|
||||||
|
const useCssModule: typeof import('vue')['useCssModule']
|
||||||
|
const useCssVars: typeof import('vue')['useCssVars']
|
||||||
|
const useSlots: typeof import('vue')['useSlots']
|
||||||
|
const watch: typeof import('vue')['watch']
|
||||||
|
const watchEffect: typeof import('vue')['watchEffect']
|
||||||
|
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||||
|
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||||
|
}
|
35
components.d.ts
vendored
Normal file
35
components.d.ts
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// generated by unplugin-vue-components
|
||||||
|
// We suggest you to commit this file into source control
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
import '@vue/runtime-core'
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
Background: typeof import('./src/components/Background.vue')['default']
|
||||||
|
ElCard: typeof import('element-plus/es')['ElCard']
|
||||||
|
ElCol: typeof import('element-plus/es')['ElCol']
|
||||||
|
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||||
|
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||||
|
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||||
|
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||||
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||||
|
ElRow: typeof import('element-plus/es')['ElRow']
|
||||||
|
ElSlider: typeof import('element-plus/es')['ElSlider']
|
||||||
|
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||||
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
|
Footer: typeof import('./src/components/Footer.vue')['default']
|
||||||
|
Hitokoto: typeof import('./src/components/Hitokoto.vue')['default']
|
||||||
|
Links: typeof import('./src/components/Links.vue')['default']
|
||||||
|
Loading: typeof import('./src/components/Loading.vue')['default']
|
||||||
|
Message: typeof import('./src/components/Message.vue')['default']
|
||||||
|
MoreContent: typeof import('./src/components/MoreContent.vue')['default']
|
||||||
|
Music: typeof import('./src/components/Music.vue')['default']
|
||||||
|
Player: typeof import('./src/components/Player.vue')['default']
|
||||||
|
Set: typeof import('./src/components/Set.vue')['default']
|
||||||
|
SocialLinks: typeof import('./src/components/SocialLinks.vue')['default']
|
||||||
|
TimeCapsule: typeof import('./src/components/TimeCapsule.vue')['default']
|
||||||
|
Weather: typeof import('./src/components/Weather.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
17
package.json
17
package.json
@ -16,13 +16,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@worstone/vue-aplayer": "^1.0.6",
|
"@worstone/vue-aplayer": "^1.0.6",
|
||||||
"aplayer": "^1.10.1",
|
"aplayer": "^1.10.1",
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.8",
|
||||||
"element-plus": "^2.6.1",
|
"dayjs": "^1.11.10",
|
||||||
|
"element-plus": "^2.7.1",
|
||||||
"fetch-jsonp": "^1.3.0",
|
"fetch-jsonp": "^1.3.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
"swiper": "^9.4.1",
|
"swiper": "^11.1.1",
|
||||||
"vue": "^3.4.21"
|
"vue": "^3.4.24"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@icon-park/vue-next": "^1.4.2",
|
"@icon-park/vue-next": "^1.4.2",
|
||||||
@ -30,13 +31,13 @@
|
|||||||
"@vicons/utils": "^0.1.4",
|
"@vicons/utils": "^0.1.4",
|
||||||
"@vitejs/plugin-vue": "^4.6.2",
|
"@vitejs/plugin-vue": "^4.6.2",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-vue": "^9.22.0",
|
"eslint-plugin-vue": "^9.25.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"sass": "^1.71.1",
|
"sass": "^1.75.0",
|
||||||
"terser": "^5.29.1",
|
"terser": "^5.30.4",
|
||||||
"unplugin-auto-import": "^0.11.5",
|
"unplugin-auto-import": "^0.11.5",
|
||||||
"unplugin-vue-components": "^0.22.12",
|
"unplugin-vue-components": "^0.22.12",
|
||||||
"vite": "^4.5.2",
|
"vite": "^4.5.3",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-pwa": "^0.14.7"
|
"vite-plugin-pwa": "^0.14.7"
|
||||||
}
|
}
|
||||||
|
6021
pnpm-lock.yaml
6021
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -46,7 +46,7 @@ import { Icon } from "@vicons/utils";
|
|||||||
import { Link, Blog, CompactDisc, Cloud, Compass, Book, Fire, LaptopCode } from "@vicons/fa"; // 注意使用正确的类别
|
import { Link, Blog, CompactDisc, Cloud, Compass, Book, Fire, LaptopCode } from "@vicons/fa"; // 注意使用正确的类别
|
||||||
import { mainStore } from "@/store";
|
import { mainStore } from "@/store";
|
||||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||||
import { Pagination, Mousewheel } from "swiper";
|
import { Pagination, Mousewheel } from "swiper/modules";
|
||||||
import siteLinks from "@/assets/siteLinks.json";
|
import siteLinks from "@/assets/siteLinks.json";
|
||||||
|
|
||||||
const store = mainStore();
|
const store = mainStore();
|
||||||
@ -109,14 +109,22 @@ onMounted(() => {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.swiper-pagination {
|
.swiper-pagination {
|
||||||
position: static;
|
margin-top: 12px;
|
||||||
margin-top: 4px;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
:deep(.swiper-pagination-bullet) {
|
:deep(.swiper-pagination-bullet) {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
width: 18px;
|
width: 20px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
|
margin: 0 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
opacity: 0.2;
|
||||||
transition: opacity 0.3s;
|
transition: opacity 0.3s;
|
||||||
|
&.swiper-pagination-bullet-active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
<Icon size="16">
|
<Icon size="16">
|
||||||
<QuoteLeft />
|
<QuoteLeft />
|
||||||
</Icon>
|
</Icon>
|
||||||
<div class="text">
|
<Transition name="fade" mode="out-in">
|
||||||
|
<div :key="descriptionText.hello + descriptionText.text" class="text">
|
||||||
<p>{{ descriptionText.hello }}</p>
|
<p>{{ descriptionText.hello }}</p>
|
||||||
<p>{{ descriptionText.text }}</p>
|
<p>{{ descriptionText.text }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</Transition>
|
||||||
<Icon size="16">
|
<Icon size="16">
|
||||||
<QuoteRight />
|
<QuoteRight />
|
||||||
</Icon>
|
</Icon>
|
||||||
@ -146,6 +148,7 @@ watch(
|
|||||||
margin: 0.75rem 1rem;
|
margin: 0.75rem 1rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
&:nth-of-type(1) {
|
&:nth-of-type(1) {
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<go-start theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(0)" />
|
<go-start theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(0)" />
|
||||||
<div class="state" @click="changePlayState">
|
<Transition name="fade" mode="out-in">
|
||||||
|
<div :key="store.playerState" class="state" @click="changePlayState">
|
||||||
<play-one theme="filled" size="50" fill="#efefef" v-show="!store.playerState" />
|
<play-one theme="filled" size="50" fill="#efefef" v-show="!store.playerState" />
|
||||||
<pause theme="filled" size="50" fill="#efefef" v-show="store.playerState" />
|
<pause theme="filled" size="50" fill="#efefef" v-show="store.playerState" />
|
||||||
</div>
|
</div>
|
||||||
|
</Transition>
|
||||||
<go-end theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(1)" />
|
<go-end theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(1)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
@ -120,7 +122,7 @@ onMounted(() => {
|
|||||||
// 空格键事件
|
// 空格键事件
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
if (!store.musicIsOk) {
|
if (!store.musicIsOk) {
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
if (e.code == "Space") {
|
if (e.code == "Space") {
|
||||||
changePlayState();
|
changePlayState();
|
||||||
@ -177,6 +179,7 @@ watch(
|
|||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.state {
|
.state {
|
||||||
|
transition: opacity 0.1s;
|
||||||
.i-icon {
|
.i-icon {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
@ -4,23 +4,24 @@
|
|||||||
<hourglass-full theme="two-tone" size="24" :fill="['#efefef', '#00000020']" />
|
<hourglass-full theme="two-tone" size="24" :fill="['#efefef', '#00000020']" />
|
||||||
<span>时光胶囊</span>
|
<span>时光胶囊</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text">今日已经度过了 {{ timeData.day.elapsed }} 小时</span>
|
<div v-if="timeData" class="all-capsule">
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.day.pass" />
|
<div v-for="(item, tag, index) in timeData" :key="index" class="capsule-item">
|
||||||
<span class="text">本周已经度过了 {{ timeData.week.elapsed }} 天</span>
|
<div class="item-title">
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.week.pass" />
|
<span class="percentage">
|
||||||
<span class="text">本月已经度过了 {{ timeData.month.elapsed }} 天</span>
|
{{ item.name }}已度过
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.month.pass" />
|
<strong>{{ item.passed }}</strong>
|
||||||
<span class="text">今年已经度过了 {{ timeData.year.elapsed }} 个月</span>
|
{{ tag === "day" ? "小时" : "天" }}
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.year.pass" />
|
</span>
|
||||||
<div v-if="startDate?.length >= 4 && store.siteStartShow">
|
<span class="remaining">
|
||||||
<span class="text" v-html="startDateText" />
|
剩余 {{ item.remaining }} {{ tag === "day" ? "小时" : "天" }}
|
||||||
<!-- <el-progress
|
</span>
|
||||||
:show-text="false"
|
</div>
|
||||||
:indeterminate="true"
|
<el-progress :text-inside="true" :stroke-width="20" :percentage="item.percentage" />
|
||||||
:stroke-width="6"
|
</div>
|
||||||
:percentage="80"
|
<!-- 建站日期 -->
|
||||||
:duration="2"
|
<div v-if="store.siteStartShow" class="capsule-item start">
|
||||||
/> -->
|
<div class="item-title">{{ startDateText }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -65,10 +66,33 @@ onBeforeUnmount(() => {
|
|||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.text {
|
.all-capsule {
|
||||||
display: block;
|
.capsule-item {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
.item-title {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
margin: 1rem 0rem 0.5rem 0rem;
|
margin: 1rem 0rem 0.5rem 0rem;
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
|
.remaining {
|
||||||
|
opacity: 0.6;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-style: oblique;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
&.start {
|
||||||
|
.item-title {
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0.8;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,8 +5,7 @@ import App from "@/App.vue";
|
|||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia";
|
||||||
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
||||||
// swiper
|
// swiper
|
||||||
import "swiper/scss";
|
import "swiper/css";
|
||||||
import "swiper/scss/pagination";
|
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
@ -13,6 +13,8 @@ html,
|
|||||||
body {
|
body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100dvh;
|
||||||
|
height: 100dvh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
@ -53,8 +55,8 @@ p {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { h } from "vue";
|
import { h } from "vue";
|
||||||
import { SpaCandle } from "@icon-park/vue-next";
|
import { SpaCandle } from "@icon-park/vue-next";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
// 时钟
|
// 时钟
|
||||||
export const getCurrentTime = () => {
|
export const getCurrentTime = () => {
|
||||||
@ -25,47 +26,44 @@ export const getCurrentTime = () => {
|
|||||||
|
|
||||||
// 时光胶囊
|
// 时光胶囊
|
||||||
export const getTimeCapsule = () => {
|
export const getTimeCapsule = () => {
|
||||||
// 日进度
|
const now = dayjs();
|
||||||
const todayStartDate = new Date(new Date().toLocaleDateString()).getTime();
|
const dayText = {
|
||||||
const todayPassHours = (new Date() - todayStartDate) / 1000 / 60 / 60;
|
day: "今日",
|
||||||
const todayPassHoursPercent = (todayPassHours / 24) * 100;
|
week: "本周",
|
||||||
|
month: "本月",
|
||||||
// 周进度
|
year: "本年",
|
||||||
const weeks = [7, 1, 2, 3, 4, 5, 6];
|
};
|
||||||
const weekDay = weeks[new Date().getDay()];
|
/**
|
||||||
const weekDayPassPercent = (weekDay / 7) * 100;
|
* 计算时间差的函数
|
||||||
|
* @param {String} unit 时间单位,可以是 'day', 'week', 'month', 'year'
|
||||||
// 月进度
|
*/
|
||||||
const year = new Date().getFullYear();
|
const getDifference = (unit) => {
|
||||||
const date = new Date().getDate();
|
// 获取当前时间单位的开始时间
|
||||||
const month = new Date().getMonth() + 1;
|
const start = now.startOf(unit);
|
||||||
const monthAll = new Date(year, month, 0).getDate();
|
// 获取当前时间单位的结束时间
|
||||||
const monthPassPercent = (date / monthAll) * 100;
|
const end = now.endOf(unit);
|
||||||
|
// 计算总的天数或小时数
|
||||||
// 年进度
|
const total = Math.floor(end.diff(start, unit === "day" ? "hour" : "day")) + 1;
|
||||||
const yearStartDate = new Date(year, 0, 1).getTime();
|
// 计算已经过去的天数或小时数
|
||||||
const yearEndDate = new Date(year + 1, 0, 1).getTime();
|
const passed = Math.floor(now.diff(start, unit === "day" ? "hour" : "day"));
|
||||||
const yearPassHours = (new Date() - yearStartDate) / 1000 / 60 / 60;
|
// 计算剩余的天数或小时数
|
||||||
const yearTotalHours = (yearEndDate - yearStartDate) / 1000 / 60 / 60;
|
const remaining = total - passed;
|
||||||
const yearPassPercent = (yearPassHours / yearTotalHours) * 100;
|
// 计算已经过去的时间占总时间的百分比
|
||||||
|
const percentage = (passed / total) * 100;
|
||||||
|
// 返回数据
|
||||||
return {
|
return {
|
||||||
day: {
|
name: dayText[unit],
|
||||||
elapsed: Math.floor(todayPassHours),
|
total: total,
|
||||||
pass: Math.floor(todayPassHoursPercent),
|
passed: passed,
|
||||||
},
|
remaining: remaining,
|
||||||
week: {
|
percentage: Number(percentage.toFixed(2)),
|
||||||
elapsed: weekDay,
|
};
|
||||||
pass: Math.floor(weekDayPassPercent),
|
};
|
||||||
},
|
return {
|
||||||
month: {
|
day: getDifference("day"),
|
||||||
elapsed: date,
|
week: getDifference("week"),
|
||||||
pass: Math.floor(monthPassPercent),
|
month: getDifference("month"),
|
||||||
},
|
year: getDifference("year"),
|
||||||
year: {
|
|
||||||
elapsed: month - 1,
|
|
||||||
pass: Math.floor(yearPassPercent),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user