math/ui/src/components/users/UserPanel.vue

138 lines
3.8 KiB
Vue

<template>
<v-card title="用户信息面板" max-width="80%">
<v-card-item>
<v-chip class="ma-2" color="primary" label>
<v-icon icon="mdi-account-circle-outline" start></v-icon>
用户 ID: {{ userId }}
</v-chip>
<v-chip class="ma-2" color="pink" label @click="updateUserPermission">
<v-icon icon="mdi-human" start></v-icon>
权限: {{ userPermissionReadable }}
</v-chip>
</v-card-item>
<v-card-item>
<v-chip class="chips" color="orange" @click="logout">
退出登录
</v-chip>
<v-chip class="chips" color="blue" @click="dialogRepasswdShow = true">
修改密码
</v-chip>
<v-chip class="chips" color="red" @click="dialogDeleteAccountShow = true">
删除账号
</v-chip>
</v-card-item>
<v-card-item v-if="userPermission == '1'">
<v-chip class="chips" color="blue" @click="dialogRepasswd2Show = true">
修改学生账号的密码
</v-chip>
</v-card-item>
</v-card>
<v-dialog v-model="dialogShow" width="auto">
<v-card max-width="400" prepend-icon="mdi-update" :text="dialogText" :title="dialogTitle">
<template v-slot:actions>
<v-btn class="ms-auto" text="Ok" @click="dialogShow = false, dialogClose()"></v-btn>
</template>
</v-card>
</v-dialog>
<RepasswdDialog v-model="dialogRepasswdShow"></RepasswdDialog>
<Repasswd2Dialog v-model="dialogRepasswd2Show"></Repasswd2Dialog>
<DeleteAccountDialog v-model="dialogDeleteAccountShow"></DeleteAccountDialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { useAuthStore } from '@/store/auth';
import { jwtDecode, type JwtPayload } from 'jwt-decode';
import axios, { AxiosError } from 'axios';
import DeleteAccountDialog from './DeleteAccountDialog.vue';
import RepasswdDialog from './RepasswdDialog.vue';
import Repasswd2Dialog from './Repasswd2Dialog.vue';
const dialogShow = ref(false);
const dialogTitle = ref('');
const dialogText = ref('');
const dialogClose = ref(() => { });
const dialogDeleteAccountShow = ref(false);
const dialogRepasswdShow = ref(false);
const dialogRepasswd2Show = ref(false);
const dialog = (title: string, text: string) => {
dialogTitle.value = title;
dialogText.value = text;
dialogShow.value = true;
return new Promise(res => {
dialogClose.value = res as () => void;
});
};
const reveal = ref(false);
interface KqmJwt extends JwtPayload {
user_id: string;
};
const authStore = useAuthStore();
const token = ref(authStore.token);
const userId = computed(() => {
if (token.value != '') {
let data: KqmJwt = jwtDecode(token.value);
return data.user_id;
}
return '';
});
type UserPermissionResponse = { success?: string, permission?: string, error?: string };
const queryPermission = async () => {
try {
const formData = new FormData;
formData.append("user_id", userId.value);
let res = await axios.post('/api/auth/permission', formData);
return res.data as UserPermissionResponse;
} catch (e) {
let ex = e as AxiosError;
return ex.response?.data as UserPermissionResponse;
}
}
const userPermission = ref('');
const updateUserPermission = async () => {
let res = await queryPermission();
if (res?.success) {
userPermission.value = res.permission as string;
} else {
userPermission.value = '';
}
}
watch(userId, updateUserPermission, { immediate: true });
const userPermissionReadable = computed(() => {
if (userPermission.value.length > 0) {
if (userPermission.value == '1') {
return '老师';
} else if (userPermission.value == '2') {
return '学生';
} else {
return '未知';
}
} else {
return '获取失败';
}
})
const logout = async () => {
authStore.clearToken();
}
</script>
<style lang="scss" scoped>
.chips {
margin: 5px;
}
</style>