Compare commits
No commits in common. "dev" and "v1.2" have entirely different histories.
@ -1,15 +0,0 @@
|
|||||||
node_modules
|
|
||||||
npm-debug.log
|
|
||||||
Dockerfile*
|
|
||||||
docker-compose*
|
|
||||||
.dockerignore
|
|
||||||
.git
|
|
||||||
.github
|
|
||||||
.gitignore
|
|
||||||
README.md
|
|
||||||
LICENSE
|
|
||||||
.vscode
|
|
||||||
dist
|
|
||||||
build
|
|
||||||
images
|
|
||||||
script
|
|
51
.env.example
@ -1,51 +0,0 @@
|
|||||||
# 站点信息
|
|
||||||
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"
|
|
@ -1,3 +0,0 @@
|
|||||||
node_modules
|
|
||||||
dist
|
|
||||||
.gitignore
|
|
@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"es2021": true
|
|
||||||
},
|
|
||||||
"extends": ["eslint:recommended", "plugin:vue/vue3-essential"],
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": "latest",
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"plugins": ["vue"],
|
|
||||||
"rules": {
|
|
||||||
"vue/multi-word-component-names": "off"
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"defineProps": true,
|
|
||||||
"defineEmits": true,
|
|
||||||
"withDefaults": true,
|
|
||||||
"h": true,
|
|
||||||
"vue": true,
|
|
||||||
"ref": true,
|
|
||||||
"reactive": true,
|
|
||||||
"computed": true,
|
|
||||||
"watch": true,
|
|
||||||
"provide": true,
|
|
||||||
"inject": true,
|
|
||||||
"defineComponent": true,
|
|
||||||
"onBeforeMount": true,
|
|
||||||
"onMounted": true,
|
|
||||||
"onBeforeUnmount": true,
|
|
||||||
"nextTick": true,
|
|
||||||
"ElMessage": true,
|
|
||||||
"$openList": true
|
|
||||||
}
|
|
||||||
}
|
|
22
.github/ISSUE_TEMPLATE/bug-en.yml
vendored
@ -1,22 +0,0 @@
|
|||||||
name: Encountering an Issue
|
|
||||||
description: Please provide details about the issue you are encountering
|
|
||||||
labels: [bug]
|
|
||||||
body:
|
|
||||||
- type: input
|
|
||||||
id: site-url
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
attributes:
|
|
||||||
label: "Site URL"
|
|
||||||
placeholder: "Please provide the URL of the site where the issue occurred"
|
|
||||||
- type: input
|
|
||||||
id: problem
|
|
||||||
attributes:
|
|
||||||
label: "Description of the Issue"
|
|
||||||
description: "Include any error messages or screenshots if applicable"
|
|
||||||
placeholder: "Please describe the issue you are encountering"
|
|
||||||
- type: textarea
|
|
||||||
id: other
|
|
||||||
attributes:
|
|
||||||
label: "Additional Information"
|
|
||||||
description: "Is there anything else you would like to add?"
|
|
22
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -1,22 +0,0 @@
|
|||||||
name: 遇到问题
|
|
||||||
description: 请填写遇到的问题的详细信息
|
|
||||||
labels: [bug]
|
|
||||||
body:
|
|
||||||
- type: input
|
|
||||||
id: site-url
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
attributes:
|
|
||||||
label: "站点链接"
|
|
||||||
placeholder: "请填写你的站点链接"
|
|
||||||
- type: input
|
|
||||||
id: problem
|
|
||||||
attributes:
|
|
||||||
label: "问题描述"
|
|
||||||
description: "有错误的话请提供报错截图"
|
|
||||||
placeholder: "请详细描述一下遇到的问题"
|
|
||||||
- type: textarea
|
|
||||||
id: other
|
|
||||||
attributes:
|
|
||||||
label: "补充信息"
|
|
||||||
description: "还需要说些什么吗"
|
|
14
.github/ISSUE_TEMPLATE/other-en.yml
vendored
@ -1,14 +0,0 @@
|
|||||||
name: Other Information
|
|
||||||
description: Any other issues or questions related to usage
|
|
||||||
labels: [other]
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
id: title
|
|
||||||
attributes:
|
|
||||||
label: "Description of the Issue"
|
|
||||||
description: "Please provide a clear description of the issue you are experiencing"
|
|
||||||
- type: textarea
|
|
||||||
id: other
|
|
||||||
attributes:
|
|
||||||
label: "Additional Information"
|
|
||||||
description: "Is there any other information you would like to add?"
|
|
14
.github/ISSUE_TEMPLATE/other.yml
vendored
@ -1,14 +0,0 @@
|
|||||||
name: 其他信息
|
|
||||||
description: 关于使用上的问题
|
|
||||||
labels: [other]
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
id: title
|
|
||||||
attributes:
|
|
||||||
label: "问题描述"
|
|
||||||
description: "请尽量清晰的描述您遇到的问题"
|
|
||||||
- type: textarea
|
|
||||||
id: other
|
|
||||||
attributes:
|
|
||||||
label: "补充信息"
|
|
||||||
description: "有需要补充的信息吗"
|
|
46
.github/workflows/build.yml
vendored
@ -1,46 +0,0 @@
|
|||||||
# Dev 分支推送部署预览
|
|
||||||
## 仅部署 Win 端
|
|
||||||
name: Build Dev
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Build Website
|
|
||||||
runs-on: windows-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# 检出 Git 仓库
|
|
||||||
- name: Check out git repository
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
# 安装 Node.js
|
|
||||||
- name: Install Node.js
|
|
||||||
uses: actions/setup-node@v4.0.0
|
|
||||||
with:
|
|
||||||
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
|
|
||||||
run: npm install
|
|
||||||
# 构建程序
|
|
||||||
- name: Build Website
|
|
||||||
run: npm run build
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
|
||||||
# 上传构建产物
|
|
||||||
- name: Upload artifacts
|
|
||||||
uses: actions/upload-artifact@v3.1.3
|
|
||||||
with:
|
|
||||||
name: Home
|
|
||||||
path: dist
|
|
25
.gitignore
vendored
@ -1,25 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
*.local
|
|
||||||
.env
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
17
.hintrc
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"development"
|
|
||||||
],
|
|
||||||
"hints": {
|
|
||||||
"compat-api/html": "off",
|
|
||||||
"no-protocol-relative-urls": "off",
|
|
||||||
"compat-api/css": [
|
|
||||||
"default",
|
|
||||||
{
|
|
||||||
"ignore": [
|
|
||||||
"backdrop-filter"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/prettierrc",
|
|
||||||
"singleQuote": false,
|
|
||||||
"trailingComma": "all",
|
|
||||||
"tabWidth": 2,
|
|
||||||
"semi": true,
|
|
||||||
"printWidth": 100
|
|
||||||
}
|
|
3
.vscode/extensions.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["Vue.volar"]
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
# Contributor Covenant Code of Conduct
|
|
||||||
|
|
||||||
## Our Pledge
|
|
||||||
|
|
||||||
We as members, contributors, and leaders pledge to make participation in our
|
|
||||||
community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
||||||
identity and expression, level of experience, education, socio-economic status,
|
|
||||||
nationality, personal appearance, race, religion, or sexual identity
|
|
||||||
and orientation.
|
|
||||||
|
|
||||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
||||||
diverse, inclusive, and healthy community.
|
|
||||||
|
|
||||||
## Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to a positive environment for our
|
|
||||||
community include:
|
|
||||||
|
|
||||||
* Demonstrating empathy and kindness toward other people
|
|
||||||
* Being respectful of differing opinions, viewpoints, and experiences
|
|
||||||
* Giving and gracefully accepting constructive feedback
|
|
||||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
||||||
and learning from the experience
|
|
||||||
* Focusing on what is best not just for us as individuals, but for the
|
|
||||||
overall community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery, and sexual attention or
|
|
||||||
advances of any kind
|
|
||||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or email
|
|
||||||
address, without their explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
|
||||||
|
|
||||||
Community leaders are responsible for clarifying and enforcing our standards of
|
|
||||||
acceptable behavior and will take appropriate and fair corrective action in
|
|
||||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
||||||
or harmful.
|
|
||||||
|
|
||||||
Community leaders have the right and responsibility to remove, edit, or reject
|
|
||||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
||||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
||||||
decisions when appropriate.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies within all community spaces, and also applies when
|
|
||||||
an individual is officially representing the community in public spaces.
|
|
||||||
Examples of representing our community include using an official e-mail address,
|
|
||||||
posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event.
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
||||||
reported to the community leaders responsible for enforcement at
|
|
||||||
one@imsyy.top.
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
|
||||||
reporter of any incident.
|
|
||||||
|
|
||||||
## Enforcement Guidelines
|
|
||||||
|
|
||||||
Community leaders will follow these Community Impact Guidelines in determining
|
|
||||||
the consequences for any action they deem in violation of this Code of Conduct:
|
|
||||||
|
|
||||||
### 1. Correction
|
|
||||||
|
|
||||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
||||||
unprofessional or unwelcome in the community.
|
|
||||||
|
|
||||||
**Consequence**: A private, written warning from community leaders, providing
|
|
||||||
clarity around the nature of the violation and an explanation of why the
|
|
||||||
behavior was inappropriate. A public apology may be requested.
|
|
||||||
|
|
||||||
### 2. Warning
|
|
||||||
|
|
||||||
**Community Impact**: A violation through a single incident or series
|
|
||||||
of actions.
|
|
||||||
|
|
||||||
**Consequence**: A warning with consequences for continued behavior. No
|
|
||||||
interaction with the people involved, including unsolicited interaction with
|
|
||||||
those enforcing the Code of Conduct, for a specified period of time. This
|
|
||||||
includes avoiding interactions in community spaces as well as external channels
|
|
||||||
like social media. Violating these terms may lead to a temporary or
|
|
||||||
permanent ban.
|
|
||||||
|
|
||||||
### 3. Temporary Ban
|
|
||||||
|
|
||||||
**Community Impact**: A serious violation of community standards, including
|
|
||||||
sustained inappropriate behavior.
|
|
||||||
|
|
||||||
**Consequence**: A temporary ban from any sort of interaction or public
|
|
||||||
communication with the community for a specified period of time. No public or
|
|
||||||
private interaction with the people involved, including unsolicited interaction
|
|
||||||
with those enforcing the Code of Conduct, is allowed during this period.
|
|
||||||
Violating these terms may lead to a permanent ban.
|
|
||||||
|
|
||||||
### 4. Permanent Ban
|
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within
|
|
||||||
the community.
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
||||||
version 2.0, available at
|
|
||||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
|
||||||
enforcement ladder](https://github.com/mozilla/diversity).
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
|
||||||
https://www.contributor-covenant.org/faq. Translations are available at
|
|
||||||
https://www.contributor-covenant.org/translations.
|
|
17
Dockerfile
@ -1,17 +0,0 @@
|
|||||||
# 构建应用
|
|
||||||
FROM node:18 AS builder
|
|
||||||
WORKDIR /app
|
|
||||||
COPY package*.json ./
|
|
||||||
RUN npm install
|
|
||||||
COPY . .
|
|
||||||
RUN [ ! -e ".env" ] && cp .env.example .env || true
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# 最小化镜像
|
|
||||||
FROM node:18-alpine
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=builder /app/dist ./dist
|
|
||||||
RUN npm install -g http-server
|
|
||||||
|
|
||||||
EXPOSE 12445
|
|
||||||
CMD ["http-server", "dist", "-p", "12445"]
|
|
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022 imsyy
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
243
README.md
@ -1,244 +1,5 @@
|
|||||||
简体中文 | [English](./README_EN.md)
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<strong><h2>無名の主页 </h2></strong>
|
<strong><h2>無名の主页 </h2></strong>
|
||||||
简单的小主页,原来的看够了,重新弄了一个
|
一个小主页,原来的看够了,重新弄一个
|
||||||
</p>
|
</p>
|
||||||
|
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a> <a title="CDN" target="_blank" href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral"><img src="https://img.shields.io/badge/CDN-%E5%8F%88%E6%8B%8D%E4%BA%91-blue"></a> <a title="beian" target="_blank" href="https://beian.miit.gov.cn/"><img src="https://img.shields.io/badge/%E8%B1%ABICP%E5%A4%87-20013231--2%E5%8F%B7-important"></a> <a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2021-%E7%84%A1%E5%90%8D-red"></a>
|
||||||

|
|
||||||
|
|
||||||
> 主页的 Logo 字体已经过压缩,若用本站 Logo 以外的字母会变回默认字体,这里是 [完整字体](https://file.imsyy.top/font/Other/Pacifico-Regular.ttf),若无法下载,可将字体目录下的 `Pacifico-Regular-all.ttf` 进行替换
|
|
||||||
|
|
||||||
### 👀 Demo
|
|
||||||
|
|
||||||
> 由于 CDN 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存
|
|
||||||
|
|
||||||
- [無名の主页](https://www.imsyy.top)
|
|
||||||
- [無名の主页 - Dev](https://home-imsyy.vercel.app)
|
|
||||||
- [無名の主页 - 备用线路](https://home-5iw.pages.dev)
|
|
||||||
|
|
||||||
### 🎉 功能
|
|
||||||
|
|
||||||
- [x] 载入动画
|
|
||||||
- [x] 站点简介
|
|
||||||
- [x] Hitokoto 一言
|
|
||||||
- [x] 日期及时间
|
|
||||||
- [x] 实时天气
|
|
||||||
- [x] 时光进度条
|
|
||||||
- [x] 音乐播放器
|
|
||||||
- [x] 移动端适配
|
|
||||||
|
|
||||||
### ⚙️ 自动部署
|
|
||||||
|
|
||||||
如果遇到构建环境或者打包过程出现错误,则可以采用 `Github Actions` 来进行自动构建
|
|
||||||
|
|
||||||
- 在成功 `fork` 仓库后,前往 `Actions` 页面,若您是首次开启,则会出现下面的提示,点击开启
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 然后在仓库中进行任意修改后均会触发工作流的运行,在工作流完成后,会在下方生成一个可供下载的压缩包,这就是构建出的静态文件,可自行上传至服务器
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### ⚙️ 手动部署
|
|
||||||
|
|
||||||
- **安装** [node.js](https://nodejs.org/zh-cn/) **环境**
|
|
||||||
|
|
||||||
> node > 16.16.0
|
|
||||||
> npm > 8.15.0
|
|
||||||
|
|
||||||
- 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
|
|
||||||
- 在 `终端` 中输入:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 安装 pnpm
|
|
||||||
npm install -g pnpm
|
|
||||||
|
|
||||||
# 安装依赖
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
# 预览
|
|
||||||
pnpm dev
|
|
||||||
|
|
||||||
# 构建
|
|
||||||
pnpm build
|
|
||||||
```
|
|
||||||
|
|
||||||
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,也可使用 `Vercel` 等托管平台一键导入并自动部署
|
|
||||||
|
|
||||||
### ⚙️ Docker 部署
|
|
||||||
|
|
||||||
> 安装及配置 Docker 将不在此处说明,请自行解决
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 构建
|
|
||||||
docker build -t home .
|
|
||||||
# 运行
|
|
||||||
docker run -p 12445:12445 -d home
|
|
||||||
```
|
|
||||||
|
|
||||||
### ⚙️ Vercel 部署
|
|
||||||
|
|
||||||
> 其他部署平台大致相同,在此不做说明
|
|
||||||
|
|
||||||
1. 点击本仓库右上角的 `Fork`,复制本仓库到你的 `GitHub` 账号
|
|
||||||
2. 复制 `/.env.example` 文件并重命名为 `/.env`( 重要 )
|
|
||||||
3. 按需修改 `/.env` 文件中的配置
|
|
||||||
4. 点击 `Deploy`,即可成功部署
|
|
||||||
|
|
||||||
### 网站链接
|
|
||||||
|
|
||||||
在 `src/assets/siteLinks.json` 中可以自定义网站链接(以指向自己的网站):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"icon": "Blog",
|
|
||||||
"name": "博客",
|
|
||||||
"link": "https://blog.imsyy.top/"
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
其中 `icon` 网站链接的图标可以在 `src/components/Links/index.vue` 中添加:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// 可前往 https://www.xicons.org 自行挑选并在此处引入
|
|
||||||
// 此处引入的是 fa 类型
|
|
||||||
import {
|
|
||||||
Link,
|
|
||||||
Blog,
|
|
||||||
CompactDisc,
|
|
||||||
Cloud,
|
|
||||||
Compass,
|
|
||||||
Book,
|
|
||||||
Fire,
|
|
||||||
LaptopCode,
|
|
||||||
} from "@vicons/fa";
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
// 网站链接图标
|
|
||||||
const siteIcon = {
|
|
||||||
Blog,
|
|
||||||
Cloud,
|
|
||||||
CompactDisc,
|
|
||||||
Compass,
|
|
||||||
Book,
|
|
||||||
Fire,
|
|
||||||
LaptopCode,
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### 社交链接
|
|
||||||
|
|
||||||
在 `src/assets/socialLinks.json` 中可以自定义社交链接。
|
|
||||||
|
|
||||||
### 天气
|
|
||||||
|
|
||||||
天气及地区获取需要 `高德开放平台` 相关 API
|
|
||||||
|
|
||||||
- 前往 [高德开放平台控制台](https://console.amap.com/dev/index) 创建一个 `Web 服务` 类型的 `Key`,并将 `Key` 填入 `.env` 中的 `VITE_WEATHER_KEY` 中
|
|
||||||
|
|
||||||
也可自行更换其他方式
|
|
||||||
|
|
||||||
### 音乐
|
|
||||||
|
|
||||||
> 本项目采用了基于 `MetingJS` 的 `Aplayer` 音乐播放器,可实现快速自定义歌单
|
|
||||||
> \*仅支持 **中国大陆地区**
|
|
||||||
|
|
||||||
请在 `.env` 文件中更改歌曲相关参数即可实现自定义歌单列表
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 歌曲 API 地址
|
|
||||||
VITE_SONG_API = "https://api-meting.imsyy.top"
|
|
||||||
# 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
|
|
||||||
VITE_SONG_SERVER = "netease"
|
|
||||||
# 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
|
||||||
VITE_SONG_TYPE = "playlist"
|
|
||||||
# 播放 ID
|
|
||||||
VITE_SONG_ID = "7452421335"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 字体
|
|
||||||
|
|
||||||
现采用 `HarmonyOS Sans` 开源字体,采用字体拆分,提升加载速度
|
|
||||||
|
|
||||||
> 由于本站 `CDN` 已开启防盗链,**非本站域名不可访问**,请将字体引入链接更改为下方内容,否则 **自定义字体将失效**
|
|
||||||
>
|
|
||||||
> `https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css`
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>旧版方式</summary>
|
|
||||||
|
|
||||||
> 由于本项目引入了中文字体,需要压缩中文字体以提高网页加载速度( 也可以取消使用中文字体 )
|
|
||||||
|
|
||||||
#### 中文字体去除繁体
|
|
||||||
|
|
||||||
- 安装 `Python 3.7` 和 `pip`
|
|
||||||
- 运行 `pip install fonttools`
|
|
||||||
- 下载 [sc_unicode.txt](https://gist.githubusercontent.com/imaegoo/d64e5088b723c2e02c40985f55ff12db/raw/5ebd2ce49418c73459a9dfe050483409306a6c1d/sc_unicode.txt)
|
|
||||||
- 运行 `pyftsubset 字体名称.ttf --unicodes-file=sc_unicode.txt`
|
|
||||||
|
|
||||||
#### 字体进一步压缩
|
|
||||||
|
|
||||||
- 编译安装 `Google woff2`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt-get install -y git g++ make
|
|
||||||
git clone --recursive https://github.com/google/woff2.git
|
|
||||||
cd woff2
|
|
||||||
make clean all
|
|
||||||
```
|
|
||||||
|
|
||||||
- 再压缩字体
|
|
||||||
|
|
||||||
```
|
|
||||||
./woff2_compress ./字体名称.ttf
|
|
||||||
```
|
|
||||||
|
|
||||||
- 最终可对原字体进行缓加载,**先行加载压缩后的字体**
|
|
||||||
|
|
||||||
> 详细信息可前往 [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) 查看原文
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### 网站图标及网站背景
|
|
||||||
|
|
||||||
#### 网站背景
|
|
||||||
|
|
||||||
可以在 `public/images` 中修改网站背景
|
|
||||||
|
|
||||||
如果想要添加更多的本地图片作为网站背景,可以将图片重命名 `background+数字` 的形式,并在 `src/components/Background/index.vue` 中进行修改:
|
|
||||||
|
|
||||||
```js
|
|
||||||
if (type == 0) {
|
|
||||||
// 修改此处 Math.random() 后面的第一个数字为图片的数量
|
|
||||||
bgUrl.value = `/images/background${Math.floor(Math.random() * 10 + 1)}.webp`;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 网站图标
|
|
||||||
|
|
||||||
可以在 `public/images/icon` 中修改网站图标。
|
|
||||||
|
|
||||||
### 技术栈
|
|
||||||
|
|
||||||
- [Vue](https://cn.vuejs.org/)
|
|
||||||
- [Vite](https://vitejs.cn/vite3-cn/)
|
|
||||||
- [Pinia](https://pinia.vuejs.org/zh/)
|
|
||||||
- [IconPark](https://iconpark.oceanengine.com/official)
|
|
||||||
- [xicons](https://xicons.org/)
|
|
||||||
- [Aplayer](https://aplayer.js.org/)
|
|
||||||
|
|
||||||
### API
|
|
||||||
|
|
||||||
- [韩小韩 WebAPI 接口](https://api.vvhan.com/)
|
|
||||||
- [搏天 API](https://api.btstu.cn/doc/sjbz.php)
|
|
||||||
- [教书先生 API](https://api.oioweb.cn/doc/weather/GetWeather)
|
|
||||||
- [高德开放平台](https://lbs.amap.com/)
|
|
||||||
- [Hitokoto 一言](https://hitokoto.cn/)
|
|
||||||
|
|
||||||
## Star History
|
|
||||||
|
|
||||||
[](https://star-history.com/#imsyy/home&Date)
|
|
||||||
|
|
||||||
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a> <a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a> <a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a>
|
|
||||||
|
144
README_EN.md
@ -1,144 +0,0 @@
|
|||||||
English | [Chinese](./README.md)
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong><h2>無名の主页</h2></strong>
|
|
||||||
Simple little homepage, had enough of the original one and made a new one
|
|
||||||
</p>
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
>The logo font on the home page has been compressed, so if you use a font other than this logo, it will change back to the default font, Here is the [full font](https://file.4everland.app/font/Other/Pacifico-Regular.ttf)
|
|
||||||
|
|
||||||
### Demo
|
|
||||||
|
|
||||||
>Due to CDN caching, you may need `Ctrl` + `F5` to force a browser cache refresh to see the latest results
|
|
||||||
|
|
||||||
- [無名の主页](https://www.imsyy.top)
|
|
||||||
- [無名の主页 - Dev](https://home-imsyy.vercel.app)
|
|
||||||
- [無名の主页 - Standby](https://home-5iw.pages.dev)
|
|
||||||
|
|
||||||
### Functions
|
|
||||||
|
|
||||||
- [x] Loading animation
|
|
||||||
- [x] Site description
|
|
||||||
- [x] Hitokoto
|
|
||||||
- [x] Date and time
|
|
||||||
- [x] Live weather
|
|
||||||
- [x] Time progress bar
|
|
||||||
- [x] Music player
|
|
||||||
- [x] Mobile adaptation
|
|
||||||
|
|
||||||
* [ ] Player cancels using Aplayer
|
|
||||||
|
|
||||||
### Deployment
|
|
||||||
|
|
||||||
* **Installation** [node.js](https://nodejs.org/zh-cn/) **Environment**
|
|
||||||
|
|
||||||
> node > 16.16.0
|
|
||||||
> npm > 8.15.0
|
|
||||||
|
|
||||||
* Then run the `cmd` terminal with **administrator privileges** and `cd` to the project root directory
|
|
||||||
* In the `terminal` type:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install pnpm
|
|
||||||
npm install -g pnpm
|
|
||||||
|
|
||||||
# Install the dependencies
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
# Preview
|
|
||||||
pnpm dev
|
|
||||||
|
|
||||||
# Build
|
|
||||||
pnpm build
|
|
||||||
```
|
|
||||||
|
|
||||||
> Once the build is complete, the files in the `dist` folder can be uploaded to the server or imported and automatically deployed with one click using a hosting platform such as `Vercel`.
|
|
||||||
|
|
||||||
### Weather
|
|
||||||
|
|
||||||
Weather and area access requires `高德开放平台` related API
|
|
||||||
|
|
||||||
- Go to [高德开放平台控制台](https://console.amap.com/dev/index) to create a `Key` of type `Web Service` and fill the `Key` into `VITE_WEATHER_KEY` in `.env`
|
|
||||||
|
|
||||||
It can also be replaced by other methods
|
|
||||||
|
|
||||||
### Music
|
|
||||||
|
|
||||||
>This project uses the `Aplayer` music player based on `MetingJS` for quick song list customization
|
|
||||||
>*Only supported in **Mainland China**
|
|
||||||
|
|
||||||
Please change the song related parameters in the `.env` file to customize the song list
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Songs API address
|
|
||||||
VITE_SONG_API = "https://api-meting.imsyy.top"
|
|
||||||
# Song server ( netease-netease, tencent-qq music )
|
|
||||||
VITE_SONG_SERVER = "netease"
|
|
||||||
# Playback type ( song-song, playlist-playlist, album-album, search-search, artist-artist )
|
|
||||||
VITE_SONG_TYPE = "playlist"
|
|
||||||
# Playback ID
|
|
||||||
VITE_SONG_ID = "7452421335"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fonts
|
|
||||||
|
|
||||||
Now using `HarmonyOS Sans` open source font, using font splitting to improve loading speed
|
|
||||||
|
|
||||||
>Because this site's `CDN` has opened anti-leech, **non-site domain name is not accessible**, please change the font import link to the following content, otherwise **custom fonts will be invalid**
|
|
||||||
>
|
|
||||||
>`https://cdn.jsdelivr.net/gh/imsyy/file/font/HarmonyOS_Sans/regular.min.css`
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>old way</summary>
|
|
||||||
|
|
||||||
>As Chinese fonts are introduced in this project, Chinese fonts need to be compressed to improve the loading speed of the page (you can also cancel the use of Chinese fonts)
|
|
||||||
|
|
||||||
#### Chinese font removal traditional
|
|
||||||
|
|
||||||
- Install `Python 3.7` and `pip`
|
|
||||||
- Run `pip install fonttools`
|
|
||||||
- Download [sc_unicode.txt](https://gist.githubusercontent.com/imaegoo/d64e5088b723c2e02c40985f55ff12db/raw/5ebd2ce49418c73459a9dfe050483409306a6c1d/sc_unicode.txt)
|
|
||||||
- Run `pyftsubset font-name.ttf --unicodes-file=sc_unicode.txt`
|
|
||||||
|
|
||||||
#### fonts further compressed
|
|
||||||
|
|
||||||
- Compile and install ``Google woff2``
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt-get install -y git g++ make
|
|
||||||
git clone --recursive https://github.com/google/woff2.git
|
|
||||||
cd woff2
|
|
||||||
make clean all
|
|
||||||
```
|
|
||||||
|
|
||||||
- Compress the font again
|
|
||||||
|
|
||||||
```
|
|
||||||
. /woff2_compress . /font_name.ttf
|
|
||||||
```
|
|
||||||
|
|
||||||
- Eventually the original font can be slow loaded, **load the compressed font first**
|
|
||||||
|
|
||||||
>For more information, please go to [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) to view the original article
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Technology Stack
|
|
||||||
|
|
||||||
* [Vue](https://cn.vuejs.org/)
|
|
||||||
* [Vite](https://vitejs.cn/vite3-cn/)
|
|
||||||
* [Pinia](https://pinia.vuejs.org/zh/)
|
|
||||||
* [IconPark](https://iconpark.oceanengine.com/official)
|
|
||||||
* [xicons](https://xicons.org/)
|
|
||||||
* [Aplayer](https://aplayer.js.org/)
|
|
||||||
|
|
||||||
### API
|
|
||||||
|
|
||||||
* [韩小韩 WebAPI 接口](https://api.vvhan.com/)
|
|
||||||
* [搏天 API](https://api.btstu.cn/doc/sjbz.php)
|
|
||||||
* [高德开放平台](https://lbs.amap.com/)
|
|
||||||
* [Hitokoto 一言](https://hitokoto.cn/)
|
|
||||||
|
|
||||||
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a> <a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a> <a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a>
|
|
57
auto-imports.d.ts
vendored
@ -1,57 +0,0 @@
|
|||||||
// 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
@ -1,35 +0,0 @@
|
|||||||
// 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']
|
|
||||||
}
|
|
||||||
}
|
|
89
css/animation.css
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*模糊渐入动画*/
|
||||||
|
@keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-o-keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
backdrop-filter: blur(0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*渐入动画*/
|
||||||
|
@keyframes fade {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fade {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes fade {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-o-keyframes fade {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
64
css/font.css
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "iconfont";
|
||||||
|
src: url('../font/font_2831425_80aedhvquju.woff2') format('woff2'),
|
||||||
|
url('../font/font_2831425_80aedhvquju.woff') format('woff'),
|
||||||
|
url('../font/font_2831425_80aedhvquju.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Pacifico-Regular";
|
||||||
|
src: url('../font/Pacifico-Regular.ttf');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "UnidreamLED";
|
||||||
|
src: url('../font/UnidreamLED.ttf');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-youxiang:before {
|
||||||
|
content: "\e605";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-github:before {
|
||||||
|
content: "\e691";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-telegram1:before {
|
||||||
|
content: "\e731";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-QQ:before {
|
||||||
|
content: "\e882";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-twitter:before {
|
||||||
|
content: "\e883";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-github1:before {
|
||||||
|
content: "\e799";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-weixin:before {
|
||||||
|
content: "\e600";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-telegram:before {
|
||||||
|
content: "\e8db";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-yinhao-copy:before {
|
||||||
|
content: "\e608";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-yinhao-copy-copy:before {
|
||||||
|
content: "\e62e";
|
||||||
|
}
|
125
css/loading.css
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#loading-box .loading-left-bg,
|
||||||
|
#loading-box .loading-right-bg {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 999998;
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgb(81 81 81 / 80%);
|
||||||
|
transition: all 0.7s cubic-bezier(0.42, 0, 0, 1.01);
|
||||||
|
backdrop-filter: blur(40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading-box .loading-right-bg {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading-box>.spinner-box {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 999999;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading-box .spinner-box .loading-word {
|
||||||
|
position: absolute;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
transform: translateY(64px);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.loading-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
margin: 20px 10px 4px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading-box .spinner-box .configure-core {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #37474f;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.loaded div.loading-left-bg {
|
||||||
|
transform: translate(-100%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.loaded div.loading-right-bg {
|
||||||
|
transform: translate(100%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.loaded div.spinner-box {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 32px);
|
||||||
|
left: calc(50% - 32px);
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 50%;
|
||||||
|
perspective: 800px;
|
||||||
|
transition: all 0.7s cubic-bezier(0.42, 0, 0, 1.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner.one {
|
||||||
|
left: 0%;
|
||||||
|
top: 0%;
|
||||||
|
animation: rotate-one 1s linear infinite;
|
||||||
|
border-bottom: 3px solid #EFEFFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner.two {
|
||||||
|
right: 0%;
|
||||||
|
top: 0%;
|
||||||
|
animation: rotate-two 1s linear infinite;
|
||||||
|
border-right: 3px solid #EFEFFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner.three {
|
||||||
|
right: 0%;
|
||||||
|
bottom: 0%;
|
||||||
|
animation: rotate-three 1s linear infinite;
|
||||||
|
border-top: 3px solid #EFEFFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate-one {
|
||||||
|
0% {
|
||||||
|
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate-two {
|
||||||
|
0% {
|
||||||
|
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate-three {
|
||||||
|
0% {
|
||||||
|
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
232
css/mobile.css
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
@charset"utf-8";
|
||||||
|
|
||||||
|
/*小于1400px时*/
|
||||||
|
@media (max-width: 1400px) {
|
||||||
|
|
||||||
|
/*时钟显示*/
|
||||||
|
span#win_text,
|
||||||
|
span#win_speed {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小于1200px时*/
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
|
||||||
|
/*总布局*/
|
||||||
|
.container,
|
||||||
|
.container-lg,
|
||||||
|
.container-md,
|
||||||
|
.container-sm {
|
||||||
|
max-width: 1100px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*天气模块*/
|
||||||
|
.weather {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weekday {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小于992px时*/
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
|
||||||
|
/*简介不可点击*/
|
||||||
|
.message {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*一言*/
|
||||||
|
.col.hitokotos {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*日期显示*/
|
||||||
|
.weekday {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*标题文字*/
|
||||||
|
.main-img img {
|
||||||
|
width: 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.img-title {
|
||||||
|
font-size: 4.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.img-text {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小于789px时*/
|
||||||
|
@media (max-width: 789px) {
|
||||||
|
|
||||||
|
/*标题文字*/
|
||||||
|
span.img-text {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小于768px时*/
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
|
/*标题文字*/
|
||||||
|
.main-img img {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.img-title {
|
||||||
|
font-size: 4.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小于660px时*/
|
||||||
|
@media (max-width: 660px) {
|
||||||
|
|
||||||
|
/*左侧栏高度*/
|
||||||
|
.main-left {
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*右侧栏隐藏*/
|
||||||
|
.col.right {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*标题文字*/
|
||||||
|
span.img-text {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*简介*/
|
||||||
|
.message {
|
||||||
|
max-width: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.des {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*社交链接*/
|
||||||
|
.social {
|
||||||
|
max-width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-text {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link i {
|
||||||
|
margin: 0px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*菜单栏按钮*/
|
||||||
|
.menu {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
position: fixed;
|
||||||
|
top: 84%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.munu-button {
|
||||||
|
padding: 5px 20px;
|
||||||
|
background: rgb(0 0 0 / 20%);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
transition: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*页脚文字*/
|
||||||
|
footer {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 660px) {
|
||||||
|
.menu {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小于390px时*/
|
||||||
|
@media (max-width: 390px) {
|
||||||
|
.main-img img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
菜单按钮
|
||||||
|
*/
|
||||||
|
.menus .col.left {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menus .col.right {
|
||||||
|
display: block !important;
|
||||||
|
transition: 0.5s;
|
||||||
|
padding: 0rem 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*功能区调整*/
|
||||||
|
.menus .col.hitokotos {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menus .col.times {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*边界布局*/
|
||||||
|
.menus .row {
|
||||||
|
--bs-gutter-x: 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menus .col.\32 {
|
||||||
|
margin: 0 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menus .logo {
|
||||||
|
display: inline !important;
|
||||||
|
position: fixed;
|
||||||
|
top: 8%;
|
||||||
|
font-family: 'Pacifico-Regular';
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*切换动画*/
|
||||||
|
.hitokoto,
|
||||||
|
.time,
|
||||||
|
.link-card,
|
||||||
|
.message {
|
||||||
|
animation: fade-in;
|
||||||
|
-webkit-animation: fade-in 0.5s;
|
||||||
|
-moz-animation: fade-in 0.5s;
|
||||||
|
-o-animation: fade-in 0.5s;
|
||||||
|
-ms-animation: fade-in 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo,
|
||||||
|
.line,
|
||||||
|
.main-img,
|
||||||
|
.social,
|
||||||
|
.close,
|
||||||
|
#link-text {
|
||||||
|
animation: fade 0.5;
|
||||||
|
-webkit-animation: fade 0.5s;
|
||||||
|
-moz-animation: fade 0.5s;
|
||||||
|
-o-animation: fade 0.5s;
|
||||||
|
-ms-animation: fade 0.5s;
|
||||||
|
}
|
386
css/style.css
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
@charset"utf-8";
|
||||||
|
|
||||||
|
/*全局样式*/
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
a,
|
||||||
|
p {
|
||||||
|
text-decoration: none;
|
||||||
|
transition: 0.3s;
|
||||||
|
color: #efefef;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards {
|
||||||
|
transition: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards:hover {
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
transition: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*页面样式*/
|
||||||
|
section {
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgb(0 0 0 / 20%);
|
||||||
|
display: flex;
|
||||||
|
/*align-items: center;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-left {
|
||||||
|
/*transform: translateY(240px);*/
|
||||||
|
transform: translateY(40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.main-right {
|
||||||
|
transform: translateY(38%);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
.row.rightone {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*头像*/
|
||||||
|
.main-img {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-img img {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-title {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 12px;
|
||||||
|
font-family: Pacifico-Regular;
|
||||||
|
transform: translateY(-8%);
|
||||||
|
}
|
||||||
|
|
||||||
|
span.img-title {
|
||||||
|
font-size: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.img-text {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*简介*/
|
||||||
|
.message {
|
||||||
|
background: rgb(0 0 0 / 25%);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
/*margin: 0.5rem;*/
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-top: 3.5rem;
|
||||||
|
max-width: 460px;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.des {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.des-title {
|
||||||
|
margin: 1rem 1rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
font-family: Pacifico-Regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.iconfont.icon-yinhao-copy {
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*社交链接*/
|
||||||
|
.social {
|
||||||
|
margin-top: 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 460px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link i {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
margin: 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-text {
|
||||||
|
display: none;
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*一言*/
|
||||||
|
.hitokoto {
|
||||||
|
width: 100%;
|
||||||
|
background: rgb(0 0 0 / 25%);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hitokoto-all {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hitokoto-from {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*时间卡片*/
|
||||||
|
.time {
|
||||||
|
width: 100%;
|
||||||
|
background: rgb(0 0 0 / 25%);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.time-text {
|
||||||
|
font-size: 3.25rem;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
font-family: UnidreamLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*链接卡片*/
|
||||||
|
.line {
|
||||||
|
margin: 1rem 0.25rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-size: 1.10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-card {
|
||||||
|
height: 100px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgb(0 0 0 / 25%);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-card:hover {
|
||||||
|
background: rgb(0 0 0 / 40%);
|
||||||
|
transition: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*更多页面*/
|
||||||
|
.more {
|
||||||
|
display: none !important;
|
||||||
|
width: 46%;
|
||||||
|
z-index: 999;
|
||||||
|
position: fixed;
|
||||||
|
height: 82%;
|
||||||
|
right: 4%;
|
||||||
|
background: rgb(0 0 0 / 25%);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
top: 7%;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mores .more {
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
animation: fade;
|
||||||
|
-webkit-animation: fade 0.3s;
|
||||||
|
-moz-animation: fade 0.3s;
|
||||||
|
-o-animation: fade 0.3s;
|
||||||
|
-ms-animation: fade 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mores .col.right {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*关闭按钮*/
|
||||||
|
|
||||||
|
.close {
|
||||||
|
display: none;
|
||||||
|
left: auto;
|
||||||
|
top: 4px;
|
||||||
|
right: 8px;
|
||||||
|
font-size: 1.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*进度条*/
|
||||||
|
.progress {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
align-items: center;
|
||||||
|
background: rgb(255 255 255 / 25%) !important;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
font-family: 'UnidreamLED';
|
||||||
|
background-color: #efefef !important;
|
||||||
|
color: rgb(86 77 89) !important;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*时间胶囊*/
|
||||||
|
|
||||||
|
.date {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-text {
|
||||||
|
margin: 1rem 0rem 0.5rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*更多页面链接*/
|
||||||
|
|
||||||
|
.mores .link-card {
|
||||||
|
height: 48px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*box*/
|
||||||
|
|
||||||
|
.box {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1996;
|
||||||
|
background-color: rgba(0, 0, 0, .5);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
animation: fade 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
-webkit-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 1997;
|
||||||
|
width: 80%;
|
||||||
|
height: 80%;
|
||||||
|
background: rgb(255 255 255 / 40%);
|
||||||
|
border-radius: 6px;
|
||||||
|
-webkit-animation: fade .3s;
|
||||||
|
animation: fade .3s;
|
||||||
|
padding: 40px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upnote {
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-left: 2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closebox {
|
||||||
|
left: auto;
|
||||||
|
top: 4px;
|
||||||
|
right: 8px;
|
||||||
|
font-size: 1.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closebox:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*页脚样式*/
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
height: 46px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background: rgb(0 0 0 / 25%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.power {
|
||||||
|
line-height: 46px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*弹窗样式*/
|
||||||
|
.iziToast {
|
||||||
|
background: rgb(0 0 0 / 45%) !important;
|
||||||
|
backdrop-filter: blur(10px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iziToast-body .iziToast-message {
|
||||||
|
line-height: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iziToast:after {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iziToast-message.slideIn {
|
||||||
|
margin-top: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iziToast-message {
|
||||||
|
word-break: break-all !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iziToast>.iziToast-close {
|
||||||
|
background: url(https://cdn.jsdelivr.net/gh/imsyy/file/pic/close.png) no-repeat 50% 50% !important;
|
||||||
|
background-size: 8px !important;
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
ports:
|
|
||||||
- "12445:12445"
|
|
BIN
favicon.ico
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
font/font_2831425_80aedhvquju.ttf
Normal file
BIN
font/font_2831425_80aedhvquju.woff
Normal file
BIN
font/font_2831425_80aedhvquju.woff2
Normal file
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
img/background.png
Normal file
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
img/weixin.png
Normal file
After Width: | Height: | Size: 39 KiB |
349
index.html
@ -1,39 +1,328 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<!-- 基础信息 -->
|
||||||
<meta http-equiv="Access-Control-Allow-Origin" content="*" />
|
<meta charset="utf-8">
|
||||||
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> -->
|
<meta http-equiv="Access-Control-Allow-Origin" content="*">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="renderer" content="webkit" />
|
||||||
<link rel="icon" href="%VITE_SITE_LOGO%" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<link rel="apple-touch-icon" href="%VITE_SITE_APPLE_LOGO%" />
|
<meta name="force-rendering" content="webkit" />
|
||||||
<link rel="bookmark" href="%VITE_SITE_APPLE_LOGO%" />
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="apple-touch-icon-precomposed" sizes="200x200" href="%VITE_SITE_APPLE_LOGO%" />
|
<meta name="description" content="無名の主页">
|
||||||
<meta name="description" content="%VITE_SITE_DES%" />
|
<meta name="keywords" content="無名,个人主页">
|
||||||
<meta name="keywords" content="%VITE_SITE_KEYWORDS%" />
|
<meta name="author" content="無名">
|
||||||
<meta name="author" content="%VITE_SITE_ANTHOR%" />
|
<title>無名の主页</title>
|
||||||
<meta name="theme-color" content="#424242" />
|
<!-- 引入样式 -->
|
||||||
<title>%VITE_SITE_NAME%</title>
|
<link rel="stylesheet" type="text/css"
|
||||||
<!-- HarmonyOS Sans -->
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css">
|
||||||
<!-- 本站 CDN 已开启防盗链,非本站域名不可访问,请更改链接为下方内容,否则自定义字体将失效 -->
|
<link rel="stylesheet" type="text/css" href="./css/style.css">
|
||||||
<link rel="stylesheet" href="https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css" />
|
<link rel="stylesheet" type="text/css" href="./css/mobile.css">
|
||||||
<!-- <link rel="stylesheet" href="https://cdn.imsyy.top/gh/imsyy/file/font/HarmonyOS_Sans/regular.min.css" /> -->
|
<link rel="stylesheet" type="text/css" href="./css/font.css">
|
||||||
<!-- IE Out -->
|
<link rel="stylesheet" type="text/css" href="./css/loading.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="./css/animation.css">
|
||||||
|
<link rel="icon" href="./favicon.ico">
|
||||||
|
<link rel="apple-touch-icon" href="./img/apple-touch-icon.png">
|
||||||
|
<!-- 引入 Izitoast -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/izitoast@1.4.0/dist/css/iziToast.min.css">
|
||||||
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/izitoast@1.4.0/dist/js/iziToast.min.js"></script>
|
||||||
|
<!-- 引入 Fontawesome -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-fontawesome-pro@master/css/all.min.css"
|
||||||
|
media="all">
|
||||||
|
<!--引入 Vue-->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
|
||||||
|
<!-- 引入 jQuery -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
|
||||||
|
<!-- 百度统计 -->
|
||||||
<script>
|
<script>
|
||||||
if (/*@cc_on!@*/ false || (!!window.MSInputMethodContext && !!document.documentMode))
|
var _hmt = _hmt || [];
|
||||||
window.location.href =
|
(function () {
|
||||||
'https://support.dmeng.net/upgrade-your-browser.html?referrer=' +
|
var hm = document.createElement("script");
|
||||||
encodeURIComponent(window.location.href);
|
hm.src = "https://hm.baidu.com/hm.js?14e9f35ff8bc67fd4bcb5f07a6e6655a";
|
||||||
|
var s = document.getElementsByTagName("script")[0];
|
||||||
|
s.parentNode.insertBefore(hm, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- IE 淘汰计划 -->
|
||||||
|
<script>
|
||||||
|
if ( /*@cc_on!@*/ false || (!!window.MSInputMethodContext && !!document.documentMode)) window.location.href =
|
||||||
|
"/upgrade-your-browser/index.html?referrer=" + encodeURIComponent(window.location.href);
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- 主体内容 -->
|
<!--加载动画-->
|
||||||
<div id="app"></div>
|
<div id="loading-box">
|
||||||
<!-- noscript -->
|
<div class="loading-left-bg"></div>
|
||||||
<noscript>
|
<div class="loading-right-bg"></div>
|
||||||
<div style="text-align: center">请开启 JavaScript</div>
|
<div class="spinner-box">
|
||||||
</noscript>
|
<div class="loader">
|
||||||
<script type="module" src="/src/main.js"></script>
|
<div class="inner one"></div>
|
||||||
|
<div class="inner two"></div>
|
||||||
|
<div class="inner three"></div>
|
||||||
|
</div>
|
||||||
|
<div class="loading-word">
|
||||||
|
<p class="loading-title">無名の主页</p>加载中
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--加载动画结束-->
|
||||||
|
<section id="section" class="section">
|
||||||
|
<main id="main" class="main">
|
||||||
|
<div class="container" id="container">
|
||||||
|
<div class="row" id="row">
|
||||||
|
<div class="col left">
|
||||||
|
<!--基本信息-->
|
||||||
|
<div class="main-left">
|
||||||
|
<!--Logo-->
|
||||||
|
<div class="main-img">
|
||||||
|
<img src="./img/logo.png" alt="img">
|
||||||
|
<div class="img-title">
|
||||||
|
<span class="img-title">imsyy</span>
|
||||||
|
<span class="img-text">.top</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--介绍信息-->
|
||||||
|
<div class="message cards" onclick="switchMore()">
|
||||||
|
<div class="des" id="des"><i class="iconfont icon-yinhao-copy-copy"></i>
|
||||||
|
<p class="des-title"><span id="change">Hello World !</span><br /><span
|
||||||
|
id="change1">一个建立于 21 世纪的小站,存活于互联网的边缘</span></p>
|
||||||
|
<i class="iconfont icon-yinhao-copy"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--社交链接-->
|
||||||
|
<div class="social" id="social">
|
||||||
|
<a href="https://github.com/imsyy" class="link" id="github" target="_blank">
|
||||||
|
<i class="iconfont icon-github"></i>
|
||||||
|
</a>
|
||||||
|
<a href="http://wpa.qq.com/msgrd?v=3&uin=1539250352&site=qq&menu=yes" class="link"
|
||||||
|
id="qq" target="_blank">
|
||||||
|
<i class="iconfont icon-QQ"></i>
|
||||||
|
</a>
|
||||||
|
<a href="mailto:one@imsyy.top" class="link" id="email">
|
||||||
|
<i class="iconfont icon-youxiang"></i>
|
||||||
|
</a>
|
||||||
|
<a href="https://t.me/bottom_user" class="link" id="telegram" target="_blank">
|
||||||
|
<i class="iconfont icon-telegram"></i>
|
||||||
|
</a>
|
||||||
|
<a href="https://twitter.com/iimmsyy" class="link" id="twitter" target="_blank">
|
||||||
|
<i class="iconfont icon-twitter"></i>
|
||||||
|
</a>
|
||||||
|
<a id="link-text">通过这里联系我</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col right">
|
||||||
|
<div class="main-right">
|
||||||
|
<!--功能区-->
|
||||||
|
<div class="row rightone">
|
||||||
|
<div class="col hitokotos">
|
||||||
|
<!--一言-->
|
||||||
|
<div class="hitokoto cards" id="hitokoto">
|
||||||
|
<div class="hitokoto-ico"><i class="fad fa-comment-alt-lines"></i> 一言</div>
|
||||||
|
<div class="hitokoto-all">
|
||||||
|
<div class="hitokoto-text"><span id="hitokoto_text">每一个人都应该明确自己的方向和位置</span>
|
||||||
|
</div>
|
||||||
|
<div class="hitokoto-from">-「 <span id="from_text">無名</span> 」
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col times">
|
||||||
|
<!--时间-->
|
||||||
|
<div class="time cards">
|
||||||
|
<div class="timeshow" id="time"></div>
|
||||||
|
<div class="weather">
|
||||||
|
<span id="city_text">天气</span> <span
|
||||||
|
id="wea_text">加载失败</span> <span id="tem_night">*</span>°C~<span
|
||||||
|
id="tem_day">*</span>°C <span id="win_text">风向</span><span
|
||||||
|
id="win_speed">*</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--分隔线-->
|
||||||
|
<div class="line">
|
||||||
|
<i class="fad fa-grip-lines-vertical"></i>
|
||||||
|
<span class="line-text">网站列表</span>
|
||||||
|
</div>
|
||||||
|
<!--网站链接-->
|
||||||
|
<div class="link">
|
||||||
|
<!--第一组-->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://blog.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<i class="fad fa-blog"></i>
|
||||||
|
<span class="link-name">博客</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col 2">
|
||||||
|
<a href="https://web.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<i class="fad fa-spider-web"></i>
|
||||||
|
<span class="link-name">网址导航</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://music.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<i class="fad fa-list-music"></i>
|
||||||
|
<span class="link-name">音乐</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--第二组-->
|
||||||
|
<div class="row" style="margin-top: 1.5rem;">
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://lab.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<i class="fad fa-flask"></i>
|
||||||
|
<span class="link-name">实验室</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col 2">
|
||||||
|
<a href="https://share.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<i class="fad fa-cloud-download"></i>
|
||||||
|
<span class="link-name">网盘</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://blog.imsyy.top/about/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<i class="fad fa-info-circle"></i>
|
||||||
|
<span class="link-name">关于</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--展开菜单按钮-->
|
||||||
|
<div class="menu">
|
||||||
|
<a class="munu-button cards" id="menu" onclick="switchMenu()"><i class="fad fa-bars"></i></a>
|
||||||
|
</div>
|
||||||
|
<!--第二屏 Logo-->
|
||||||
|
<div class="logo" style="display: none">
|
||||||
|
<a>imsyy.top</a>
|
||||||
|
</div>
|
||||||
|
<!--更多内容-->
|
||||||
|
<div class="more cards" id="more">
|
||||||
|
<!--关闭按钮-->
|
||||||
|
<div class="close fixed-top" onclick="switchMore()" id="close"><i class="fad fa-times-circle"></i>
|
||||||
|
</div>
|
||||||
|
<div class="line" style="margin-top: 1rem;">
|
||||||
|
<i class="fad fa-grip-lines-vertical"></i>
|
||||||
|
<span class="line-text">时间胶囊</span>
|
||||||
|
<i class="fad fa-grip-lines-vertical"></i>
|
||||||
|
</div>
|
||||||
|
<div class="date" id="date">
|
||||||
|
<p class="date-text" style="margin-top: 0rem;">今日已经度过了大约 {{hour}} 小时</p>
|
||||||
|
<div v-html="jinduT()" class="marginbottom"></div>
|
||||||
|
<p class="date-text">本周已经度过了 {{week}} 天,今天是第 {{curweek}} 天</p>
|
||||||
|
<div v-html="jinduZ()" class="marginbottom"></div>
|
||||||
|
<p class="date-text">本月已经度过了 {{day}} 天,今天是第 {{curday}} 天</p>
|
||||||
|
<div v-html="jinduD()" class="marginbottom"></div>
|
||||||
|
<p class="date-text">{{year}} 年已经度过了 {{month}} 个月,度过了 {{outday}} 天</p>
|
||||||
|
<div v-html="jinduY()" class="marginbottom"></div>
|
||||||
|
</div>
|
||||||
|
<div class="line">
|
||||||
|
<i class="fad fa-grip-lines-vertical"></i>
|
||||||
|
<span class="line-text">杂七杂八</span>
|
||||||
|
<i class="fad fa-grip-lines-vertical"></i>
|
||||||
|
</div>
|
||||||
|
<!--网站链接-->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://status.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<span class="link-name">站点监测</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col 2">
|
||||||
|
<a href="https://player.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<span class="link-name">播放器</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://write.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<span class="link-name">Markdown</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-top: 1.5rem;">
|
||||||
|
<div class="col">
|
||||||
|
<a href="https://img.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<span class="link-name">图片站</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col 2">
|
||||||
|
<a href="https://file.imsyy.top/" target="_blank">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<span class="link-name">文件库</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<a onclick="openBox()">
|
||||||
|
<div class="link-card cards">
|
||||||
|
<span class="link-name">更多</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--更多页面-->
|
||||||
|
<div class="box" id="box" style="display: none">
|
||||||
|
<div class="box-wrapper">
|
||||||
|
<!--关闭按钮-->
|
||||||
|
<div class="closebox fixed-top" onclick="closeBox()">
|
||||||
|
<i class="fad fa-times-circle"></i>
|
||||||
|
</div>
|
||||||
|
<!--更新日志-->
|
||||||
|
<div class="img-title">
|
||||||
|
<span class="img-title">imsyy</span>
|
||||||
|
<span class="img-text">.top</span>
|
||||||
|
<span class="img-text"> v 1.2</span>
|
||||||
|
</div>
|
||||||
|
<div class="upnote">
|
||||||
|
<span class="uptext"><i class="fad fa-plus-circle"></i> 点击左侧简介可弹出隐藏页面</span>
|
||||||
|
<span class="uptext"><i class="fad fa-plus-circle"></i> 新增时间胶囊( 时光进度条 )</span>
|
||||||
|
<span class="uptext"><i class="fad fa-plus-circle"></i> 隐藏页面新增更多页面弹窗</span>
|
||||||
|
<span class="uptext"><i class="fad fa-wrench"></i> 星期进度条显示错误</span>
|
||||||
|
<span class="uptext"><i class="fad fa-wrench"></i> 移动端动画及细节</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer id="footer" class="fixed-bottom footer">
|
||||||
|
<div class="power">Copyright © 2020
|
||||||
|
<script>
|
||||||
|
document.write(' - ' + (new Date()).getFullYear())
|
||||||
|
</script> 無名 | <a href="https://beian.miit.gov.cn/" target="_blank">豫ICP备20013231-2号</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</section>
|
||||||
|
<!-- JS -->
|
||||||
|
<script type="text/javascript" src="./js/main.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/time.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
287
js/main.js
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
//弹窗样式
|
||||||
|
iziToast.settings({
|
||||||
|
timeout: 10000,
|
||||||
|
icon: 'Fontawesome',
|
||||||
|
closeOnEscape: 'true',
|
||||||
|
position: 'topLeft',
|
||||||
|
transitionIn: 'bounceInRight',
|
||||||
|
transitionOut: 'fadeOutLeft',
|
||||||
|
displayMode: 'replace',
|
||||||
|
layout: '2',
|
||||||
|
titleColor: '#efefef',
|
||||||
|
messageColor: '#efefef',
|
||||||
|
iconColor: '#efefef',
|
||||||
|
});
|
||||||
|
|
||||||
|
iziToast.info({
|
||||||
|
icon: 'fad fa-vial',
|
||||||
|
title: '新版站点试运行',
|
||||||
|
message: '还存在亿些小问题 ~ <a href="./old/" style="color:#efefef">返回旧版</a>'
|
||||||
|
});
|
||||||
|
|
||||||
|
//控制台输出
|
||||||
|
/*
|
||||||
|
let date = '2021-09-27 21:32'
|
||||||
|
let a = 'background: #606060; color: #fff; border-radius: 3px 0 0 3px;'
|
||||||
|
let b = 'background: #1475B2; color: #fff; border-radius: 0 3px 3px 0;'
|
||||||
|
console.log(`%c Update Time %c ${date} `, a, b)
|
||||||
|
*/
|
||||||
|
/* 样式代码 */
|
||||||
|
var styleTitle1 = `
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: rgb(244,167,89);
|
||||||
|
`
|
||||||
|
var styleTitle2 = `
|
||||||
|
font-style: oblique;
|
||||||
|
font-size:14px;
|
||||||
|
color: rgb(244,167,89);
|
||||||
|
font-weight: 400;
|
||||||
|
`
|
||||||
|
var styleContent = `
|
||||||
|
color: rgb(30,152,255);
|
||||||
|
`
|
||||||
|
|
||||||
|
/* 内容代码 */
|
||||||
|
var title1 = '無名の主页'
|
||||||
|
var title2 = 'imsyy.top'
|
||||||
|
var content = `
|
||||||
|
版 本 号:1.2.0
|
||||||
|
更新日期:2021-09-27 19:39:21
|
||||||
|
|
||||||
|
更新说明:
|
||||||
|
1. 新增 点击左侧简介弹出更多页面
|
||||||
|
2. 新增 时间胶囊 ( 时光进度条 )
|
||||||
|
3. 优化 移动端动画及细节
|
||||||
|
4. 修复 星期进度条显示错误
|
||||||
|
|
||||||
|
主页: https://imsyy.top
|
||||||
|
Github: https://github.com/imsyy/home
|
||||||
|
`
|
||||||
|
console.log(`%c${title1} %c${title2}
|
||||||
|
%c${content}`, styleTitle1, styleTitle2, styleContent)
|
||||||
|
|
||||||
|
//获取一言
|
||||||
|
fetch('https://v1.hitokoto.cn')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const hitokoto = document.getElementById('hitokoto_text')
|
||||||
|
const from = document.getElementById('from_text')
|
||||||
|
hitokoto.innerText = data.hitokoto
|
||||||
|
from.innerText = data.from
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
|
||||||
|
//获取天气
|
||||||
|
fetch('https://www.tianqiapi.com/free/day?appid=43986679&appsecret=TksqGZT7')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const wea = document.getElementById('wea_text')
|
||||||
|
const city = document.getElementById('city_text')
|
||||||
|
const tem_night = document.getElementById('tem_night')
|
||||||
|
const tem_day = document.getElementById('tem_day')
|
||||||
|
const win = document.getElementById('win_text')
|
||||||
|
const win_speed = document.getElementById('win_speed')
|
||||||
|
wea.innerText = data.wea
|
||||||
|
city.innerText = data.city
|
||||||
|
tem_night.innerText = data.tem_night
|
||||||
|
tem_day.innerText = data.tem_day
|
||||||
|
win.innerText = data.win
|
||||||
|
win_speed.innerText = data.win_speed
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
|
||||||
|
//获取时间
|
||||||
|
var t = null;
|
||||||
|
t = setTimeout(time, 1000);
|
||||||
|
|
||||||
|
function time() {
|
||||||
|
clearTimeout(t);
|
||||||
|
dt = new Date();
|
||||||
|
var y = dt.getYear() + 1900;
|
||||||
|
var mm = dt.getMonth() + 1;
|
||||||
|
var d = dt.getDate();
|
||||||
|
var weekday = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
|
||||||
|
var day = dt.getDay();
|
||||||
|
var h = dt.getHours();
|
||||||
|
var m = dt.getMinutes();
|
||||||
|
var s = dt.getSeconds();
|
||||||
|
if (h < 10) {
|
||||||
|
h = "0" + h;
|
||||||
|
}
|
||||||
|
if (m < 10) {
|
||||||
|
m = "0" + m;
|
||||||
|
}
|
||||||
|
if (s < 10) {
|
||||||
|
s = "0" + s;
|
||||||
|
}
|
||||||
|
document.getElementById("time").innerHTML = y + " 年 " + mm + " 月 " + d + " 日 " + "<span class='weekday'>" + weekday[day] + "</span><br>" + "<span class='time-text'>" + h + ":" + m + ":" + s + "</span>";
|
||||||
|
t = setTimeout(time, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//必应壁纸
|
||||||
|
var url = 'https://bird.ioliu.cn/v1/?url=https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=8';
|
||||||
|
var imgUrls = JSON.parse(sessionStorage.getItem("imgUrls"));
|
||||||
|
var index = sessionStorage.getItem("index");
|
||||||
|
var $section = $('#section');
|
||||||
|
if (imgUrls == null) {
|
||||||
|
imgUrls = new Array();
|
||||||
|
index = 0;
|
||||||
|
$.get(url, function (result) {
|
||||||
|
images = result.images;
|
||||||
|
for (let i = 0; i < images.length; i++) {
|
||||||
|
const item = images[i];
|
||||||
|
imgUrls.push(item.url);
|
||||||
|
}
|
||||||
|
var imgUrl = imgUrls[index];
|
||||||
|
var url = "https://www.bing.com" + imgUrl;
|
||||||
|
$section.css("background", "url('" + url + "') center center no-repeat #666");
|
||||||
|
$section.css("background-size", "cover");
|
||||||
|
sessionStorage.setItem("imgUrls", JSON.stringify(imgUrls));
|
||||||
|
sessionStorage.setItem("index", index);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (index == 7)
|
||||||
|
index = 0;
|
||||||
|
else
|
||||||
|
index++;
|
||||||
|
var imgUrl = imgUrls[index];
|
||||||
|
var url = "https://www.bing.com" + imgUrl;
|
||||||
|
$section.css("background", "url('" + url + "') center center no-repeat #666");
|
||||||
|
$section.css("background-size", "cover");
|
||||||
|
sessionStorage.setItem("index", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
//加载动画
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
document.body.style.overflow = 'auto';
|
||||||
|
document.getElementById('loading-box').classList.add("loaded")
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
//链接提示文字
|
||||||
|
window.onload = function () {
|
||||||
|
var link = document.getElementById("social");
|
||||||
|
link.onmouseover = function () {
|
||||||
|
document.getElementById("social").style.cssText = "background: rgb(0 0 0 / 25%);backdrop-filter: blur(5px);border-radius: 6px;transition: all 0.5s";
|
||||||
|
document.getElementById("link-text").style.cssText = "display: block;transition: all 0.5s";
|
||||||
|
};
|
||||||
|
link.onmouseout = function () {
|
||||||
|
document.getElementById("social").style.cssText = "background: none;backdrop-filter: none;border-radius: 6px;transition: all 0.5s";
|
||||||
|
document.getElementById("link-text").style.cssText = "display: none;transition: all 0.5s";
|
||||||
|
}
|
||||||
|
|
||||||
|
var link = document.getElementById("github");
|
||||||
|
link.onmouseover = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "去 Github 看看";
|
||||||
|
};
|
||||||
|
link.onmouseout = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "通过这里联系我";
|
||||||
|
}
|
||||||
|
var link1 = document.getElementById("qq");
|
||||||
|
link1.onmouseover = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "有什么事吗";
|
||||||
|
};
|
||||||
|
link1.onmouseout = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "通过这里联系我";
|
||||||
|
}
|
||||||
|
var link2 = document.getElementById("email");
|
||||||
|
link2.onmouseover = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "来封 Email";
|
||||||
|
};
|
||||||
|
link2.onmouseout = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "通过这里联系我";
|
||||||
|
}
|
||||||
|
var link3 = document.getElementById("telegram");
|
||||||
|
link3.onmouseover = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "你懂的 ~";
|
||||||
|
};
|
||||||
|
link3.onmouseout = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "通过这里联系我";
|
||||||
|
}
|
||||||
|
var link4 = document.getElementById("twitter");
|
||||||
|
link4.onmouseover = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "你懂的 ~";
|
||||||
|
};
|
||||||
|
link4.onmouseout = function () {
|
||||||
|
document.getElementById("link-text").innerHTML = "通过这里联系我";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//菜单栏切换
|
||||||
|
function switchMenu() {
|
||||||
|
var menu = document.cookie.replace(/(?:(?:^|.*;\s*)menu\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0';
|
||||||
|
if (menu == '0') {
|
||||||
|
document.getElementById("container").classList.add('menus');
|
||||||
|
document.getElementById("menu").innerHTML = "<i class='fad fa-times'></i>";
|
||||||
|
document.cookie = "menu=1;path=/";
|
||||||
|
} else {
|
||||||
|
document.getElementById("container").classList.remove('menus');
|
||||||
|
document.getElementById("menu").innerHTML = "<i class='fad fa-bars'></i>";
|
||||||
|
document.cookie = "menu=0;path=/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//更多页面切换
|
||||||
|
function switchMore() {
|
||||||
|
var more = document.cookie.replace(/(?:(?:^|.*;\s*)more\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0';
|
||||||
|
if (more == '0') {
|
||||||
|
document.getElementById("container").classList.add('mores');
|
||||||
|
document.getElementById("change").innerHTML = "Oops !";
|
||||||
|
document.getElementById("change1").innerHTML = "哎呀,这都被你发现了( 再点击一次可关闭 )";
|
||||||
|
document.cookie = "more=1;path=/";
|
||||||
|
} else {
|
||||||
|
document.getElementById("container").classList.remove('mores');
|
||||||
|
document.getElementById("change").innerHTML = "Hello World !";
|
||||||
|
document.getElementById("change1").innerHTML = "一个建立于 21 世纪的小站,存活于互联网的边缘";
|
||||||
|
document.cookie = "more=0;path=/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//更多弹窗页面
|
||||||
|
function openBox() {
|
||||||
|
document.getElementById("box").style.cssText = "display: block";
|
||||||
|
document.getElementById("row").style.cssText = "display: none";
|
||||||
|
document.getElementById("more").style.cssText = "display: none!important";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeBox() {
|
||||||
|
document.getElementById("box").style.cssText = "display: none";
|
||||||
|
document.getElementById("row").style.cssText = "display: flex";
|
||||||
|
document.getElementById("more").style.cssText = "display: flex";
|
||||||
|
}
|
||||||
|
|
||||||
|
//监听网页宽度
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
//console.log(window.innerWidth);
|
||||||
|
window.addEventListener('resize', function () {
|
||||||
|
//console.log(window.innerWidth);
|
||||||
|
//关闭移动端样式
|
||||||
|
if (window.innerWidth >= 600) {
|
||||||
|
document.getElementById("container").classList.remove('menus');
|
||||||
|
}
|
||||||
|
//移动端隐藏更多页面
|
||||||
|
if (window.innerWidth <= 990) {
|
||||||
|
document.getElementById("container").classList.remove('mores');
|
||||||
|
document.getElementById("change").innerHTML = "Hello World !";
|
||||||
|
document.getElementById("change1").innerHTML = "一个建立于 21 世纪的小站,存活于互联网的边缘";
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
//更多页面显示关闭按钮
|
||||||
|
$("#more").hover(function(){
|
||||||
|
document.getElementById("close").style.cssText = "display: block";
|
||||||
|
},function(){
|
||||||
|
document.getElementById("close").style.cssText = "display: none";
|
||||||
|
})
|
||||||
|
|
||||||
|
//屏蔽右键
|
||||||
|
document.oncontextmenu = function(){
|
||||||
|
iziToast.info({
|
||||||
|
icon: 'fad fa-do-not-enter',
|
||||||
|
title: '温馨提醒',
|
||||||
|
message: '为了浏览体验,本站禁用右键'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
73
js/time.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
var vm = new Vue({
|
||||||
|
el: '#date',
|
||||||
|
data: {
|
||||||
|
hour: "",
|
||||||
|
week: "",
|
||||||
|
curweek: "",
|
||||||
|
day: "",
|
||||||
|
curday: "",
|
||||||
|
month: "",
|
||||||
|
outday: "",
|
||||||
|
},
|
||||||
|
created: function () { //这里是定时器
|
||||||
|
this.timer();
|
||||||
|
setInterval(this.timer, 60000);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
timer: function () {
|
||||||
|
var myDate = new Date();
|
||||||
|
var myYear = myDate.getFullYear(); // 获取当前年份
|
||||||
|
var myMonth = myDate.getMonth() + 1; // 获取当前月份
|
||||||
|
var myDay = myDate.getDate(); // 获取当前日(1- 31)
|
||||||
|
var myHours = myDate.getHours(); // 获取当前小时(0-23)
|
||||||
|
var myMinu = myDate.getMinutes(); // 获取当前分钟(0-59)
|
||||||
|
var mySec = myDate.getSeconds(); // 获取当前秒数(0-59)
|
||||||
|
var myWeek = myDate.getDay() -1; //获取当前星期几(0-6)
|
||||||
|
|
||||||
|
this.hour = myHours;
|
||||||
|
this.year = myYear;
|
||||||
|
this.month = myMonth - 1;
|
||||||
|
this.day = myDay - 1;
|
||||||
|
this.curday = myDay;
|
||||||
|
this.week = myWeek;
|
||||||
|
this.curweek = myWeek +1;
|
||||||
|
this.minute = myMinu;
|
||||||
|
this.age = myYear - this.yearForYour;
|
||||||
|
},
|
||||||
|
//今天
|
||||||
|
jinduT: function () {
|
||||||
|
var tian = ((this.hour * 60 + this.minute) / 24 / 60 * 100).toFixed(1);
|
||||||
|
return "<div class='progress'><div class='progress-bar' style='width:" + tian + "%'>" + tian + " %" +
|
||||||
|
"</div></div>";
|
||||||
|
},
|
||||||
|
//本周
|
||||||
|
jinduZ: function () {
|
||||||
|
var curdayWithHour = (this.week * 24 * 60 + this.hour * 60 + this.minute) / 7 / 24 / 60;
|
||||||
|
var zhou = (curdayWithHour * 100).toFixed(1);
|
||||||
|
return "<div class='progress'><div class='progress-bar' style='width:" + zhou + "%'>" + zhou + " %" +
|
||||||
|
"</div></div>";
|
||||||
|
},
|
||||||
|
//这个月
|
||||||
|
jinduD: function () {
|
||||||
|
var days = new Date(this.year, this.month + 1, 0).getDate();
|
||||||
|
var yue = ((this.day * 24 * 60 + this.hour * 60 + this.minute) / days / 24 / 60 * 100)
|
||||||
|
.toFixed(1);
|
||||||
|
return "<div class='progress'><div class='progress-bar" + "' style='width:" + yue +
|
||||||
|
"%'>" + yue + " %" + "</div></div>";
|
||||||
|
},
|
||||||
|
//年
|
||||||
|
jinduY: function () {
|
||||||
|
var olddate = new Date(this.year, 0);
|
||||||
|
var nowdate = new Date(this.year, this.month, this.day + 1);
|
||||||
|
var outday = (nowdate - olddate) / (1000 * 60 * 60 * 24) + 1; //
|
||||||
|
this.outday = outday; //已经过去天数
|
||||||
|
var isLeap = (0 === this.year % 4) && (0 === this.year % 100) || (0 === this.year %
|
||||||
|
400);
|
||||||
|
var days = isLeap ? 366 : 365; //今年的天数
|
||||||
|
var ye = (((outday - 1) * 24 * 60 + this.hour * 60 + this.minute) / days / 24 / 60 *
|
||||||
|
100).toFixed(1);
|
||||||
|
return "<div class='progress'><div class='progress-bar" + "' style='width:" + ye +
|
||||||
|
"%'>" + ye + " %" + "</div></div>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
44
package.json
@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "home",
|
|
||||||
"author": "imsyy",
|
|
||||||
"github": "https://github.com/imsyy/home",
|
|
||||||
"home": "https://imsyy.top",
|
|
||||||
"private": true,
|
|
||||||
"version": "4.1.4",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite --host",
|
|
||||||
"build": "vite build",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"format": "prettier --write src/",
|
|
||||||
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@worstone/vue-aplayer": "^1.0.6",
|
|
||||||
"aplayer": "^1.10.1",
|
|
||||||
"axios": "^1.6.8",
|
|
||||||
"dayjs": "^1.11.10",
|
|
||||||
"element-plus": "^2.7.1",
|
|
||||||
"fetch-jsonp": "^1.3.0",
|
|
||||||
"pinia": "^2.1.7",
|
|
||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
|
||||||
"swiper": "^11.1.1",
|
|
||||||
"vue": "^3.4.24"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@icon-park/vue-next": "^1.4.2",
|
|
||||||
"@vicons/fa": "^0.12.0",
|
|
||||||
"@vicons/utils": "^0.1.4",
|
|
||||||
"@vitejs/plugin-vue": "^4.6.2",
|
|
||||||
"eslint": "^8.57.0",
|
|
||||||
"eslint-plugin-vue": "^9.25.0",
|
|
||||||
"prettier": "^3.2.5",
|
|
||||||
"sass": "^1.75.0",
|
|
||||||
"terser": "^5.30.4",
|
|
||||||
"unplugin-auto-import": "^0.11.5",
|
|
||||||
"unplugin-vue-components": "^0.22.12",
|
|
||||||
"vite": "^4.5.3",
|
|
||||||
"vite-plugin-compression": "^0.5.1",
|
|
||||||
"vite-plugin-pwa": "^0.14.7"
|
|
||||||
}
|
|
||||||
}
|
|
5112
pnpm-lock.yaml
@ -1,3 +0,0 @@
|
|||||||
## Logo 字体替换
|
|
||||||
|
|
||||||
可将该文件夹下的 `Pacifico-Regular-all.ttf` 替换原来的 `Pacifico-Regular.ttf`
|
|
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 138 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 245 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 67 KiB |
191
src/App.vue
@ -1,191 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 加载 -->
|
|
||||||
<Loading />
|
|
||||||
<!-- 壁纸 -->
|
|
||||||
<Background @loadComplete="loadComplete" />
|
|
||||||
<!-- 主界面 -->
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<main id="main" v-if="store.imgLoadStatus">
|
|
||||||
<div class="container" v-show="!store.backgroundShow">
|
|
||||||
<section class="all" v-show="!store.setOpenState">
|
|
||||||
<MainLeft />
|
|
||||||
<MainRight v-show="!store.boxOpenState" />
|
|
||||||
<Box v-show="store.boxOpenState" />
|
|
||||||
</section>
|
|
||||||
<section class="more" v-show="store.setOpenState" @click="store.setOpenState = false">
|
|
||||||
<MoreSet />
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<!-- 移动端菜单按钮 -->
|
|
||||||
<Icon
|
|
||||||
class="menu"
|
|
||||||
size="24"
|
|
||||||
v-show="!store.backgroundShow"
|
|
||||||
@click="store.mobileOpenState = !store.mobileOpenState"
|
|
||||||
>
|
|
||||||
<component :is="store.mobileOpenState ? CloseSmall : HamburgerButton" />
|
|
||||||
</Icon>
|
|
||||||
<!-- 页脚 -->
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<Footer v-show="!store.backgroundShow && !store.setOpenState" />
|
|
||||||
</Transition>
|
|
||||||
</main>
|
|
||||||
</Transition>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import { helloInit, checkDays } from "@/utils/getTime.js";
|
|
||||||
import { HamburgerButton, CloseSmall } from "@icon-park/vue-next";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import { Icon } from "@vicons/utils";
|
|
||||||
import Loading from "@/components/Loading.vue";
|
|
||||||
import MainLeft from "@/views/Main/Left.vue";
|
|
||||||
import MainRight from "@/views/Main/Right.vue";
|
|
||||||
import Background from "@/components/Background.vue";
|
|
||||||
import Footer from "@/components/Footer.vue";
|
|
||||||
import Box from "@/views/Box/index.vue";
|
|
||||||
import MoreSet from "@/views/MoreSet/index.vue";
|
|
||||||
import cursorInit from "@/utils/cursor.js";
|
|
||||||
import config from "@/../package.json";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 页面宽度
|
|
||||||
const getWidth = () => {
|
|
||||||
store.setInnerWidth(window.innerWidth);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 加载完成事件
|
|
||||||
const loadComplete = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
// 欢迎提示
|
|
||||||
helloInit();
|
|
||||||
// 默哀模式
|
|
||||||
checkDays();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监听宽度变化
|
|
||||||
watch(
|
|
||||||
() => store.innerWidth,
|
|
||||||
(value) => {
|
|
||||||
if (value < 990) {
|
|
||||||
store.boxOpenState = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 自定义鼠标
|
|
||||||
cursorInit();
|
|
||||||
|
|
||||||
// 屏蔽右键
|
|
||||||
document.oncontextmenu = () => {
|
|
||||||
ElMessage({
|
|
||||||
message: "为了浏览体验,本站禁用右键",
|
|
||||||
grouping: true,
|
|
||||||
duration: 2000,
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 鼠标中键事件
|
|
||||||
window.addEventListener("mousedown", (event) => {
|
|
||||||
if (event.button == 1) {
|
|
||||||
store.backgroundShow = !store.backgroundShow;
|
|
||||||
ElMessage({
|
|
||||||
message: `已${store.backgroundShow ? "开启" : "退出"}壁纸展示状态`,
|
|
||||||
grouping: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 监听当前页面宽度
|
|
||||||
getWidth();
|
|
||||||
window.addEventListener("resize", getWidth);
|
|
||||||
|
|
||||||
// 控制台输出
|
|
||||||
const styleTitle1 = "font-size: 20px;font-weight: 600;color: rgb(244,167,89);";
|
|
||||||
const styleTitle2 = "font-size:12px;color: rgb(244,167,89);";
|
|
||||||
const styleContent = "color: rgb(30,152,255);";
|
|
||||||
const title1 = "無名の主页";
|
|
||||||
const title2 = `
|
|
||||||
_____ __ __ _______ ____ __
|
|
||||||
|_ _| \\/ |/ ____\\ \\ / /\\ \\ / /
|
|
||||||
| | | \\ / | (___ \\ \\_/ / \\ \\_/ /
|
|
||||||
| | | |\\/| |\\___ \\ \\ / \\ /
|
|
||||||
_| |_| | | |____) | | | | |
|
|
||||||
|_____|_| |_|_____/ |_| |_|`;
|
|
||||||
const content = `\n\n版本: ${config.version}\n主页: ${config.home}\nGithub: ${config.github}`;
|
|
||||||
console.info(`%c${title1} %c${title2} %c${content}`, styleTitle1, styleTitle2, styleContent);
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
window.removeEventListener("resize", getWidth);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
#main {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
transform: scale(1.2);
|
|
||||||
transition: transform 0.3s;
|
|
||||||
animation: fade-blur-main-in 0.65s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
|
|
||||||
animation-delay: 0.5s;
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
margin: 0 auto;
|
|
||||||
.all {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 0.75rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.more {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #00000080;
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
z-index: 2;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
}
|
|
||||||
@media (max-width: 1200px) {
|
|
||||||
padding: 0 2vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menu {
|
|
||||||
position: fixed;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
top: 84%;
|
|
||||||
left: calc(50% - 28px);
|
|
||||||
width: 56px;
|
|
||||||
height: 34px;
|
|
||||||
background: rgb(0 0 0 / 20%);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
border-radius: 6px;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
.i-icon {
|
|
||||||
transform: translateY(2px);
|
|
||||||
}
|
|
||||||
@media (min-width: 721px) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,75 +0,0 @@
|
|||||||
// import axios from "axios";
|
|
||||||
import fetchJsonp from "fetch-jsonp";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 音乐播放器
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 获取音乐播放列表
|
|
||||||
export const getPlayerList = async (server, type, id) => {
|
|
||||||
const res = await fetch(
|
|
||||||
`${import.meta.env.VITE_SONG_API}?server=${server}&type=${type}&id=${id}`,
|
|
||||||
);
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
if (data[0].url.startsWith("@")) {
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
const [handle, jsonpCallback, jsonpCallbackFunction, url] = data[0].url.split("@").slice(1);
|
|
||||||
const jsonpData = await fetchJsonp(url).then((res) => res.json());
|
|
||||||
const domain = (
|
|
||||||
jsonpData.req_0.data.sip.find((i) => !i.startsWith("http://ws")) ||
|
|
||||||
jsonpData.req_0.data.sip[0]
|
|
||||||
).replace("http://", "https://");
|
|
||||||
|
|
||||||
return data.map((v, i) => ({
|
|
||||||
name: v.name || v.title,
|
|
||||||
artist: v.artist || v.author,
|
|
||||||
url: domain + jsonpData.req_0.data.midurlinfo[i].purl,
|
|
||||||
cover: v.cover || v.pic,
|
|
||||||
lrc: v.lrc,
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
return data.map((v) => ({
|
|
||||||
name: v.name || v.title,
|
|
||||||
artist: v.artist || v.author,
|
|
||||||
url: v.url,
|
|
||||||
cover: v.cover || v.pic,
|
|
||||||
lrc: v.lrc,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 一言
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 获取一言数据
|
|
||||||
export const getHitokoto = async () => {
|
|
||||||
const res = await fetch("https://v1.hitokoto.cn");
|
|
||||||
return await res.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 天气
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 获取高德地理位置信息
|
|
||||||
export const getAdcode = async (key) => {
|
|
||||||
const res = await fetch(`https://restapi.amap.com/v3/ip?key=${key}`);
|
|
||||||
return await res.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取高德地理天气信息
|
|
||||||
export const getWeather = async (key, city) => {
|
|
||||||
const res = await fetch(
|
|
||||||
`https://restapi.amap.com/v3/weather/weatherInfo?key=${key}&city=${city}`,
|
|
||||||
);
|
|
||||||
return await res.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取教书先生天气 API
|
|
||||||
// https://api.oioweb.cn/doc/weather/GetWeather
|
|
||||||
export const getOtherWeather = async () => {
|
|
||||||
const res = await fetch("https://api.oioweb.cn/api/weather/GetWeather");
|
|
||||||
return await res.json();
|
|
||||||
};
|
|
@ -1,37 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"icon": "Blog",
|
|
||||||
"name": "博客",
|
|
||||||
"link": "https://blog.imsyy.top/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "Cloud",
|
|
||||||
"name": "网盘",
|
|
||||||
"link": "https://pan.imsyy.top/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "CompactDisc",
|
|
||||||
"name": "音乐",
|
|
||||||
"link": "https://music.imsyy.top/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "Compass",
|
|
||||||
"name": "起始页",
|
|
||||||
"link": "https://nav.imsyy.top/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "Book",
|
|
||||||
"name": "网址集",
|
|
||||||
"link": "https://web.imsyy.top/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "Fire",
|
|
||||||
"name": "今日热榜",
|
|
||||||
"link": "https://hot.imsyy.top/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon": "LaptopCode",
|
|
||||||
"name": "站点监测",
|
|
||||||
"link": "https://status.imsyy.top/"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,38 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"name": "Github",
|
|
||||||
"icon": "/images/icon/github.png",
|
|
||||||
"tip": "去 Github 看看",
|
|
||||||
"url": "https://github.com/imsyy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "BiliBili",
|
|
||||||
"icon": "/images/icon/bilibili.png",
|
|
||||||
"tip": "(゜-゜)つロ 干杯 ~",
|
|
||||||
"url": "https://space.bilibili.com/98544142"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "QQ",
|
|
||||||
"icon": "/images/icon/qq.png",
|
|
||||||
"tip": "有什么事吗",
|
|
||||||
"url": "https://res.abeim.cn/api/qq/?qq=1539250352"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Email",
|
|
||||||
"icon": "/images/icon/email.png",
|
|
||||||
"tip": "来封 Email ~",
|
|
||||||
"url": "mailto:one@imsyy.top"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Twitter",
|
|
||||||
"icon": "/images/icon/twitter.png",
|
|
||||||
"tip": "你懂的 ~",
|
|
||||||
"url": "https://twitter.com/iimmsyy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Telegram",
|
|
||||||
"icon": "/images/icon/telegram.png",
|
|
||||||
"tip": "你懂的 ~",
|
|
||||||
"url": "https://t.me/bottom_user"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,171 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div :class="store.backgroundShow ? 'cover show' : 'cover'">
|
|
||||||
<img
|
|
||||||
v-show="store.imgLoadStatus"
|
|
||||||
:src="bgUrl"
|
|
||||||
class="bg"
|
|
||||||
alt="cover"
|
|
||||||
@load="imgLoadComplete"
|
|
||||||
@error.once="imgLoadError"
|
|
||||||
@animationend="imgAnimationEnd"
|
|
||||||
/>
|
|
||||||
<div :class="store.backgroundShow ? 'gray hidden' : 'gray'" />
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<a
|
|
||||||
v-if="store.backgroundShow && store.coverType != '3'"
|
|
||||||
class="down"
|
|
||||||
:href="bgUrl"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
下载壁纸
|
|
||||||
</a>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import { Error } from "@icon-park/vue-next";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
const bgUrl = ref(null);
|
|
||||||
const imgTimeout = ref(null);
|
|
||||||
const emit = defineEmits(["loadComplete"]);
|
|
||||||
|
|
||||||
// 壁纸随机数
|
|
||||||
// 请依据文件夹内的图片个数修改 Math.random() 后面的第一个数字
|
|
||||||
const bgRandom = Math.floor(Math.random() * 10 + 1);
|
|
||||||
|
|
||||||
// 更换壁纸链接
|
|
||||||
const changeBg = (type) => {
|
|
||||||
if (type == 0) {
|
|
||||||
bgUrl.value = `/images/background${bgRandom}.jpg`;
|
|
||||||
} else if (type == 1) {
|
|
||||||
bgUrl.value = "https://api.dujin.org/bing/1920.php";
|
|
||||||
} else if (type == 2) {
|
|
||||||
bgUrl.value = "https://api.vvhan.com/api/wallpaper/views";
|
|
||||||
} else if (type == 3) {
|
|
||||||
bgUrl.value = "https://api.vvhan.com/api/wallpaper/acg";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 图片加载完成
|
|
||||||
const imgLoadComplete = () => {
|
|
||||||
imgTimeout.value = setTimeout(
|
|
||||||
() => {
|
|
||||||
store.setImgLoadStatus(true);
|
|
||||||
},
|
|
||||||
Math.floor(Math.random() * (600 - 300 + 1)) + 300,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 图片动画完成
|
|
||||||
const imgAnimationEnd = () => {
|
|
||||||
console.log("壁纸加载且动画完成");
|
|
||||||
// 加载完成事件
|
|
||||||
emit("loadComplete");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 图片显示失败
|
|
||||||
const imgLoadError = () => {
|
|
||||||
console.error("壁纸加载失败:", bgUrl.value);
|
|
||||||
ElMessage({
|
|
||||||
message: "壁纸加载失败,已临时切换回默认",
|
|
||||||
icon: h(Error, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
bgUrl.value = `/images/background${bgRandom}.jpg`;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监听壁纸切换
|
|
||||||
watch(
|
|
||||||
() => store.coverType,
|
|
||||||
(value) => {
|
|
||||||
changeBg(value);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 加载壁纸
|
|
||||||
changeBg(store.coverType);
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
clearTimeout(imgTimeout.value);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.cover {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
transition: 0.25s;
|
|
||||||
z-index: -1;
|
|
||||||
|
|
||||||
&.show {
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
backface-visibility: hidden;
|
|
||||||
filter: blur(20px) brightness(0.3);
|
|
||||||
transition:
|
|
||||||
filter 0.3s,
|
|
||||||
transform 0.3s;
|
|
||||||
animation: fade-blur-in 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
|
|
||||||
animation-delay: 0.45s;
|
|
||||||
}
|
|
||||||
.gray {
|
|
||||||
opacity: 1;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: radial-gradient(rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0.5) 100%),
|
|
||||||
radial-gradient(rgba(0, 0, 0, 0) 33%, rgba(0, 0, 0, 0.3) 166%);
|
|
||||||
|
|
||||||
transition: 1.5s;
|
|
||||||
&.hidden {
|
|
||||||
opacity: 0;
|
|
||||||
transition: 1.5s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.down {
|
|
||||||
font-size: 16px;
|
|
||||||
color: white;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 30px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: 0 auto;
|
|
||||||
display: block;
|
|
||||||
padding: 20px 26px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #00000030;
|
|
||||||
width: 120px;
|
|
||||||
height: 30px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
background-color: #00000060;
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,120 +0,0 @@
|
|||||||
<template>
|
|
||||||
<footer id="footer" :class="store.footerBlur ? 'blur' : null">
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<div v-if="!store.playerState || !store.playerLrcShow" class="power">
|
|
||||||
<span>
|
|
||||||
Copyright ©
|
|
||||||
<span v-if="siteStartDate?.length >= 4" class="site-start">
|
|
||||||
{{ siteStartDate.substring(0, 4) }}
|
|
||||||
-
|
|
||||||
</span>
|
|
||||||
{{ fullYear }}
|
|
||||||
<a :href="siteUrl">{{ siteAnthor }}</a>
|
|
||||||
</span>
|
|
||||||
<!-- 以下信息请不要修改哦 -->
|
|
||||||
<span class="hidden">
|
|
||||||
& Made by
|
|
||||||
<a :href="config.github" target="_blank">
|
|
||||||
{{ config.author }}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<!-- 站点备案 -->
|
|
||||||
<a v-if="siteIcp" href="https://beian.miit.gov.cn" target="_blank">
|
|
||||||
&
|
|
||||||
{{ siteIcp }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div v-else class="lrc">
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<div class="lrc-all" :key="store.getPlayerLrc">
|
|
||||||
<music-one theme="filled" size="18" fill="#efefef" />
|
|
||||||
<span class="lrc-text text-hidden" v-html="store.getPlayerLrc" />
|
|
||||||
<music-one theme="filled" size="18" fill="#efefef" />
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</footer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { MusicOne } from "@icon-park/vue-next";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import config from "@/../package.json";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
const fullYear = new Date().getFullYear();
|
|
||||||
|
|
||||||
// 加载配置数据
|
|
||||||
const siteStartDate = ref(import.meta.env.VITE_SITE_START);
|
|
||||||
const siteIcp = ref(import.meta.env.VITE_SITE_ICP);
|
|
||||||
const siteAnthor = ref(import.meta.env.VITE_SITE_ANTHOR);
|
|
||||||
const siteUrl = computed(() => {
|
|
||||||
const url = import.meta.env.VITE_SITE_URL;
|
|
||||||
if (!url) return "https://www.imsyy.top";
|
|
||||||
// 判断协议前缀
|
|
||||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
||||||
return "//" + url;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
#footer {
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 46px;
|
|
||||||
line-height: 46px;
|
|
||||||
text-align: center;
|
|
||||||
z-index: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
.power {
|
|
||||||
animation: fade 0.3s;
|
|
||||||
}
|
|
||||||
.lrc {
|
|
||||||
padding: 0 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
.lrc-all {
|
|
||||||
width: 98%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
.lrc-text {
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
.i-icon {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
display: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.blur {
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
background: rgb(0 0 0 / 25%);
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.fade-enter-active,
|
|
||||||
.fade-leave-active {
|
|
||||||
transition: opacity 0.15s ease-in-out;
|
|
||||||
}
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
font-size: 0.85rem;
|
|
||||||
&.blur {
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,128 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="hitokoto cards"
|
|
||||||
v-show="!store.musicOpenState"
|
|
||||||
@mouseenter="openMusicShow = true"
|
|
||||||
@mouseleave="openMusicShow = false"
|
|
||||||
@click.stop
|
|
||||||
>
|
|
||||||
<!-- 打开音乐面板 -->
|
|
||||||
<Transition name="el-fade-in-linear">
|
|
||||||
<div
|
|
||||||
class="open-music"
|
|
||||||
v-show="openMusicShow && store.musicIsOk"
|
|
||||||
@click="store.musicOpenState = true"
|
|
||||||
>
|
|
||||||
<music-menu theme="filled" size="18" fill="#efefef" />
|
|
||||||
<span>打开音乐播放器</span>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
<!-- 一言内容 -->
|
|
||||||
<Transition name="el-fade-in-linear" mode="out-in">
|
|
||||||
<div :key="hitokotoData.text" class="content" @click="updateHitokoto">
|
|
||||||
<span class="text">{{ hitokotoData.text }}</span>
|
|
||||||
<span class="from">-「 {{ hitokotoData.from }} 」</span>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { MusicMenu, Error } from "@icon-park/vue-next";
|
|
||||||
import { getHitokoto } from "@/api";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import debounce from "@/utils/debounce.js";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 开启音乐面板按钮显隐
|
|
||||||
const openMusicShow = ref(false);
|
|
||||||
|
|
||||||
// 一言数据
|
|
||||||
const hitokotoData = reactive({
|
|
||||||
text: "这里应该显示一句话",
|
|
||||||
from: "無名",
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取一言数据
|
|
||||||
const getHitokotoData = async () => {
|
|
||||||
try {
|
|
||||||
const result = await getHitokoto();
|
|
||||||
hitokotoData.text = result.hitokoto;
|
|
||||||
hitokotoData.from = result.from;
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage({
|
|
||||||
message: "一言获取失败",
|
|
||||||
icon: h(Error, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
hitokotoData.text = "这里应该显示一句话";
|
|
||||||
hitokotoData.from = "無名";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新一言数据
|
|
||||||
const updateHitokoto = () => {
|
|
||||||
// 防抖
|
|
||||||
debounce(() => {
|
|
||||||
getHitokotoData();
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getHitokotoData();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.hitokoto {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
.open-music {
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: #00000026;
|
|
||||||
padding: 4px 0;
|
|
||||||
border-radius: 8px 8px 0 0;
|
|
||||||
.i-icon {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
display: block;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
font-size: 0.95rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
.text {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
word-break: break-all;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
|
||||||
.from {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
align-self: flex-end;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,182 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div v-if="siteLinks[0]" class="links">
|
|
||||||
<div class="line">
|
|
||||||
<Icon size="20">
|
|
||||||
<Link />
|
|
||||||
</Icon>
|
|
||||||
<span class="title">网站列表</span>
|
|
||||||
</div>
|
|
||||||
<!-- 网站列表 -->
|
|
||||||
<Swiper
|
|
||||||
v-if="siteLinks[0]"
|
|
||||||
:modules="[Pagination, Mousewheel]"
|
|
||||||
:slides-per-view="1"
|
|
||||||
:space-between="40"
|
|
||||||
:pagination="{
|
|
||||||
el: '.swiper-pagination',
|
|
||||||
clickable: true,
|
|
||||||
bulletElement: 'div',
|
|
||||||
}"
|
|
||||||
:mousewheel="true"
|
|
||||||
>
|
|
||||||
<SwiperSlide v-for="site in siteLinksList" :key="site">
|
|
||||||
<el-row class="link-all" :gutter="20">
|
|
||||||
<el-col v-for="(item, index) in site" :span="8" :key="item">
|
|
||||||
<div
|
|
||||||
class="item cards"
|
|
||||||
:style="index < 3 ? 'margin-bottom: 20px' : null"
|
|
||||||
@click="jumpLink(item)"
|
|
||||||
>
|
|
||||||
<Icon size="26">
|
|
||||||
<component :is="siteIcon[item.icon]" />
|
|
||||||
</Icon>
|
|
||||||
<span class="name text-hidden">{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</SwiperSlide>
|
|
||||||
<div class="swiper-pagination" />
|
|
||||||
</Swiper>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { Icon } from "@vicons/utils";
|
|
||||||
// 可前往 https://www.xicons.org 自行挑选并在此处引入
|
|
||||||
import { Link, Blog, CompactDisc, Cloud, Compass, Book, Fire, LaptopCode } from "@vicons/fa"; // 注意使用正确的类别
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
|
||||||
import { Pagination, Mousewheel } from "swiper/modules";
|
|
||||||
import siteLinks from "@/assets/siteLinks.json";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 计算网站链接
|
|
||||||
const siteLinksList = computed(() => {
|
|
||||||
const result = [];
|
|
||||||
for (let i = 0; i < siteLinks.length; i += 6) {
|
|
||||||
const subArr = siteLinks.slice(i, i + 6);
|
|
||||||
result.push(subArr);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 网站链接图标
|
|
||||||
const siteIcon = {
|
|
||||||
Blog,
|
|
||||||
Cloud,
|
|
||||||
CompactDisc,
|
|
||||||
Compass,
|
|
||||||
Book,
|
|
||||||
Fire,
|
|
||||||
LaptopCode,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 链接跳转
|
|
||||||
const jumpLink = (data) => {
|
|
||||||
if (data.name === "音乐" && store.musicClick) {
|
|
||||||
if (typeof $openList === "function") $openList();
|
|
||||||
} else {
|
|
||||||
window.open(data.link, "_blank");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
console.log(siteLinks);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.links {
|
|
||||||
.line {
|
|
||||||
margin: 2rem 0.25rem 1rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
.title {
|
|
||||||
margin-left: 8px;
|
|
||||||
font-size: 1.15rem;
|
|
||||||
text-shadow: 0 0 5px #00000050;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.swiper {
|
|
||||||
left: -10px;
|
|
||||||
width: calc(100% + 20px);
|
|
||||||
padding: 5px 10px 0;
|
|
||||||
z-index: 0;
|
|
||||||
.swiper-slide {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.swiper-pagination {
|
|
||||||
margin-top: 12px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
:deep(.swiper-pagination-bullet) {
|
|
||||||
background-color: #fff;
|
|
||||||
width: 20px;
|
|
||||||
height: 4px;
|
|
||||||
margin: 0 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
opacity: 0.2;
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
&.swiper-pagination-bullet-active {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.link-all {
|
|
||||||
height: 220px;
|
|
||||||
.item {
|
|
||||||
height: 100px;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.02);
|
|
||||||
background: rgb(0 0 0 / 40%);
|
|
||||||
transition: 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
@media (min-width: 720px) and (max-width: 820px) {
|
|
||||||
.name {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
@media (max-width: 460px) {
|
|
||||||
flex-direction: column;
|
|
||||||
.name {
|
|
||||||
font-size: 1rem;
|
|
||||||
margin-left: 0;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
height: 180px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,152 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div id="loader-wrapper" :class="store.imgLoadStatus ? 'loaded' : null">
|
|
||||||
<div class="loader">
|
|
||||||
<div class="loader-circle" />
|
|
||||||
<div class="loader-text">
|
|
||||||
<span class="name">
|
|
||||||
{{ siteName }}
|
|
||||||
</span>
|
|
||||||
<span class="tip"> 加载中 </span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="loader-section section-left" />
|
|
||||||
<div class="loader-section section-right" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 配置
|
|
||||||
const siteName = import.meta.env.VITE_SITE_NAME;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
#loader-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 999;
|
|
||||||
overflow: hidden;
|
|
||||||
.loader {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
.loader-circle {
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 3px solid transparent;
|
|
||||||
border-top-color: #fff;
|
|
||||||
animation: spin 1.8s linear infinite;
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
left: 5px;
|
|
||||||
right: 5px;
|
|
||||||
bottom: 5px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 3px solid transparent;
|
|
||||||
border-top-color: #a4a4a4;
|
|
||||||
animation: spin-reverse 0.6s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
left: 15px;
|
|
||||||
right: 15px;
|
|
||||||
bottom: 15px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 3px solid transparent;
|
|
||||||
border-top-color: #d3d3d3;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.loader-text {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
color: #fff;
|
|
||||||
z-index: 2;
|
|
||||||
margin-top: 40px;
|
|
||||||
font-size: 24px;
|
|
||||||
.tip {
|
|
||||||
margin-top: 6px;
|
|
||||||
font-size: 18px;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.loader-section {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
width: 51%;
|
|
||||||
height: 100%;
|
|
||||||
background: #333;
|
|
||||||
z-index: 1;
|
|
||||||
&.section-left {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
&.section-right {
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.loaded {
|
|
||||||
visibility: hidden;
|
|
||||||
transform: translateY(-100%);
|
|
||||||
transition:
|
|
||||||
transform 0.3s 1s ease-out,
|
|
||||||
visibility 0.3s 1s ease-out;
|
|
||||||
.loader {
|
|
||||||
.loader-circle,
|
|
||||||
.loader-text {
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.3s ease-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.loader-section {
|
|
||||||
&.section-left {
|
|
||||||
transform: translateX(-100%);
|
|
||||||
transition: transform 0.5s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
}
|
|
||||||
&.section-right {
|
|
||||||
transform: translateX(100%);
|
|
||||||
transition: transform 0.5s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin-reverse {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(-360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,193 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 基本信息 -->
|
|
||||||
<div class="message">
|
|
||||||
<!-- Logo -->
|
|
||||||
<div class="logo">
|
|
||||||
<img class="logo-img" :src="siteLogo" alt="logo" />
|
|
||||||
<div :class="{ name: true, 'text-hidden': true, long: siteUrl[0].length >= 6 }">
|
|
||||||
<span class="bg">{{ siteUrl[0] }}</span>
|
|
||||||
<span class="sm">.{{ siteUrl[1] }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 简介 -->
|
|
||||||
<div class="description cards" @click="changeBox">
|
|
||||||
<div class="content">
|
|
||||||
<Icon size="16">
|
|
||||||
<QuoteLeft />
|
|
||||||
</Icon>
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<div :key="descriptionText.hello + descriptionText.text" class="text">
|
|
||||||
<p>{{ descriptionText.hello }}</p>
|
|
||||||
<p>{{ descriptionText.text }}</p>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
<Icon size="16">
|
|
||||||
<QuoteRight />
|
|
||||||
</Icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { Icon } from "@vicons/utils";
|
|
||||||
import { QuoteLeft, QuoteRight } from "@vicons/fa";
|
|
||||||
import { Error } from "@icon-park/vue-next";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 主页站点logo
|
|
||||||
const siteLogo = import.meta.env.VITE_SITE_MAIN_LOGO;
|
|
||||||
// 站点链接
|
|
||||||
const siteUrl = computed(() => {
|
|
||||||
const url = import.meta.env.VITE_SITE_URL;
|
|
||||||
if (!url) return "imsyy.top".split(".");
|
|
||||||
// 判断协议前缀
|
|
||||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
||||||
const urlFormat = url.replace(/^(https?:\/\/)/, "");
|
|
||||||
return urlFormat.split(".");
|
|
||||||
}
|
|
||||||
return url.split(".");
|
|
||||||
});
|
|
||||||
|
|
||||||
// 简介区域文字
|
|
||||||
const descriptionText = reactive({
|
|
||||||
hello: import.meta.env.VITE_DESC_HELLO,
|
|
||||||
text: import.meta.env.VITE_DESC_TEXT,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 切换右侧功能区
|
|
||||||
const changeBox = () => {
|
|
||||||
if (store.getInnerWidth >= 990) {
|
|
||||||
store.boxOpenState = !store.boxOpenState;
|
|
||||||
} else {
|
|
||||||
ElMessage({
|
|
||||||
message: "当前页面宽度不足以开启盒子",
|
|
||||||
grouping: true,
|
|
||||||
icon: h(Error, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监听状态变化
|
|
||||||
watch(
|
|
||||||
() => store.boxOpenState,
|
|
||||||
(value) => {
|
|
||||||
if (value) {
|
|
||||||
descriptionText.hello = import.meta.env.VITE_DESC_HELLO_OTHER;
|
|
||||||
descriptionText.text = import.meta.env.VITE_DESC_TEXT_OTHER;
|
|
||||||
} else {
|
|
||||||
descriptionText.hello = import.meta.env.VITE_DESC_HELLO;
|
|
||||||
descriptionText.text = import.meta.env.VITE_DESC_TEXT;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.message {
|
|
||||||
.logo {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
max-width: 460px;
|
|
||||||
.logo-img {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
width: 100%;
|
|
||||||
padding-left: 22px;
|
|
||||||
transform: translateY(-8px);
|
|
||||||
font-family: "Pacifico-Regular";
|
|
||||||
|
|
||||||
.bg {
|
|
||||||
font-size: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm {
|
|
||||||
margin-left: 6px;
|
|
||||||
font-size: 2rem;
|
|
||||||
@media (min-width: 720px) and (max-width: 789px) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.logo-img {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
height: 128px;
|
|
||||||
.bg {
|
|
||||||
font-size: 4.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
padding: 1rem;
|
|
||||||
margin-top: 3.5rem;
|
|
||||||
max-width: 460px;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.text {
|
|
||||||
margin: 0.75rem 1rem;
|
|
||||||
line-height: 2rem;
|
|
||||||
margin-right: auto;
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
|
|
||||||
p {
|
|
||||||
&:nth-of-type(1) {
|
|
||||||
font-family: "Pacifico-Regular";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.xicon:nth-of-type(2) {
|
|
||||||
align-self: flex-end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
max-width: 100%;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 390px) {
|
|
||||||
.logo {
|
|
||||||
flex-direction: column;
|
|
||||||
.logo-img {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
margin-left: 0;
|
|
||||||
height: auto;
|
|
||||||
transform: none;
|
|
||||||
text-align: center;
|
|
||||||
.bg {
|
|
||||||
font-size: 3.5rem;
|
|
||||||
}
|
|
||||||
.sm {
|
|
||||||
font-size: 1.4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.description {
|
|
||||||
margin-top: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,14 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="more-content">您可在此编写任意内容</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.more-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 20px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,312 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 音乐控制面板 -->
|
|
||||||
<div
|
|
||||||
class="music"
|
|
||||||
@mouseenter="volumeShow = true"
|
|
||||||
@mouseleave="volumeShow = false"
|
|
||||||
v-show="store.musicOpenState"
|
|
||||||
>
|
|
||||||
<div class="btns">
|
|
||||||
<span @click="openMusicList()">音乐列表</span>
|
|
||||||
<span @click="store.musicOpenState = false">回到一言</span>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<go-start theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(0)" />
|
|
||||||
<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" />
|
|
||||||
<pause theme="filled" size="50" fill="#efefef" v-show="store.playerState" />
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
<go-end theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(1)" />
|
|
||||||
</div>
|
|
||||||
<div class="menu">
|
|
||||||
<div class="name" v-show="!volumeShow">
|
|
||||||
<span>{{
|
|
||||||
store.getPlayerData.name
|
|
||||||
? store.getPlayerData.name + " - " + store.getPlayerData.artist
|
|
||||||
: "未播放音乐"
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="volume" v-show="volumeShow">
|
|
||||||
<div class="icon">
|
|
||||||
<volume-mute theme="filled" size="24" fill="#efefef" v-if="volumeNum == 0" />
|
|
||||||
<volume-small
|
|
||||||
theme="filled"
|
|
||||||
size="24"
|
|
||||||
fill="#efefef"
|
|
||||||
v-else-if="volumeNum > 0 && volumeNum < 0.7"
|
|
||||||
/>
|
|
||||||
<volume-notice theme="filled" size="24" fill="#efefef" v-else />
|
|
||||||
</div>
|
|
||||||
<el-slider v-model="volumeNum" :show-tooltip="false" :min="0" :max="1" :step="0.01" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 音乐列表弹窗 -->
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<div class="music-list" v-show="musicListShow" @click="closeMusicList()">
|
|
||||||
<Transition name="zoom">
|
|
||||||
<div class="list" v-show="musicListShow" @click.stop>
|
|
||||||
<close-one
|
|
||||||
class="close"
|
|
||||||
theme="filled"
|
|
||||||
size="28"
|
|
||||||
fill="#ffffff60"
|
|
||||||
@click="closeMusicList()"
|
|
||||||
/>
|
|
||||||
<Player
|
|
||||||
ref="playerRef"
|
|
||||||
:songServer="playerData.server"
|
|
||||||
:songType="playerData.type"
|
|
||||||
:songId="playerData.id"
|
|
||||||
:volume="volumeNum"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {
|
|
||||||
GoStart,
|
|
||||||
PlayOne,
|
|
||||||
Pause,
|
|
||||||
GoEnd,
|
|
||||||
CloseOne,
|
|
||||||
VolumeMute,
|
|
||||||
VolumeSmall,
|
|
||||||
VolumeNotice,
|
|
||||||
} from "@icon-park/vue-next";
|
|
||||||
import Player from "@/components/Player.vue";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 音量条数据
|
|
||||||
const volumeShow = ref(false);
|
|
||||||
const volumeNum = ref(store.musicVolume ? store.musicVolume : 0.7);
|
|
||||||
|
|
||||||
// 播放列表数据
|
|
||||||
const musicListShow = ref(false);
|
|
||||||
const playerRef = ref(null);
|
|
||||||
const playerData = reactive({
|
|
||||||
server: import.meta.env.VITE_SONG_SERVER,
|
|
||||||
type: import.meta.env.VITE_SONG_TYPE,
|
|
||||||
id: import.meta.env.VITE_SONG_ID,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 开启播放列表
|
|
||||||
const openMusicList = () => {
|
|
||||||
musicListShow.value = true;
|
|
||||||
playerRef.value.toggleList();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 关闭播放列表
|
|
||||||
const closeMusicList = () => {
|
|
||||||
musicListShow.value = false;
|
|
||||||
playerRef.value.toggleList();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 音乐播放暂停
|
|
||||||
const changePlayState = () => {
|
|
||||||
playerRef.value.playToggle();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 音乐上下曲
|
|
||||||
const changeMusicIndex = (type) => {
|
|
||||||
playerRef.value.changeSong(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 空格键事件
|
|
||||||
window.addEventListener("keydown", (e) => {
|
|
||||||
if (!store.musicIsOk) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.code == "Space") {
|
|
||||||
changePlayState();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 挂载方法至 window
|
|
||||||
window.$openList = openMusicList;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 监听音量变化
|
|
||||||
watch(
|
|
||||||
() => volumeNum.value,
|
|
||||||
(value) => {
|
|
||||||
store.musicVolume = value;
|
|
||||||
playerRef.value.changeVolume(store.musicVolume);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.music {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: #00000040;
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
.btns {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
span {
|
|
||||||
background: #ffffff26;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 6px;
|
|
||||||
margin: 0px 6px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow-x: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
&:hover {
|
|
||||||
background: #ffffff4d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.control {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
width: 100%;
|
|
||||||
.state {
|
|
||||||
transition: opacity 0.1s;
|
|
||||||
.i-icon {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.i-icon {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
display: flex;
|
|
||||||
border-radius: 6px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 6px;
|
|
||||||
transform: scale(1);
|
|
||||||
&:hover {
|
|
||||||
background: #ffffff33;
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menu {
|
|
||||||
height: 26px;
|
|
||||||
width: 100%;
|
|
||||||
line-height: 26px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
.name {
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow-x: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
animation: fade 0.3s;
|
|
||||||
}
|
|
||||||
.volume {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: row;
|
|
||||||
animation: fade 0.3s;
|
|
||||||
.icon {
|
|
||||||
margin-right: 12px;
|
|
||||||
span {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(*) {
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
:deep(.el-slider__button) {
|
|
||||||
transition: 0.3s;
|
|
||||||
}
|
|
||||||
.el-slider {
|
|
||||||
margin-right: 12px;
|
|
||||||
--el-slider-main-bg-color: #efefef;
|
|
||||||
--el-slider-runway-bg-color: #ffffff40;
|
|
||||||
--el-slider-button-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.music-list {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
margin: auto;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #00000080;
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
z-index: 1;
|
|
||||||
.list {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
top: calc(50% - 300px);
|
|
||||||
left: calc(50% - 320px);
|
|
||||||
width: 640px;
|
|
||||||
height: 600px;
|
|
||||||
background-color: #ffffff66;
|
|
||||||
border-radius: 6px;
|
|
||||||
z-index: 999;
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
left: calc(50% - 45%);
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
.close {
|
|
||||||
position: absolute;
|
|
||||||
top: 12px;
|
|
||||||
right: 12px;
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
display: block;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.2);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 弹窗动画
|
|
||||||
.zoom-enter-active {
|
|
||||||
animation: zoom 0.4s ease-in-out;
|
|
||||||
}
|
|
||||||
.zoom-leave-active {
|
|
||||||
animation: zoom 0.3s ease-in-out reverse;
|
|
||||||
}
|
|
||||||
@keyframes zoom {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0) translateY(-600px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1) translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,288 +0,0 @@
|
|||||||
<template>
|
|
||||||
<APlayer
|
|
||||||
v-if="playList[0]"
|
|
||||||
ref="player"
|
|
||||||
:audio="playList"
|
|
||||||
:autoplay="store.playerAutoplay"
|
|
||||||
:theme="theme"
|
|
||||||
:autoSwitch="false"
|
|
||||||
:loop="store.playerLoop"
|
|
||||||
:order="store.playerOrder"
|
|
||||||
:volume="volume"
|
|
||||||
:showLrc="true"
|
|
||||||
:listFolded="listFolded"
|
|
||||||
:listMaxHeight="listMaxHeight"
|
|
||||||
:noticeSwitch="false"
|
|
||||||
@play="onPlay"
|
|
||||||
@pause="onPause"
|
|
||||||
@timeupdate="onTimeUp"
|
|
||||||
@error="loadMusicError"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
|
|
||||||
import { getPlayerList } from "@/api";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import APlayer from "@worstone/vue-aplayer";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 获取播放器 DOM
|
|
||||||
const player = ref(null);
|
|
||||||
|
|
||||||
// 歌曲播放列表
|
|
||||||
const playList = ref([]);
|
|
||||||
|
|
||||||
// 歌曲播放项
|
|
||||||
const playIndex = ref(0);
|
|
||||||
|
|
||||||
// 配置项
|
|
||||||
const props = defineProps({
|
|
||||||
// 主题色
|
|
||||||
theme: {
|
|
||||||
type: String,
|
|
||||||
default: "#efefef",
|
|
||||||
},
|
|
||||||
// 默认音量
|
|
||||||
volume: {
|
|
||||||
type: Number,
|
|
||||||
default: 0.7,
|
|
||||||
validator: (value) => {
|
|
||||||
return value >= 0 && value <= 1;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
|
|
||||||
songServer: {
|
|
||||||
type: String,
|
|
||||||
default: "netease", //'netease' | 'tencent'
|
|
||||||
},
|
|
||||||
// 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
|
|
||||||
songType: {
|
|
||||||
type: String,
|
|
||||||
default: "playlist",
|
|
||||||
},
|
|
||||||
// id
|
|
||||||
songId: {
|
|
||||||
type: String,
|
|
||||||
default: "7452421335",
|
|
||||||
},
|
|
||||||
// 列表是否默认折叠
|
|
||||||
listFolded: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
// 列表最大高度
|
|
||||||
listMaxHeight: {
|
|
||||||
type: Number,
|
|
||||||
default: 420,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const listHeight = computed(() => {
|
|
||||||
return props.listMaxHeight + "px";
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化播放器
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
try {
|
|
||||||
getPlayerList(props.songServer, props.songType, props.songId).then((res) => {
|
|
||||||
console.log(res);
|
|
||||||
// 更改播放器加载状态
|
|
||||||
store.musicIsOk = true;
|
|
||||||
// 生成歌单
|
|
||||||
playList.value = res;
|
|
||||||
console.log("音乐加载完成");
|
|
||||||
console.log(playList.value);
|
|
||||||
console.log(playIndex.value, playList.value.length, props.volume);
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
store.musicIsOk = false;
|
|
||||||
ElMessage({
|
|
||||||
message: "播放器加载失败",
|
|
||||||
grouping: true,
|
|
||||||
icon: h(PlayWrong, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 播放
|
|
||||||
const onPlay = () => {
|
|
||||||
console.log("播放");
|
|
||||||
playIndex.value = player.value.aplayer.index;
|
|
||||||
// 播放状态
|
|
||||||
store.setPlayerState(player.value.audioRef.paused);
|
|
||||||
// 储存播放器信息
|
|
||||||
store.setPlayerData(playList.value[playIndex.value].name, playList.value[playIndex.value].artist);
|
|
||||||
ElMessage({
|
|
||||||
message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
|
|
||||||
grouping: true,
|
|
||||||
icon: h(MusicOne, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暂停
|
|
||||||
const onPause = () => {
|
|
||||||
store.setPlayerState(player.value.audioRef.paused);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 音频时间更新事件
|
|
||||||
const onTimeUp = () => {
|
|
||||||
let lyrics = player.value.aplayer.lyrics[playIndex.value];
|
|
||||||
let lyricIndex = player.value.aplayer.lyricIndex;
|
|
||||||
if (!lyrics || !lyrics[lyricIndex]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let lrc = lyrics[lyricIndex][1];
|
|
||||||
if (lrc === "Loading") {
|
|
||||||
lrc = "歌词加载中";
|
|
||||||
} else if (lrc === "Not available") {
|
|
||||||
lrc = "歌词加载失败";
|
|
||||||
}
|
|
||||||
store.setPlayerLrc(lrc);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换播放暂停事件
|
|
||||||
const playToggle = () => {
|
|
||||||
player.value.toggle();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换音量事件
|
|
||||||
const changeVolume = (value) => {
|
|
||||||
player.value.setVolume(value, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换上下曲
|
|
||||||
const changeSong = (type) => {
|
|
||||||
type === 0 ? player.value.skipBack() : player.value.skipForward();
|
|
||||||
nextTick(() => {
|
|
||||||
player.value.play();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 切换歌曲列表状态
|
|
||||||
const toggleList = () => {
|
|
||||||
player.value.toggleList();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 加载音频错误
|
|
||||||
const loadMusicError = () => {
|
|
||||||
let notice = "";
|
|
||||||
if (playList.value.length > 1) {
|
|
||||||
notice = "播放歌曲出现错误,播放器将在 2s 后进行下一首";
|
|
||||||
} else {
|
|
||||||
notice = "播放歌曲出现错误";
|
|
||||||
}
|
|
||||||
ElMessage({
|
|
||||||
message: notice,
|
|
||||||
grouping: true,
|
|
||||||
icon: h(PlayWrong, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#EFEFEF",
|
|
||||||
duration: 2000,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
console.error(
|
|
||||||
"播放歌曲: " + player.value.aplayer.audio[player.value.aplayer.index].name + " 出现错误",
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露子组件方法
|
|
||||||
defineExpose({ playToggle, changeVolume, changeSong, toggleList });
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.aplayer {
|
|
||||||
width: 80%;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-family: "HarmonyOS_Regular", sans-serif !important;
|
|
||||||
:deep(.aplayer-body) {
|
|
||||||
background-color: transparent;
|
|
||||||
.aplayer-pic {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.aplayer-info {
|
|
||||||
margin-left: 0;
|
|
||||||
background-color: #ffffff40;
|
|
||||||
border-color: transparent !important;
|
|
||||||
.aplayer-music {
|
|
||||||
flex-grow: initial;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
overflow: initial;
|
|
||||||
.aplayer-title {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
.aplayer-author {
|
|
||||||
color: #efefef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.aplayer-lrc {
|
|
||||||
text-align: left;
|
|
||||||
margin: 7px 0 6px 6px;
|
|
||||||
height: 44px;
|
|
||||||
mask: linear-gradient(
|
|
||||||
#fff 15%,
|
|
||||||
#fff 85%,
|
|
||||||
hsla(0deg, 0%, 100%, 0.6) 90%,
|
|
||||||
hsla(0deg, 0%, 100%, 0)
|
|
||||||
);
|
|
||||||
-webkit-mask: linear-gradient(
|
|
||||||
#fff 15%,
|
|
||||||
#fff 85%,
|
|
||||||
hsla(0deg, 0%, 100%, 0.6) 90%,
|
|
||||||
hsla(0deg, 0%, 100%, 0)
|
|
||||||
);
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: #efefef;
|
|
||||||
}
|
|
||||||
.aplayer-lrc-current {
|
|
||||||
font-size: 0.95rem;
|
|
||||||
margin-bottom: 4px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.aplayer-controller {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.aplayer-list) {
|
|
||||||
margin-top: 6px;
|
|
||||||
height: v-bind(listHeight);
|
|
||||||
background-color: transparent;
|
|
||||||
ol {
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
border-color: transparent;
|
|
||||||
&.aplayer-list-light {
|
|
||||||
background: #ffffff40;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
background: #ffffff26 !important;
|
|
||||||
border-radius: 6px !important;
|
|
||||||
}
|
|
||||||
.aplayer-list-index,
|
|
||||||
.aplayer-list-author {
|
|
||||||
color: #efefef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,202 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="setting">
|
|
||||||
<el-collapse class="collapse" v-model="activeName" accordion>
|
|
||||||
<el-collapse-item title="个性壁纸" name="1">
|
|
||||||
<div class="bg-set">
|
|
||||||
<el-radio-group v-model="coverType" text-color="#ffffff" @change="radioChange">
|
|
||||||
<el-radio value="0" size="large" border>默认壁纸</el-radio>
|
|
||||||
<el-radio value="1" size="large" border>每日一图</el-radio>
|
|
||||||
<el-radio value="2" size="large" border>随机风景</el-radio>
|
|
||||||
<el-radio value="3" size="large" border>随机动漫</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
|
||||||
<el-collapse-item title="个性化调整" name="2">
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">建站日期显示</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="siteStartShow"
|
|
||||||
inline-prompt
|
|
||||||
:active-icon="CheckSmall"
|
|
||||||
:inactive-icon="CloseSmall"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">音乐点击是否打开面板</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="musicClick"
|
|
||||||
inline-prompt
|
|
||||||
:active-icon="CheckSmall"
|
|
||||||
:inactive-icon="CloseSmall"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">底栏歌词显示</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="playerLrcShow"
|
|
||||||
inline-prompt
|
|
||||||
:active-icon="CheckSmall"
|
|
||||||
:inactive-icon="CloseSmall"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">底栏背景模糊</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="footerBlur"
|
|
||||||
inline-prompt
|
|
||||||
:active-icon="CheckSmall"
|
|
||||||
:inactive-icon="CloseSmall"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
|
||||||
<el-collapse-item title="播放器配置" name="3">
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">自动播放</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="playerAutoplay"
|
|
||||||
inline-prompt
|
|
||||||
:active-icon="CheckSmall"
|
|
||||||
:inactive-icon="CloseSmall"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">随机播放</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="playerOrder"
|
|
||||||
inline-prompt
|
|
||||||
:active-icon="CheckSmall"
|
|
||||||
:inactive-icon="CloseSmall"
|
|
||||||
active-value="random"
|
|
||||||
inactive-value="list"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<span class="text">循环模式</span>
|
|
||||||
<el-radio-group v-model="playerLoop" size="small" text-color="#FFFFFF">
|
|
||||||
<el-radio value="all" border>列表</el-radio>
|
|
||||||
<el-radio value="one" border>单曲</el-radio>
|
|
||||||
<el-radio value="none" border>不循环</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
|
||||||
<el-collapse-item title="其他设置" name="4">
|
|
||||||
<div>设置内容待增加</div>
|
|
||||||
</el-collapse-item>
|
|
||||||
</el-collapse>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { CheckSmall, CloseSmall, SuccessPicture } from "@icon-park/vue-next";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
|
|
||||||
const store = mainStore();
|
|
||||||
const {
|
|
||||||
coverType,
|
|
||||||
siteStartShow,
|
|
||||||
musicClick,
|
|
||||||
playerLrcShow,
|
|
||||||
footerBlur,
|
|
||||||
playerAutoplay,
|
|
||||||
playerOrder,
|
|
||||||
playerLoop,
|
|
||||||
} = storeToRefs(store);
|
|
||||||
|
|
||||||
// 默认选中项
|
|
||||||
const activeName = ref("1");
|
|
||||||
|
|
||||||
// 壁纸切换
|
|
||||||
const radioChange = () => {
|
|
||||||
ElMessage({
|
|
||||||
message: "壁纸更换成功",
|
|
||||||
icon: h(SuccessPicture, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.setting {
|
|
||||||
.collapse {
|
|
||||||
border-radius: 8px;
|
|
||||||
--el-collapse-content-bg-color: #ffffff10;
|
|
||||||
border-color: transparent;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
:deep(.el-collapse-item__header) {
|
|
||||||
background-color: #ffffff30;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 15px;
|
|
||||||
padding-left: 18px;
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-collapse-item__wrap) {
|
|
||||||
border-color: transparent;
|
|
||||||
|
|
||||||
.el-collapse-item__content {
|
|
||||||
padding: 20px;
|
|
||||||
.item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
font-size: 14px;
|
|
||||||
.el-switch__core {
|
|
||||||
border-color: transparent;
|
|
||||||
background-color: #ffffff30;
|
|
||||||
}
|
|
||||||
.el-radio-group {
|
|
||||||
.el-radio {
|
|
||||||
margin: 2px 10px 2px 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.el-radio-group {
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.el-radio {
|
|
||||||
margin: 10px 16px;
|
|
||||||
background: #ffffff26;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
.el-radio__label {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-radio__inner {
|
|
||||||
background: #ffffff06 !important;
|
|
||||||
border: 2px solid #eeeeee !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-checked {
|
|
||||||
background: #ffffff06 !important;
|
|
||||||
border: 2px solid #eeeeee !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-checked {
|
|
||||||
.el-radio__inner {
|
|
||||||
background-color: #ffffff30 !important;
|
|
||||||
border-color: #fff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
& + .el-radio__label {
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,88 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- 社交链接 -->
|
|
||||||
<div class="social">
|
|
||||||
<div class="link">
|
|
||||||
<a
|
|
||||||
v-for="item in socialLinks"
|
|
||||||
:key="item.name"
|
|
||||||
:href="item.url"
|
|
||||||
target="_blank"
|
|
||||||
@mouseenter="socialTip = item.tip"
|
|
||||||
@mouseleave="socialTip = '通过这里联系我吧'"
|
|
||||||
>
|
|
||||||
<img class="icon" :src="item.icon" height="24" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<span class="tip">{{ socialTip }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import socialLinks from "@/assets/socialLinks.json";
|
|
||||||
|
|
||||||
// 社交链接提示
|
|
||||||
const socialTip = ref("通过这里联系我吧");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.social {
|
|
||||||
margin-top: 1rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
max-width: 460px;
|
|
||||||
width: 100%;
|
|
||||||
height: 42px;
|
|
||||||
background-color: transparent;
|
|
||||||
border-radius: 6px;
|
|
||||||
backdrop-filter: blur(0);
|
|
||||||
animation: fade 0.5s;
|
|
||||||
transition:
|
|
||||||
background-color 0.3s,
|
|
||||||
backdrop-filter 0.3s;
|
|
||||||
@media (max-width: 840px) {
|
|
||||||
max-width: 100%;
|
|
||||||
justify-content: center;
|
|
||||||
.link {
|
|
||||||
justify-content: space-evenly !important;
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
.tip {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.link {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
a {
|
|
||||||
display: inherit;
|
|
||||||
.icon {
|
|
||||||
margin: 0 12px;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tip {
|
|
||||||
display: none;
|
|
||||||
margin-right: 12px;
|
|
||||||
animation: fade 0.5s;
|
|
||||||
}
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
&:hover {
|
|
||||||
background-color: #00000040;
|
|
||||||
backdrop-filter: blur(5px);
|
|
||||||
.tip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,98 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="time-capsule">
|
|
||||||
<div class="title">
|
|
||||||
<hourglass-full theme="two-tone" size="24" :fill="['#efefef', '#00000020']" />
|
|
||||||
<span>时光胶囊</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="timeData" class="all-capsule">
|
|
||||||
<div v-for="(item, tag, index) in timeData" :key="index" class="capsule-item">
|
|
||||||
<div class="item-title">
|
|
||||||
<span class="percentage">
|
|
||||||
{{ item.name }}已度过
|
|
||||||
<strong>{{ item.passed }}</strong>
|
|
||||||
{{ tag === "day" ? "小时" : "天" }}
|
|
||||||
</span>
|
|
||||||
<span class="remaining">
|
|
||||||
剩余 {{ item.remaining }} {{ tag === "day" ? "小时" : "天" }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="item.percentage" />
|
|
||||||
</div>
|
|
||||||
<!-- 建站日期 -->
|
|
||||||
<div v-if="store.siteStartShow" class="capsule-item start">
|
|
||||||
<div class="item-title">{{ startDateText }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { HourglassFull } from "@icon-park/vue-next";
|
|
||||||
import { getTimeCapsule, siteDateStatistics } from "@/utils/getTime.js";
|
|
||||||
import { mainStore } from "@/store";
|
|
||||||
const store = mainStore();
|
|
||||||
|
|
||||||
// 进度条数据
|
|
||||||
const timeData = ref(getTimeCapsule());
|
|
||||||
const startDate = ref(import.meta.env.VITE_SITE_START);
|
|
||||||
const startDateText = ref(null);
|
|
||||||
const timeInterval = ref(null);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
timeInterval.value = setInterval(() => {
|
|
||||||
timeData.value = getTimeCapsule();
|
|
||||||
if (startDate.value) startDateText.value = siteDateStatistics(new Date(startDate.value));
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
clearInterval(timeInterval.value);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.time-capsule {
|
|
||||||
width: 100%;
|
|
||||||
.title {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0.2rem 0 1.5rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
.i-icon {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.all-capsule {
|
|
||||||
.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;
|
|
||||||
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>
|
|
@ -1,114 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="weather" v-if="weatherData.adCode.city && weatherData.weather.weather">
|
|
||||||
<span>{{ weatherData.adCode.city }} </span>
|
|
||||||
<span>{{ weatherData.weather.weather }} </span>
|
|
||||||
<span>{{ weatherData.weather.temperature }}℃</span>
|
|
||||||
<span class="sm-hidden">
|
|
||||||
{{
|
|
||||||
weatherData.weather.winddirection?.endsWith("风")
|
|
||||||
? weatherData.weather.winddirection
|
|
||||||
: weatherData.weather.winddirection + "风"
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<span class="sm-hidden">{{ weatherData.weather.windpower }} 级</span>
|
|
||||||
</div>
|
|
||||||
<div class="weather" v-else>
|
|
||||||
<span>天气数据获取失败</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { getAdcode, getWeather, getOtherWeather } from "@/api";
|
|
||||||
import { Error } from "@icon-park/vue-next";
|
|
||||||
|
|
||||||
// 高德开发者 Key
|
|
||||||
const mainKey = import.meta.env.VITE_WEATHER_KEY;
|
|
||||||
|
|
||||||
// 天气数据
|
|
||||||
const weatherData = reactive({
|
|
||||||
adCode: {
|
|
||||||
city: null, // 城市
|
|
||||||
adcode: null, // 城市编码
|
|
||||||
},
|
|
||||||
weather: {
|
|
||||||
weather: null, // 天气现象
|
|
||||||
temperature: null, // 实时气温
|
|
||||||
winddirection: null, // 风向描述
|
|
||||||
windpower: null, // 风力级别
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 取出天气平均值
|
|
||||||
const getTemperature = (min, max) => {
|
|
||||||
try {
|
|
||||||
// 计算平均值并四舍五入
|
|
||||||
const average = (Number(min) + Number(max)) / 2;
|
|
||||||
return Math.round(average);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("计算温度出现错误:", error);
|
|
||||||
return "NaN";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取天气数据
|
|
||||||
const getWeatherData = async () => {
|
|
||||||
try {
|
|
||||||
// 获取地理位置信息
|
|
||||||
if (!mainKey) {
|
|
||||||
console.log("未配置,使用备用天气接口");
|
|
||||||
const result = await getOtherWeather();
|
|
||||||
console.log(result);
|
|
||||||
const data = result.result;
|
|
||||||
weatherData.adCode = {
|
|
||||||
city: data.city.City || "未知地区",
|
|
||||||
// adcode: data.city.cityId,
|
|
||||||
};
|
|
||||||
weatherData.weather = {
|
|
||||||
weather: data.condition.day_weather,
|
|
||||||
temperature: getTemperature(data.condition.min_degree, data.condition.max_degree),
|
|
||||||
winddirection: data.condition.day_wind_direction,
|
|
||||||
windpower: data.condition.day_wind_power,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// 获取 Adcode
|
|
||||||
const adCode = await getAdcode(mainKey);
|
|
||||||
console.log(adCode);
|
|
||||||
if (adCode.infocode !== "10000") {
|
|
||||||
throw "地区查询失败";
|
|
||||||
}
|
|
||||||
weatherData.adCode = {
|
|
||||||
city: adCode.city,
|
|
||||||
adcode: adCode.adcode,
|
|
||||||
};
|
|
||||||
// 获取天气信息
|
|
||||||
const result = await getWeather(mainKey, weatherData.adCode.adcode);
|
|
||||||
weatherData.weather = {
|
|
||||||
weather: result.lives[0].weather,
|
|
||||||
temperature: result.lives[0].temperature,
|
|
||||||
winddirection: result.lives[0].winddirection,
|
|
||||||
windpower: result.lives[0].windpower,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("天气信息获取失败:" + error);
|
|
||||||
onError("天气信息获取失败");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 报错信息
|
|
||||||
const onError = (message) => {
|
|
||||||
ElMessage({
|
|
||||||
message,
|
|
||||||
icon: h(Error, {
|
|
||||||
theme: "filled",
|
|
||||||
fill: "#efefef",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
console.error(message);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 调用获取天气
|
|
||||||
getWeatherData();
|
|
||||||
});
|
|
||||||
</script>
|
|
22
src/main.js
@ -1,22 +0,0 @@
|
|||||||
import { createApp } from "vue";
|
|
||||||
import "@/style/style.scss";
|
|
||||||
import App from "@/App.vue";
|
|
||||||
// 引入 pinia
|
|
||||||
import { createPinia } from "pinia";
|
|
||||||
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
|
||||||
// swiper
|
|
||||||
import "swiper/css";
|
|
||||||
|
|
||||||
const app = createApp(App);
|
|
||||||
const pinia = createPinia();
|
|
||||||
pinia.use(piniaPluginPersistedstate);
|
|
||||||
|
|
||||||
app.use(pinia);
|
|
||||||
app.mount("#app");
|
|
||||||
|
|
||||||
// PWA
|
|
||||||
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
||||||
// 弹出更新提醒
|
|
||||||
console.log("站点已更新,刷新后生效");
|
|
||||||
ElMessage("站点已更新,刷新后生效");
|
|
||||||
});
|
|
@ -1,93 +0,0 @@
|
|||||||
import { defineStore } from "pinia";
|
|
||||||
|
|
||||||
export const mainStore = defineStore("main", {
|
|
||||||
state: () => {
|
|
||||||
return {
|
|
||||||
imgLoadStatus: false, // 壁纸加载状态
|
|
||||||
innerWidth: null, // 当前窗口宽度
|
|
||||||
coverType: "0", // 壁纸种类
|
|
||||||
siteStartShow: false, // 建站日期显示
|
|
||||||
musicClick: false, // 音乐链接是否跳转
|
|
||||||
musicIsOk: false, // 音乐是否加载完成
|
|
||||||
musicVolume: 0, // 音乐音量;
|
|
||||||
musicOpenState: false, // 音乐面板开启状态
|
|
||||||
backgroundShow: false, // 壁纸展示状态
|
|
||||||
boxOpenState: false, // 盒子开启状态
|
|
||||||
mobileOpenState: false, // 移动端开启状态
|
|
||||||
mobileFuncState: false, // 移动端功能区开启状态
|
|
||||||
setOpenState: false, // 设置页面开启状态
|
|
||||||
playerState: false, // 当前播放状态
|
|
||||||
playerTitle: null, // 当前播放歌曲名
|
|
||||||
playerArtist: null, // 当前播放歌手名
|
|
||||||
playerLrc: "歌词加载中", // 当前播放歌词
|
|
||||||
playerLrcShow: true, // 是否显示底栏歌词
|
|
||||||
footerBlur: true, // 底栏模糊
|
|
||||||
playerAutoplay: false, // 是否自动播放
|
|
||||||
playerLoop: "all", // 循环播放 "all", "one", "none"
|
|
||||||
playerOrder: "list", // 循环顺序 "list", "random"
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getters: {
|
|
||||||
// 获取歌词
|
|
||||||
getPlayerLrc(state) {
|
|
||||||
return state.playerLrc;
|
|
||||||
},
|
|
||||||
// 获取歌曲信息
|
|
||||||
getPlayerData(state) {
|
|
||||||
return {
|
|
||||||
name: state.playerTitle,
|
|
||||||
artist: state.playerArtist,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
// 获取页面宽度
|
|
||||||
getInnerWidth(state) {
|
|
||||||
return state.innerWidth;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
// 更改当前页面宽度
|
|
||||||
setInnerWidth(value) {
|
|
||||||
this.innerWidth = value;
|
|
||||||
if (value >= 720) {
|
|
||||||
this.mobileOpenState = false;
|
|
||||||
this.mobileFuncState = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 更改播放状态
|
|
||||||
setPlayerState(value) {
|
|
||||||
if (value) {
|
|
||||||
this.playerState = false;
|
|
||||||
} else {
|
|
||||||
this.playerState = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 更改歌词
|
|
||||||
setPlayerLrc(value) {
|
|
||||||
this.playerLrc = value;
|
|
||||||
},
|
|
||||||
// 更改歌曲数据
|
|
||||||
setPlayerData(title, artist) {
|
|
||||||
this.playerTitle = title;
|
|
||||||
this.playerArtist = artist;
|
|
||||||
},
|
|
||||||
// 更改壁纸加载状态
|
|
||||||
setImgLoadStatus(value) {
|
|
||||||
this.imgLoadStatus = value;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
persist: {
|
|
||||||
key: "data",
|
|
||||||
storage: window.localStorage,
|
|
||||||
paths: [
|
|
||||||
"coverType",
|
|
||||||
"musicVolume",
|
|
||||||
"siteStartShow",
|
|
||||||
"musicClick",
|
|
||||||
"playerLrcShow",
|
|
||||||
"footerBlur",
|
|
||||||
"playerAutoplay",
|
|
||||||
"playerLoop",
|
|
||||||
"playerOrder",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
@ -1,36 +0,0 @@
|
|||||||
// scss 全局变量
|
|
||||||
|
|
||||||
// 响应式布局
|
|
||||||
@mixin changeWidth($maxWidth: 1200px) {
|
|
||||||
.container {
|
|
||||||
max-width: $maxWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 首次调用
|
|
||||||
@include changeWidth;
|
|
||||||
|
|
||||||
/* 小于1380px时 */
|
|
||||||
@media (max-width: 1380px) {
|
|
||||||
.el-radio-group {
|
|
||||||
justify-content: center !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 小于1280px时 */
|
|
||||||
@media (max-width: 1280px) {
|
|
||||||
@include changeWidth($maxWidth: 1100px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 小于992px时 */
|
|
||||||
@media (max-width: 992px) {
|
|
||||||
@include changeWidth($maxWidth: 900px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 小于720px时 */
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
// 隐藏元素
|
|
||||||
.xs-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,228 +0,0 @@
|
|||||||
/*
|
|
||||||
作者: imsyy
|
|
||||||
主页:https://www.imsyy.top/
|
|
||||||
GitHub:https://github.com/imsyy/home
|
|
||||||
版权所有,请勿删除
|
|
||||||
*/
|
|
||||||
|
|
||||||
@charset "utf-8";
|
|
||||||
|
|
||||||
/*全局样式*/
|
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
// width: 100dvh;
|
|
||||||
// height: 100dvh;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: #333;
|
|
||||||
overflow: hidden;
|
|
||||||
font-family: "HarmonyOS_Regular", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
a,
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
user-select: none;
|
|
||||||
text-decoration: none;
|
|
||||||
color: #fff;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transition: 0.3s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 字体文件
|
|
||||||
@font-face {
|
|
||||||
font-family: "Pacifico-Regular";
|
|
||||||
font-display: swap;
|
|
||||||
src: url("/font/Pacifico-Regular.ttf") format("truetype");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "UnidreamLED";
|
|
||||||
font-display: swap;
|
|
||||||
src: url("/font/UnidreamLED.ttf") format("truetype");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 基础样式
|
|
||||||
#app {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡片样式
|
|
||||||
.cards {
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: #00000040;
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
transform: scale(1);
|
|
||||||
transition:
|
|
||||||
backdrop-filter 0.3s,
|
|
||||||
transform 0.3s;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.01);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.98);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 文字超出
|
|
||||||
.text-hidden {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 弹窗样式
|
|
||||||
.el-message {
|
|
||||||
--el-message-bg-color: #00000040 !important;
|
|
||||||
--el-message-text-color: #efefef !important;
|
|
||||||
-webkit-backdrop-filter: blur(10px);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
border-radius: 25px !important;
|
|
||||||
border-color: transparent !important;
|
|
||||||
|
|
||||||
.el-message__badge {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.el-message__content {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 进度条样式
|
|
||||||
.el-progress-bar {
|
|
||||||
.el-progress-bar__outer {
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: #00000020;
|
|
||||||
.el-progress-bar__inner {
|
|
||||||
background-color: #efefef;
|
|
||||||
border-radius: 6px;
|
|
||||||
text-align: center;
|
|
||||||
font-family: "UnidreamLED";
|
|
||||||
span {
|
|
||||||
color: #564d59;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tooltip 样式
|
|
||||||
.el-popper.is-dark {
|
|
||||||
background: #ffffff60 !important;
|
|
||||||
border: 1px solid transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡片样式
|
|
||||||
.el-card {
|
|
||||||
border-radius: 8px !important;
|
|
||||||
border: 1px solid transparent !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
.el-card__header {
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 16px 20px !important;
|
|
||||||
background-color: #ffffff30 !important;
|
|
||||||
border-bottom: 1px solid transparent !important;
|
|
||||||
}
|
|
||||||
.el-card__body {
|
|
||||||
padding: 0 !important;
|
|
||||||
background-color: #ffffff10 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transition 动画
|
|
||||||
.fade-enter-active,
|
|
||||||
.fade-leave-active {
|
|
||||||
transition: opacity 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-enter-from,
|
|
||||||
.fade-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// keyframes 动画
|
|
||||||
@keyframes fade {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-blur-in {
|
|
||||||
from {
|
|
||||||
filter: blur(20px) brightness(0.3);
|
|
||||||
transform: scale(1.6);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
filter: blur(0) brightness(1);
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-blur-main-in {
|
|
||||||
from {
|
|
||||||
transform: scale(1.2);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 隐藏元素
|
|
||||||
@media (min-width: 910px) and (max-width: 1200px) {
|
|
||||||
.sm-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自定义鼠标
|
|
||||||
#cursor {
|
|
||||||
position: fixed;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 25px;
|
|
||||||
opacity: 0.25;
|
|
||||||
z-index: 10086;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: 0.2s ease-in-out;
|
|
||||||
transition-property: background, opacity, transform;
|
|
||||||
|
|
||||||
&.hidden {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
opacity: 0.5;
|
|
||||||
transform: scale(0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 滚动条样式
|
|
||||||
::-webkit-scrollbar,
|
|
||||||
scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb,
|
|
||||||
scrollbar-thumb {
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: #eeeeee;
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
let mainCursor;
|
|
||||||
|
|
||||||
Math.lerp = (a, b, n) => (1 - n) * a + n * b;
|
|
||||||
|
|
||||||
const getStyle = (el, attr) => {
|
|
||||||
try {
|
|
||||||
return window.getComputedStyle ? window.getComputedStyle(el)[attr] : el.currentStyle[attr];
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const cursorInit = () => {
|
|
||||||
mainCursor = new Cursor();
|
|
||||||
return mainCursor;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Cursor {
|
|
||||||
constructor() {
|
|
||||||
this.pos = {
|
|
||||||
curr: null,
|
|
||||||
prev: null,
|
|
||||||
};
|
|
||||||
this.pt = [];
|
|
||||||
this.create();
|
|
||||||
this.init();
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
move(left, top) {
|
|
||||||
this.cursor.style["left"] = `${left}px`;
|
|
||||||
this.cursor.style["top"] = `${top}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
create() {
|
|
||||||
if (!this.cursor) {
|
|
||||||
this.cursor = document.createElement("div");
|
|
||||||
this.cursor.id = "cursor";
|
|
||||||
this.cursor.classList.add("xs-hidden");
|
|
||||||
this.cursor.classList.add("hidden");
|
|
||||||
document.body.append(this.cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
var el = document.getElementsByTagName("*");
|
|
||||||
for (let i = 0; i < el.length; i++)
|
|
||||||
if (getStyle(el[i], "cursor") == "pointer") this.pt.push(el[i].outerHTML);
|
|
||||||
|
|
||||||
document.body.appendChild((this.scr = document.createElement("style")));
|
|
||||||
this.scr.innerHTML = `* {cursor: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' width='10px' height='10px'><circle cx='4' cy='4' r='4' fill='white' /></svg>") 4 4, auto !important}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
this.scr.remove();
|
|
||||||
this.cursor.classList.remove("active");
|
|
||||||
this.pos = {
|
|
||||||
curr: null,
|
|
||||||
prev: null,
|
|
||||||
};
|
|
||||||
this.pt = [];
|
|
||||||
|
|
||||||
this.create();
|
|
||||||
this.init();
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
document.onmousemove = (e) => {
|
|
||||||
this.pos.curr == null && this.move(e.clientX - 8, e.clientY - 8);
|
|
||||||
this.pos.curr = {
|
|
||||||
x: e.clientX - 8,
|
|
||||||
y: e.clientY - 8,
|
|
||||||
};
|
|
||||||
this.cursor.classList.remove("hidden");
|
|
||||||
};
|
|
||||||
document.onmouseenter = () => this.cursor.classList.remove("hidden");
|
|
||||||
document.onmouseleave = () => this.cursor.classList.add("hidden");
|
|
||||||
document.onmousedown = () => this.cursor.classList.add("active");
|
|
||||||
document.onmouseup = () => this.cursor.classList.remove("active");
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (this.pos.prev) {
|
|
||||||
this.pos.prev.x = Math.lerp(this.pos.prev.x, this.pos.curr.x, 0.35);
|
|
||||||
this.pos.prev.y = Math.lerp(this.pos.prev.y, this.pos.curr.y, 0.35);
|
|
||||||
this.move(this.pos.prev.x, this.pos.prev.y);
|
|
||||||
} else {
|
|
||||||
this.pos.prev = this.pos.curr;
|
|
||||||
}
|
|
||||||
requestAnimationFrame(() => this.render());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default cursorInit;
|
|