mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-03 14:20:50 +08:00
添加登录
This commit is contained in:
@@ -27,4 +27,4 @@
|
||||
"vite": "^2.3.8",
|
||||
"vue-tsc": "^0.0.24"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
src/api/login.ts
Normal file
26
src/api/login.ts
Normal file
@@ -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 path = ref(route.path);
|
||||
watch(() => route.path, async newParams => {
|
||||
console.log(newParams);
|
||||
|
||||
path.value = newParams
|
||||
})
|
||||
|
||||
|
||||
@@ -15,39 +15,59 @@
|
||||
</n-input>
|
||||
</div>
|
||||
<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>
|
||||
</n-popselect>
|
||||
</n-dropdown>
|
||||
<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
|
||||
size="large"
|
||||
src="https://picsum.photos/200/300?random=1"
|
||||
/>
|
||||
@click="toLogin()"
|
||||
v-else
|
||||
>登录</n-avatar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getSearchKeyword, getHotSearch } from '@/api/home';
|
||||
import { getUserDetail } from '@/api/login';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
const router = useRouter()
|
||||
const store = useStore();
|
||||
|
||||
// 推荐热搜词
|
||||
const hotSearchKeyword = ref("搜索点什么吧...")
|
||||
const loadHotSearchKeyword = async () => {
|
||||
const { data } = await getSearchKeyword();
|
||||
hotSearchKeyword.value = data.data.showKeyword
|
||||
}
|
||||
const loadPage = async () => {
|
||||
const { data } = await getUserDetail()
|
||||
store.state.user = data.profile
|
||||
}
|
||||
|
||||
|
||||
const toLogin = () => {
|
||||
router.push('/login')
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 页面初始化
|
||||
onMounted(() => {
|
||||
loadHotSearchKeyword()
|
||||
loadPage()
|
||||
})
|
||||
|
||||
|
||||
@@ -72,18 +92,27 @@ const value = 'Drive My Car'
|
||||
const options = [
|
||||
{
|
||||
label: 'Girl',
|
||||
value: 'Girl'
|
||||
key: 'Girl'
|
||||
},
|
||||
{
|
||||
label: 'In My Life',
|
||||
value: 'In My Life'
|
||||
key: 'In My Life'
|
||||
},
|
||||
{
|
||||
label: 'Wait',
|
||||
value: 'Wait'
|
||||
label: '退出登录',
|
||||
key: 'logout'
|
||||
}
|
||||
]
|
||||
|
||||
const selectItem = (key: any) => {
|
||||
// switch 判断
|
||||
switch (key) {
|
||||
case 'logout':
|
||||
store.state.user = null
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -2,11 +2,22 @@ import { createRouter, createWebHistory } from "vue-router";
|
||||
import AppLayout from "@/layout/AppLayout.vue";
|
||||
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 = [
|
||||
{
|
||||
path: "/",
|
||||
component: AppLayout,
|
||||
children: homeRouter,
|
||||
children: [...homeRouter, loginRouter],
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ let state = {
|
||||
isPlay: false,
|
||||
playMusic: {} as SongResult,
|
||||
playMusicUrl: "",
|
||||
user: null as any,
|
||||
};
|
||||
|
||||
let mutations = {
|
||||
|
||||
@@ -21,3 +21,43 @@ export const secondToMinute = (s: number) => {
|
||||
second > 9 ? second.toString() : "0" + second.toString();
|
||||
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,
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
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;
|
||||
|
||||
@@ -22,7 +22,6 @@ const selectRecommendItem = async (item: IRecommendItem) => {
|
||||
showMusic.value = true
|
||||
recommendItem.value = item
|
||||
listDetail.value = data
|
||||
console.log(data);
|
||||
|
||||
}
|
||||
const closeMusic = () => {
|
||||
@@ -96,7 +95,7 @@ const formatDetail = computed(() => (detail: any) => {
|
||||
<div
|
||||
v-for="(item, index) in listDetail?.playlist.tracks"
|
||||
:key="item.id"
|
||||
:class="setAnimationClass('animate__bounceInRight')"
|
||||
:class="setAnimationClass('animate__bounceInUp')"
|
||||
:style="setAnimationDelay(index, 100)"
|
||||
>
|
||||
<SongItem :item="formatDetail(item)" />
|
||||
@@ -121,6 +120,7 @@ const formatDetail = computed(() => (detail: any) => {
|
||||
|
||||
&-list {
|
||||
@apply flex flex-wrap;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
&-item {
|
||||
width: 200px;
|
||||
|
||||
50
src/views/login/index.vue
Normal file
50
src/views/login/index.vue
Normal file
@@ -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