권한부여

This commit is contained in:
dyhj625 2025-03-14 13:58:15 +09:00
parent 89b5a330d7
commit 236928f1da
4 changed files with 170 additions and 24 deletions

View File

@ -87,27 +87,6 @@ profilePath && profilePath.trim() ? `${baseUrl}upload/img/profile/${profilePath}
const setDefaultImage = (event) => (event.target.src = defaultProfile);
const showImage = (event) => (event.target.style.visibility = "visible");
//
const profileSize = computed(() => {
const totalUsers = userList.value.length;
if (windowWidth.value >= 1850) {
if (totalUsers <= 10) return "80px";
if (totalUsers <= 15) return "60px";
return "45px";
} else if (windowWidth.value >= 1500) {
if (totalUsers <= 10) return "60px";
if (totalUsers <= 15) return "40px";
return "30px";
} else if (windowWidth.value >= 900) {
if (totalUsers <= 10) return "48px";
if (totalUsers <= 15) return "30px";
return "20px";
} else {
return "35px";
}
});
const getDynamicStyle = (user) => ({
borderWidth: "3px",
borderColor: user.usercolor || "#ccc",

View File

@ -74,6 +74,12 @@
<div class="text-truncate">Commuters</div>
</RouterLink>
</li>
<li class="menu-item" :class="$route.path.includes('/authorization') ? 'active' : ''">
<RouterLink class="menu-link" to="/authorization">
<i class="menu-icon icon-base bx bx-user-check"></i>
<div class="text-truncate">Authorization</div>
</RouterLink>
</li>
<!-- <li class="menu-item" :class="$route.path.includes('/sample') ? 'active' : ''">
<RouterLink class="menu-link" to="/sample"> <i class="bi "></i>
<i class="menu-icon tf-icons bx bx-calendar"></i>

View File

@ -1,7 +1,6 @@
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@s/useAuthStore';
// 초기 렌더링 속도를 위해 지연 로딩 사용
const routes = [
{
@ -85,8 +84,8 @@ const routes = [
component: () => import('@v/commuters/TheCommuters.vue'),
},
{
path: '/sample',
component: () => import('@c/calendar/SampleCalendar.vue'),
path: '/authorization',
component: () => import('@v/admin/TheAuthorization.vue'),
},
{
path: "/:anything(.*)",

View File

@ -0,0 +1,162 @@
<template>
<div class="container text-center flex-grow-1 container-p-y">
<div class="card">
<div class="card-header d-flex flex-column">
<h3>관리자 권한 부여</h3>
<div class="user-card-container">
<div v-for="user in users" :key="user.id" class="user-card">
<!-- 프로필 사진 -->
<img :src="getProfileImage(user.photo)" class="profile-img" alt="프로필 사진" @error="setDefaultImage" />
<!-- 사용자 정보 -->
<div class="user-info">
<h5>{{ user.name }}</h5>
</div>
<!-- 권한 토글 버튼 -->
<label class="switch">
<input type="checkbox" :checked="user.isAdmin" @change="toggleAdmin(user)" />
<span class="slider round"></span>
</label>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import axios from '@api';
import { useToastStore } from '@s/toastStore';
const users = ref([]);
const toastStore = useToastStore();
const baseUrl = axios.defaults.baseURL.replace(/api\/$/, "");
const defaultProfile = "/img/icons/icon.png";
//
async function fetchUsers() {
try {
const response = await axios.get('admin/users'); // API
// API
if (!response.data || !Array.isArray(response.data.data)) {
throw new Error("올바른 데이터 형식이 아닙니다.");
}
// ( )
users.value = response.data.data.map(user => ({
id: user.MEMBERSEQ,
name: user.MEMBERNAM,
photo: user.MEMBERPRF ? `${baseUrl}upload/img/profile/${user.MEMBERPRF}` : defaultProfile,
color: user.MEMBERCOL,
isAdmin: user.MEMBERROL === 'ROLE_ADMIN',
}));
} catch (error) {
console.error('사용자 목록을 불러오는 중 오류 발생:', error);
toastStore.onToast('사용자 목록을 불러오지 못했습니다.', 'e');
}
}
//
function getProfileImage(photo) {
return photo || defaultProfile;
}
//
function setDefaultImage(event) {
event.target.src = defaultProfile;
}
//
async function toggleAdmin(user) {
const requestData = {
id: user.id,
role: user.isAdmin ? 'USER' : 'ADMIN'
};
try {
const response = await axios.put('admin/role', requestData); // API
if (response.status === 200) {
user.isAdmin = !user.isAdmin;
toastStore.onToast(`'${user.name}'의 권한이 '${requestData.role}'(으)로 변경되었습니다.`, 's');
} else {
throw new Error('권한 변경 실패');
}
} catch (error) {
console.error('권한 변경 중 오류 발생:', error);
toastStore.onToast('권한 변경에 실패했습니다.', 'e');
}
}
onMounted(fetchUsers);
</script>
<style scoped>
.user-card-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
margin-top: 20px;
}
.user-card {
width: 200px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 10px;
background-color: #fff;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.profile-img {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
margin-bottom: 10px;
}
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
margin-top: 5px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 4px;
bottom: 3px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #4CAF50;
}
input:checked + .slider:before {
transform: translateX(24px);
}
</style>