Skip to content

Commit

Permalink
Feat: user info page
Browse files Browse the repository at this point in the history
  • Loading branch information
LazyCreeper committed Oct 30, 2023
1 parent 4908304 commit 427d493
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 65 deletions.
4 changes: 4 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ declare module 'vue' {
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
Expand All @@ -26,6 +28,8 @@ declare module 'vue' {
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
Github: typeof import('./src/components/icons/Github.vue')['default']
Header: typeof import('./src/components/Header.vue')['default']
Expand Down
13 changes: 11 additions & 2 deletions src/assets/global.less
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ a {
}

.card-body {
@apply px-5;
@apply px-5 pb-5;
}

.card-footer {
@apply p-5 flex justify-end;
@apply px-5 pb-5 flex justify-end;
}
}

Expand All @@ -179,6 +179,15 @@ a {
margin-bottom: 0 !important;
}

// Tabs
.tabs {
@apply text-gray-800 dark:text-gray-400;
.active-tab {
@apply text-sky-400;
border-bottom: 3px solid #38bdf8;
}
}

@media (max-width: 640px) {
.el-main {
padding: 0 !important;
Expand Down
35 changes: 3 additions & 32 deletions src/components/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ import { ref, computed } from "vue";
import { RouterLink } from "vue-router";
import { roomStore } from "@/stores/room";
import DarkModeSwitcher from "@/components/DarkModeSwitcher.vue";
import UserInfo from "./UserInfo.vue";
import { ElNotification } from "element-plus";
import router from "@/router";
import { logOutApi } from "@/services/apis/auth";
const room = roomStore();
const mobileMenu = ref(false);
Expand Down Expand Up @@ -50,34 +47,8 @@ const menuLinks = computed(() => {
return basicLinks.concat(links);
});
const logout = async () => {
const { execute, state } = logOutApi();
try {
await execute({
headers: {
Authorization: localStorage.userToken
}
});
if (state.value) {
localStorage.removeItem("userToken");
for (const i in localStorage) {
if (i.startsWith("room") && i.endsWith("token")) {
localStorage.removeItem(i);
}
}
ElNotification({
title: "登出成功",
type: "success"
});
setTimeout(() => (window.location.href = "./"), 1000);
}
} catch (err: any) {
console.error(err);
ElNotification({
title: "登出失败",
type: err.response.data.error || err.message
});
}
const toUserInfo = () => {
router.replace("/user/me");
};
</script>
<template>
Expand Down Expand Up @@ -122,7 +93,7 @@ const logout = async () => {
</div>
<div class="hidden lg:flex lg:flex-1 lg:justify-end">
<DarkModeSwitcher />
<PersonIcon v-if="room.login" class="ml-4 cursor-pointer" @click="logout" />
<PersonIcon v-if="room.login" class="ml-4 cursor-pointer" @click="toUserInfo" />
</div>
</nav>

Expand Down
35 changes: 12 additions & 23 deletions src/components/RoomList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import type { RoomList } from "@/types/Room";
import JoinRoom from "@/views/JoinRoom.vue";
import { roomStore } from "@/stores/room";
const isMyRoom = ref(false);
const props = defineProps<{
isMyRoom: boolean;
}>();
// const isMyRoom = ref(false);
const __roomList = ref<RoomList[]>([]);
const JoinRoomDialog = ref(false);
const formData = ref<{
Expand Down Expand Up @@ -35,7 +38,7 @@ const sort = ref("desc");
const getRoomList = async (showMsg = false) => {
__roomList.value = [];
try {
if (isMyRoom.value) {
if (props.isMyRoom) {
await reqMyRoomList({
params: {
page: currentPage.value,
Expand All @@ -62,7 +65,7 @@ const getRoomList = async (showMsg = false) => {
});
}
if (isMyRoom.value) {
if (props.isMyRoom) {
if (myRoomList_.value && myRoomList_.value.list) {
totalItems.value = myRoomList_.value.total;
for (let i = 0; i < myRoomList_.value.list.length; i++) {
Expand Down Expand Up @@ -102,32 +105,18 @@ onMounted(() => {
<div class="card mx-auto">
<div class="card-title flex flex-wrap justify-between items-center">
<div class="max-sm:mb-3">
<span
:class="
<!-- :class="
isMyRoom
? ' text-gray-700 cursor-pointer dark:text-slate-400 mr-4'
: 'border-b-2 border-slate-600 border-solid text-slate-700 dark:border-slate-200 dark:text-slate-200 mr-4'
"
@click="
isMyRoom = false;
getRoomList(false);
"
>
房间列表({{ __roomList.length }})</span
>
<span
v-if="roomStore().login"
:class="
" -->
<span v-if="!isMyRoom"> 房间列表({{ __roomList.length }})</span>
<!-- :class="
isMyRoom
? 'border-b-2 border-slate-600 border-solid text-slate-700 dark:border-slate-200 dark:text-slate-200'
: 'text-gray-500 cursor-pointer dark:text-slate-400'
"
@click="
isMyRoom = true;
getRoomList(false);
"
>我创建的({{ __roomList.length }})</span
>
" -->
<span v-else>我创建的({{ __roomList.length }})</span>
</div>
<div class="text-base -my-2">
排序方式:<el-select
Expand Down
5 changes: 0 additions & 5 deletions src/components/UserInfo.vue

This file was deleted.

6 changes: 6 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ const router = createRouter({
name: "search",
component: () => import("../views/SearchPage.vue"),
meta: { title: "搜索" }
},
{
path: "/user/me",
name: "myself",
component: () => import("../views/userInfo.vue"),
meta: { title: "个人信息" }
}
],
scrollBehavior(to, from, savedPosition) {
Expand Down
4 changes: 2 additions & 2 deletions src/stores/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { defineStore } from "pinia";
import type { BaseUserInfo } from "@/types/User";

export const userStore = defineStore("userStore", () => {
const userInfo = ref<BaseUserInfo>();
const info = ref<BaseUserInfo>();

return {
userInfo
info
};
});
2 changes: 1 addition & 1 deletion src/views/Rooms.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import RoomList from "@/components/RoomList.vue";
<template>
<div class="text-center">
<div class="lg:w-9/12 mx-auto">
<RoomList />
<RoomList :is-my-room="false" />
</div>
</div>
</template>
182 changes: 182 additions & 0 deletions src/views/UserInfo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<script setup lang="ts">
import { reactive, ref, type Component, onMounted } from "vue";
import RoomList from "@/components/RoomList.vue";
import { userStore } from "@/stores/user";
import { ElNotification } from "element-plus";
import { logOutApi } from "@/services/apis/auth";
import { userInfo } from "@/services/apis/user";
const user = userStore();
const getUserInfo = async () => {
const { state, execute } = userInfo();
try {
await execute({
headers: {
Authorization: localStorage.userToken
}
});
if (state.value) {
user.info = state.value;
}
} catch (err: any) {
console.error(err);
ElNotification({
title: "错误",
message: err.response.data.error || err.message,
type: "error"
});
}
};
const logout = async () => {
localStorage.removeItem("userToken");
for (const i in localStorage) {
if (i.startsWith("room") && i.endsWith("token")) {
localStorage.removeItem(i);
}
}
ElNotification({
title: "登出成功",
type: "success"
});
setTimeout(() => (window.location.href = "/"), 1000);
};
const logoff = async () => {
const { execute, state } = logOutApi();
try {
await execute({
headers: {
Authorization: localStorage.userToken
}
});
if (state.value) {
localStorage.removeItem("userToken");
for (const i in localStorage) {
if (i.startsWith("room") && i.endsWith("token")) {
localStorage.removeItem(i);
}
}
ElNotification({
title: "注销成功",
type: "success"
});
setTimeout(() => (window.location.href = "/"), 1000);
}
} catch (err: any) {
console.error(err);
ElNotification({
title: "注销失败",
message: err.response.data.error || err.message,
type: "error"
});
}
};
interface Tabs {
name: string;
component: Component;
}
const tabs: Tabs[] = [
{
name: "我的房间",
component: RoomList
}
];
const activeTab = reactive<Tabs>({
name: "我的房间",
component: RoomList
});
const switchTab = (tab: Tabs) => {
activeTab.name = tab.name;
activeTab.component = tab.component;
};
onMounted(() => {
getUserInfo();
});
</script>

<template>
<div class="md:w-9/12 mx-auto">
<el-row :gutter="20">
<el-col :lg="7" :md="9" class="mb-6 max-sm:my-2">
<div class="card mb-6">
<div class="card-title">个人信息</div>
<div class="card-body">
<table>
<tbody></tbody>
<colgroup>
<col width="100" />
</colgroup>
<tbody>
<!-- <tr>
<td>ID</td>
<td>
{{ user.info?.id }}
</td>
</tr> -->
<tr>
<td>用户名</td>
<td>{{ user.info?.username }}</td>
</tr>
<tr>
<td>权限组</td>
<td>
{{ user.info?.role }}
</td>
</tr>
<tr>
<td>注册时间</td>
<td>
{{ user.info && new Date(user.info.createdAt).toLocaleString() }}
</td>
</tr>
<tr v-if="user.info?.role === 'admin'">
<td>后台管理</td>
<td>
<a href="/admin">点击进入</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card">
<div class="card-title">操作</div>
<div class="card-body pb-5">
<el-popconfirm title="确定登出?" @confirm="logout">
<template #reference>
<button class="btn w-full mb-3" @click="">退出登录</button>
</template>
</el-popconfirm>
<el-popconfirm title="注销后,你的所有数据将会被清除" @confirm="logoff">
<template #reference>
<button class="btn btn-error w-full">注销账号</button>
</template>
</el-popconfirm>
</div>
</div>
</el-col>
<el-col :lg="17" :md="15" class="mb-6 max-sm:my-2">
<div class="card mb-6">
<div class="card-title tabs">
<span
v-for="tab in tabs"
:key="tab.name"
class="first:ml-0 last:mr-0 mx-2 cursor-pointer"
:class="activeTab.name === tab.name && 'active-tab'"
@click="switchTab(tab)"
>{{ tab.name }}</span
>
</div>
</div>
<component :is="activeTab.component" :is-my-room="true" />
</el-col>
</el-row>
</div>
</template>

0 comments on commit 427d493

Please sign in to comment.