mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-01 05:27:22 +08:00
添加登录
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
// /login/qr/key
|
||||||
|
export function getQrKey() {
|
||||||
|
return request.get("/login/qr/key");
|
||||||
|
}
|
||||||
|
|
||||||
|
// /login/qr/create
|
||||||
|
export function createQr(key: any) {
|
||||||
|
return request.get("/login/qr/create", { params: { key: key, qrimg: true } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// /login/qr/check
|
||||||
|
export function checkQr(key: any) {
|
||||||
|
return request.get("/login/qr/check", { params: { key: key } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// /login/status
|
||||||
|
export function getLoginStatus() {
|
||||||
|
return request.get("/login/status");
|
||||||
|
}
|
||||||
|
|
||||||
|
// /user/account
|
||||||
|
export function getUserDetail() {
|
||||||
|
return request.get("/user/account");
|
||||||
|
}
|
||||||
@@ -52,8 +52,6 @@ const props = defineProps({
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const path = ref(route.path);
|
const path = ref(route.path);
|
||||||
watch(() => route.path, async newParams => {
|
watch(() => route.path, async newParams => {
|
||||||
console.log(newParams);
|
|
||||||
|
|
||||||
path.value = newParams
|
path.value = newParams
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -15,39 +15,59 @@
|
|||||||
</n-input>
|
</n-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-box">
|
<div class="user-box">
|
||||||
<n-popselect v-model:value="value" :options="options" trigger="click" size="small">
|
<n-dropdown trigger="hover" @select="selectItem" :options="options">
|
||||||
<i class="iconfont icon-xiasanjiaoxing"></i>
|
<i class="iconfont icon-xiasanjiaoxing"></i>
|
||||||
</n-popselect>
|
</n-dropdown>
|
||||||
<n-avatar
|
<n-avatar
|
||||||
class="ml-2"
|
class="ml-2 cursor-pointer"
|
||||||
|
circle
|
||||||
|
size="large"
|
||||||
|
:src="store.state.user.avatarUrl"
|
||||||
|
v-if="store.state.user"
|
||||||
|
/>
|
||||||
|
<n-avatar
|
||||||
|
class="ml-2 cursor-pointer"
|
||||||
circle
|
circle
|
||||||
size="large"
|
size="large"
|
||||||
src="https://picsum.photos/200/300?random=1"
|
src="https://picsum.photos/200/300?random=1"
|
||||||
/>
|
@click="toLogin()"
|
||||||
|
v-else
|
||||||
|
>登录</n-avatar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { getSearchKeyword, getHotSearch } from '@/api/home';
|
import { getSearchKeyword, getHotSearch } from '@/api/home';
|
||||||
|
import { getUserDetail } from '@/api/login';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
// 推荐热搜词
|
// 推荐热搜词
|
||||||
const hotSearchKeyword = ref("搜索点什么吧...")
|
const hotSearchKeyword = ref("搜索点什么吧...")
|
||||||
const loadHotSearchKeyword = async () => {
|
const loadHotSearchKeyword = async () => {
|
||||||
const { data } = await getSearchKeyword();
|
const { data } = await getSearchKeyword();
|
||||||
hotSearchKeyword.value = data.data.showKeyword
|
hotSearchKeyword.value = data.data.showKeyword
|
||||||
}
|
}
|
||||||
|
const loadPage = async () => {
|
||||||
|
const { data } = await getUserDetail()
|
||||||
|
store.state.user = data.profile
|
||||||
|
}
|
||||||
|
|
||||||
|
const toLogin = () => {
|
||||||
|
router.push('/login')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 页面初始化
|
// 页面初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadHotSearchKeyword()
|
loadHotSearchKeyword()
|
||||||
|
loadPage()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -72,18 +92,27 @@ const value = 'Drive My Car'
|
|||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
label: 'Girl',
|
label: 'Girl',
|
||||||
value: 'Girl'
|
key: 'Girl'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'In My Life',
|
label: 'In My Life',
|
||||||
value: 'In My Life'
|
key: 'In My Life'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Wait',
|
label: '退出登录',
|
||||||
value: 'Wait'
|
key: 'logout'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const selectItem = (key: any) => {
|
||||||
|
// switch 判断
|
||||||
|
switch (key) {
|
||||||
|
case 'logout':
|
||||||
|
store.state.user = null
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
+12
-1
@@ -2,11 +2,22 @@ import { createRouter, createWebHistory } from "vue-router";
|
|||||||
import AppLayout from "@/layout/AppLayout.vue";
|
import AppLayout from "@/layout/AppLayout.vue";
|
||||||
import homeRouter from "@/router/home";
|
import homeRouter from "@/router/home";
|
||||||
|
|
||||||
|
let loginRouter = {
|
||||||
|
path: "/login",
|
||||||
|
name: "login",
|
||||||
|
mate: {
|
||||||
|
keepAlive: true,
|
||||||
|
title: "登录",
|
||||||
|
icon: "icon-Home",
|
||||||
|
},
|
||||||
|
component: () => import("@/views/login/index.vue"),
|
||||||
|
};
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
component: AppLayout,
|
component: AppLayout,
|
||||||
children: homeRouter,
|
children: [...homeRouter, loginRouter],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ let state = {
|
|||||||
isPlay: false,
|
isPlay: false,
|
||||||
playMusic: {} as SongResult,
|
playMusic: {} as SongResult,
|
||||||
playMusicUrl: "",
|
playMusicUrl: "",
|
||||||
|
user: null as any,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mutations = {
|
let mutations = {
|
||||||
|
|||||||
@@ -21,3 +21,43 @@ export const secondToMinute = (s: number) => {
|
|||||||
second > 9 ? second.toString() : "0" + second.toString();
|
second > 9 ? second.toString() : "0" + second.toString();
|
||||||
return minuteStr + ":" + secondStr;
|
return minuteStr + ":" + secondStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const cookie = {
|
||||||
|
/**
|
||||||
|
* @name: 设置cookie值
|
||||||
|
* @param: cname string cookie名称
|
||||||
|
* @param: cvalue any cookie值
|
||||||
|
* @param: exdays number cookie保存天数
|
||||||
|
*/
|
||||||
|
setCookie(cname: string, cvalue: any, exdays = 720) {
|
||||||
|
var d = new Date();
|
||||||
|
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
|
||||||
|
var expires = "expires=" + d.toUTCString();
|
||||||
|
document.cookie = cname + "=" + cvalue + "; " + expires;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @name: 获取cookie值
|
||||||
|
*/
|
||||||
|
getCookie(cname: string) {
|
||||||
|
var name = cname + "=";
|
||||||
|
var ca = document.cookie.split(";");
|
||||||
|
for (var i = 0; i < ca.length; i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0) == " ") c = c.substring(1);
|
||||||
|
if (c.indexOf(name) != -1) {
|
||||||
|
return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @name: 清除cookie值
|
||||||
|
* @param: cname string cookie名称
|
||||||
|
*/
|
||||||
|
clearCookie(cname: string) {
|
||||||
|
var d = new Date();
|
||||||
|
d.setTime(-1);
|
||||||
|
var expires = "expires=" + d.toUTCString();
|
||||||
|
document.cookie = cname + "=''; " + expires;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,4 +5,28 @@ const request = axios.create({
|
|||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 请求拦截器
|
||||||
|
request.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// 在请求发送之前做一些处理
|
||||||
|
// 在get请求params中添加timestamp
|
||||||
|
if (config.method === "get") {
|
||||||
|
config.params = {
|
||||||
|
...config.params,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
let token = localStorage.getItem("token");
|
||||||
|
if (token) {
|
||||||
|
config.params.cookie = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
// 当请求异常时做一些处理
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default request;
|
export default request;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ const selectRecommendItem = async (item: IRecommendItem) => {
|
|||||||
showMusic.value = true
|
showMusic.value = true
|
||||||
recommendItem.value = item
|
recommendItem.value = item
|
||||||
listDetail.value = data
|
listDetail.value = data
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
const closeMusic = () => {
|
const closeMusic = () => {
|
||||||
@@ -96,7 +95,7 @@ const formatDetail = computed(() => (detail: any) => {
|
|||||||
<div
|
<div
|
||||||
v-for="(item, index) in listDetail?.playlist.tracks"
|
v-for="(item, index) in listDetail?.playlist.tracks"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:class="setAnimationClass('animate__bounceInRight')"
|
:class="setAnimationClass('animate__bounceInUp')"
|
||||||
:style="setAnimationDelay(index, 100)"
|
:style="setAnimationDelay(index, 100)"
|
||||||
>
|
>
|
||||||
<SongItem :item="formatDetail(item)" />
|
<SongItem :item="formatDetail(item)" />
|
||||||
@@ -121,6 +120,7 @@ const formatDetail = computed(() => (detail: any) => {
|
|||||||
|
|
||||||
&-list {
|
&-list {
|
||||||
@apply flex flex-wrap;
|
@apply flex flex-wrap;
|
||||||
|
padding-bottom: 100px;
|
||||||
}
|
}
|
||||||
&-item {
|
&-item {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { getQrKey, createQr, checkQr, getLoginStatus } from '@/api/login'
|
||||||
|
import { onMounted } from '@vue/runtime-core';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
const qrUrl = ref<string>()
|
||||||
|
onMounted(() => {
|
||||||
|
loadLogin()
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadLogin = async () => {
|
||||||
|
const qrKey = await getQrKey()
|
||||||
|
const key = qrKey.data.data.unikey
|
||||||
|
const { data } = await createQr(key)
|
||||||
|
qrUrl.value = data.data.qrimg
|
||||||
|
timerIsQr(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
const timerIsQr = (key: string) => {
|
||||||
|
const timer = setInterval(async () => {
|
||||||
|
const { data } = await checkQr(key)
|
||||||
|
if (data.code === 800) {
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
if (data.code === 803) {
|
||||||
|
// 将token存入localStorage
|
||||||
|
localStorage.setItem('token', data.cookie)
|
||||||
|
await getLoginStatus().then(res => {
|
||||||
|
console.log(res);
|
||||||
|
})
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="login-page">
|
||||||
|
<div>登录</div>
|
||||||
|
<div>
|
||||||
|
<img :src="qrUrl" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.login-page {
|
||||||
|
@apply p-4;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user