mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 03:14:57 +08:00
7
.env
7
.env
@@ -1,7 +1,7 @@
|
||||
# 全局 API 地址
|
||||
## 需部署 API,详见 https://github.com/Binaryify/NeteaseCloudMusicApi
|
||||
VITE_MUSIC_API = "https://api-music.imsyy.top/"
|
||||
# VITE_MUSIC_API = "http://localhost:3000/"
|
||||
# VITE_MUSIC_API = "https://api-music.imsyy.top/"
|
||||
VITE_MUSIC_API = "http://localhost:3000/"
|
||||
|
||||
# 网易云解灰 API 地址(可选功能)
|
||||
## 需部署 API,详见 https://github.com/imsyy/UNM-Server#%E8%BF%90%E8%A1%8C
|
||||
@@ -17,9 +17,6 @@ VITE_SITE_URL = "imsyy.top"
|
||||
VITE_SITE_LOGO = "/images/logo/favicon.svg"
|
||||
VITE_SITE_APPLE_LOGO = "/images/logo/favicon-apple.png"
|
||||
|
||||
# 百度统计(若不需要,请设为空即可)
|
||||
VITE_SITE_BAIDUTONGJI = "c6579e9a33cbc5260fc90231678556ec"
|
||||
|
||||
# ICP 备案号
|
||||
## 若不需要,请设为空即可
|
||||
VITE_ICP = "豫ICP备2022018134号-1"
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
## 说明
|
||||
|
||||
> **当前项目正在重构中,当前版本进入维护模式,仅在遇到重大问题时会进行修复**
|
||||
> - 支持客户端与网页端
|
||||
> - 支持现有版本所有功能
|
||||
> - 新增支持播放与管理本地歌曲
|
||||
|
||||
- 本项目采用 [Vue 3](https://cn.vuejs.org/) 全家桶和 [Naïve UI](https://www.naiveui.com/) 组件库及 `SCSS` 开发
|
||||
- 目前主要以 `Web` 端为主,可能暂时不会考虑使用 `Electron` 构建客户端
|
||||
- 仅对移动端做了基础适配,**不保证功能全部可用**
|
||||
@@ -20,7 +25,7 @@
|
||||
## 🎉 功能
|
||||
|
||||
- 支持扫码登录
|
||||
- 支持手机号登录(上游接口暂时无法使用)
|
||||
- 支持手机号登录
|
||||
- 自动进行每日签到及云贝签到
|
||||
- 支持 [UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server),自动替换变灰歌曲
|
||||
- 由于酷我音源不支持 `https`,故网页端替换可能不全面
|
||||
|
||||
35
index.html
35
index.html
@@ -3,17 +3,16 @@
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="<%- logo %>" />
|
||||
<link rel="apple-touch-icon" href="<%- appleLogo %>" />
|
||||
<link rel="bookmark" href="<%- appleLogo %>" />
|
||||
<link rel="apple-touch-icon-precomposed" sizes="200x200" href="<%- appleLogo %>" />
|
||||
<link rel="icon" href="%VITE_SITE_LOGO%" />
|
||||
<link rel="apple-touch-icon" href="%VITE_SITE_APPLE_LOGO%" />
|
||||
<link rel="bookmark" href="%VITE_SITE_APPLE_LOGO%" />
|
||||
<link rel="apple-touch-icon-precomposed" sizes="200x200" href="%VITE_SITE_APPLE_LOGO%" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" /> -->
|
||||
<title><%- title %></title>
|
||||
<meta name="apple-mobile-web-app-title" content="<%- title %>" />
|
||||
<meta name="author" content="<%- author %>" />
|
||||
<meta name="keywords" content="<%- keywords %>" />
|
||||
<meta name="description" content="<%- description %>" />
|
||||
<title>%VITE_SITE_TITLE%</title>
|
||||
<meta name="apple-mobile-web-app-title" content="%VITE_SITE_TITLE%" />
|
||||
<meta name="author" content="%VITE_SITE_ANTHOR%" />
|
||||
<meta name="keywords" content="%VITE_SITE_KEYWORDS%" />
|
||||
<meta name="description" content="%VITE_SITE_DES%" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<!-- HarmonyOS Sans -->
|
||||
<link rel="stylesheet" href="https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css" />
|
||||
@@ -28,18 +27,6 @@
|
||||
"https://support.dmeng.net/upgrade-your-browser.html?referrer=" +
|
||||
encodeURIComponent(window.location.href);
|
||||
</script>
|
||||
<% if (tongji) { %>
|
||||
<!-- 百度统计 -->
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?<%- tongji %>";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
<% } %>
|
||||
<style>
|
||||
noscript {
|
||||
width: 100%;
|
||||
@@ -67,8 +54,8 @@
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<noscript>
|
||||
<img src="<%- logo %>" alt="logo" />
|
||||
<p class="title"><%- title %></p>
|
||||
<img src="%VITE_SITE_LOGO%" alt="logo" />
|
||||
<p class="title">%VITE_SITE_TITLE%</p>
|
||||
<p class="tip">请开启 JavaScript</p>
|
||||
</noscript>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "splayer",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.9",
|
||||
"author": "imsyy",
|
||||
"home": "https://imsyy.top",
|
||||
"github": "https://github.com/imsyy/SPlayer",
|
||||
@@ -24,7 +24,6 @@
|
||||
"screenfull": "^6.0.2",
|
||||
"swiper": "^9.3.2",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vue": "^3.2.45",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.1.6",
|
||||
@@ -38,8 +37,8 @@
|
||||
"naive-ui": "^2.34.4",
|
||||
"unplugin-auto-import": "^0.12.0",
|
||||
"unplugin-vue-components": "^0.22.11",
|
||||
"vite": "^4.3.8",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-pwa": "^0.15.0"
|
||||
"vite-plugin-pwa": "^0.16.4"
|
||||
}
|
||||
}
|
||||
619
pnpm-lock.yaml
generated
619
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -83,14 +83,18 @@ export default {
|
||||
qr: "QR",
|
||||
phone: "Captcha",
|
||||
email: "Email",
|
||||
canNotUse: "This login method is temporarily unavailable",
|
||||
getCode: "Get the verification code",
|
||||
getCodeAgain: "Try again",
|
||||
codeSuccess: "Verification code sent successfully",
|
||||
codeError: "Failed to send verification code, please try again",
|
||||
canNotUse: "This login mode is not secure and is temporarily disabled",
|
||||
loggedIn: "Already logged in, please don't log in again",
|
||||
qrText1: "Please open APP and scan the code to login",
|
||||
qrText2: "The current QR code is invalid, please scan it again",
|
||||
qrText3: "Scan successfully, please confirm login in the client",
|
||||
qrText4: "Login successfully",
|
||||
qrText5: "Login error, please try again",
|
||||
qrText6: "Login QR code generation failed",
|
||||
loginStatus1: "Please open APP and scan the code to login",
|
||||
loginStatus2: "The current QR code is invalid, please scan it again",
|
||||
loginStatus3: "Scan successfully, please confirm login in the client",
|
||||
loginStatus4: "Login successfully",
|
||||
loginStatus5: "Login error, please try again",
|
||||
loginStatus6: "Login QR code generation failed",
|
||||
},
|
||||
// Menu
|
||||
menu: {
|
||||
|
||||
@@ -83,14 +83,18 @@ export default {
|
||||
qr: "扫码登录",
|
||||
phone: "验证码登录",
|
||||
email: "邮箱登录",
|
||||
canNotUse: "该登录方式暂时无法使用",
|
||||
getCode: "获取验证码",
|
||||
getCodeAgain: "重新获取",
|
||||
codeSuccess: "验证码发送成功",
|
||||
codeError: "验证码发送失败,请重试",
|
||||
canNotUse: "该登录方式不安全,暂时禁用",
|
||||
loggedIn: "已登录,请勿重复登录",
|
||||
qrText1: "请打开云音乐 APP 扫码登录",
|
||||
qrText2: "当前二维码已失效,请重新扫码",
|
||||
qrText3: "扫描成功,请在客户端确认登录",
|
||||
qrText4: "登录成功",
|
||||
qrText5: "登录出错,请重试",
|
||||
qrText6: "登录二维码生成失败",
|
||||
loginStatus1: "请打开云音乐 APP 扫码登录",
|
||||
loginStatus2: "当前二维码已失效,请重新扫码",
|
||||
loginStatus3: "扫描成功,请在客户端确认登录",
|
||||
loginStatus4: "登录成功",
|
||||
loginStatus5: "登录出错,请重试",
|
||||
loginStatus6: "登录二维码生成失败",
|
||||
},
|
||||
// 菜单
|
||||
menu: {
|
||||
|
||||
@@ -35,16 +35,10 @@
|
||||
:foreground="setting.themeData.primaryColor"
|
||||
/>
|
||||
</n-card>
|
||||
<span class="tip">{{ qrText }}</span>
|
||||
<span class="tip">{{ loginStatus }}</span>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="phone" :tab="$t('login.phone')">
|
||||
<n-alert
|
||||
style="width: 100%; margin-top: -20px; margin-bottom: 12px"
|
||||
type="warning"
|
||||
>
|
||||
{{ $t("login.canNotUse") }}
|
||||
</n-alert>
|
||||
<!-- <n-form
|
||||
<n-form
|
||||
class="phone"
|
||||
ref="phoneFormRef"
|
||||
:model="phoneFormData"
|
||||
@@ -83,10 +77,10 @@
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-button style="width: 100%" type="primary" @click="phoneLogin">
|
||||
{{$t("login.login")}}
|
||||
{{ $t("login.login") }}
|
||||
</n-button>
|
||||
</n-form-item>
|
||||
</n-form> -->
|
||||
</n-form>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="email" :tab="$t('login.email')">
|
||||
<n-alert
|
||||
@@ -126,7 +120,7 @@ const { numberRule, mobileRule } = formRules();
|
||||
|
||||
// 二维码数据
|
||||
const qrImg = ref(null);
|
||||
const qrText = ref(t("login.qrText1"));
|
||||
const loginStatus = ref(t("login.loginStatus1"));
|
||||
|
||||
// 手机号登录数据
|
||||
const phoneFormRef = ref(null);
|
||||
@@ -139,7 +133,7 @@ const phoneFormRules = {
|
||||
captcha: numberRule,
|
||||
};
|
||||
const captchaTimeOut = ref(null);
|
||||
const captchaText = ref("获取验证码");
|
||||
const captchaText = ref(t("login.getCode"));
|
||||
const captchaDisabled = ref(false);
|
||||
|
||||
// 定时器
|
||||
@@ -157,15 +151,15 @@ const saveLoginData = (data) => {
|
||||
if (res.data.profile) {
|
||||
user.setUserData(res.data.profile);
|
||||
user.userLogin = true;
|
||||
qrText.value = t("login.qrText4");
|
||||
$message.success(t("login.qrText4"));
|
||||
loginStatus.value = t("login.loginStatus4");
|
||||
$message.success(t("login.loginStatus4"));
|
||||
// 自动签到
|
||||
if ($signIn) $signIn();
|
||||
clearInterval(qrCheckInterval.value);
|
||||
router.push("/user");
|
||||
} else {
|
||||
user.userLogOut();
|
||||
$message.error(t("login.qrText5"));
|
||||
$message.error(t("login.loginStatus5"));
|
||||
getQrKeyData();
|
||||
}
|
||||
});
|
||||
@@ -188,7 +182,7 @@ const getQrKeyData = () => {
|
||||
qrImg.value = `https://music.163.com/login?codekey=${res.data.unikey}`;
|
||||
checkQrState(res.data.unikey);
|
||||
} else {
|
||||
$message.error(t("login.qrText6"));
|
||||
$message.error(t("login.loginStatus6"));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -204,14 +198,14 @@ const checkQrState = (key) => {
|
||||
if (res.code == 800) {
|
||||
getQrKeyData();
|
||||
loginStateMessage.value = null;
|
||||
qrText.value = t("login.qrText2");
|
||||
loginStatus.value = t("login.loginStatus2");
|
||||
} else if (res.code == 801) {
|
||||
loginStateMessage.value = null;
|
||||
qrText.value = t("login.qrText1");
|
||||
loginStatus.value = t("login.loginStatus1");
|
||||
} else if (res.code == 802) {
|
||||
qrText.value = t("login.qrText3");
|
||||
loginStatus.value = t("login.loginStatus3");
|
||||
if (!loginStateMessage.value) {
|
||||
loginStateMessage.value = $message.loading(t("login.qrText3"), {
|
||||
loginStateMessage.value = $message.loading(t("login.loginStatus3"), {
|
||||
duration: 0,
|
||||
});
|
||||
}
|
||||
@@ -229,13 +223,13 @@ const getCaptcha = (data) => {
|
||||
phoneFormRef.value?.validate(
|
||||
(errors) => {
|
||||
if (errors) {
|
||||
$message.error("请输入正确的手机号");
|
||||
$message.error(t("general.message.needCheck"));
|
||||
} else {
|
||||
console.log(data + "发送验证码");
|
||||
sentCaptcha(data).then((res) => {
|
||||
console.log(res);
|
||||
if (res.code == 200) {
|
||||
$message.success("验证码发送成功");
|
||||
$message.success(t("login.codeSuccess"));
|
||||
let countDown = 60;
|
||||
captchaDisabled.value = true;
|
||||
captchaTimeOut.value = setInterval(() => {
|
||||
@@ -243,12 +237,12 @@ const getCaptcha = (data) => {
|
||||
captchaText.value = countDown + "s";
|
||||
if (countDown === 0) {
|
||||
clearInterval(captchaTimeOut.value);
|
||||
captchaText.value = "重新获取";
|
||||
captchaText.value = t("login.getCodeAgain");
|
||||
captchaDisabled.value = false;
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
$message.error("验证码发送失败,请重试");
|
||||
$message.error(t("login.codeError"));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -265,24 +259,39 @@ const phoneLogin = (e) => {
|
||||
phoneFormRef.value?.validate((errors) => {
|
||||
if (!errors) {
|
||||
console.log("通过");
|
||||
verifyCaptcha(
|
||||
phoneFormData._value.phone,
|
||||
phoneFormData._value.captcha
|
||||
).then((res) => {
|
||||
console.log(res);
|
||||
if (res.code == 200) {
|
||||
toLogin(
|
||||
phoneFormData._value.phone,
|
||||
phoneFormData._value.captcha
|
||||
).then((res) => {
|
||||
console.log(res);
|
||||
// 暂时不支持,等支持了再写
|
||||
});
|
||||
}
|
||||
});
|
||||
verifyCaptcha(phoneFormData._value.phone, phoneFormData._value.captcha)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
if (res.code == 200) {
|
||||
toLogin(
|
||||
phoneFormData._value.phone,
|
||||
phoneFormData._value.captcha
|
||||
).then((res) => {
|
||||
console.log(res);
|
||||
if (res.profile) {
|
||||
saveLoginData(res);
|
||||
user.setUserData(res.profile);
|
||||
user.userLogin = true;
|
||||
$message.success(t("login.loginStatus4"));
|
||||
// 自动签到
|
||||
if ($signIn) $signIn();
|
||||
router.push("/user");
|
||||
} else {
|
||||
user.userLogOut();
|
||||
$message.error(t("login.loginStatus5"));
|
||||
phoneFormData.value.captcha = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
$loadingBar.error();
|
||||
$message.error(t("login.loginStatus5"));
|
||||
});
|
||||
} else {
|
||||
$loadingBar.error();
|
||||
$message.error("请检查您的输入");
|
||||
$message.error(t("general.message.needCheck"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ import { fileURLToPath, URL } from "node:url";
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import { NaiveUiResolver } from "unplugin-vue-components/resolvers";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
import { createHtmlPlugin } from "vite-plugin-html";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import viteCompression from "vite-plugin-compression";
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
@@ -29,21 +28,6 @@ export default ({ mode }) =>
|
||||
Components({
|
||||
resolvers: [NaiveUiResolver()],
|
||||
}),
|
||||
createHtmlPlugin({
|
||||
minify: true,
|
||||
template: "index.html",
|
||||
inject: {
|
||||
data: {
|
||||
logo: loadEnv(mode, process.cwd()).VITE_SITE_LOGO,
|
||||
appleLogo: loadEnv(mode, process.cwd()).VITE_SITE_APPLE_LOGO,
|
||||
title: loadEnv(mode, process.cwd()).VITE_SITE_TITLE,
|
||||
author: loadEnv(mode, process.cwd()).VITE_SITE_ANTHOR,
|
||||
keywords: loadEnv(mode, process.cwd()).VITE_SITE_KEYWORDS,
|
||||
description: loadEnv(mode, process.cwd()).VITE_SITE_DES,
|
||||
tongji: loadEnv(mode, process.cwd()).VITE_SITE_BAIDUTONGJI,
|
||||
},
|
||||
},
|
||||
}),
|
||||
// PWA
|
||||
VitePWA({
|
||||
registerType: "autoUpdate",
|
||||
|
||||
Reference in New Issue
Block a user