권한부여
This commit is contained in:
parent
89b5a330d7
commit
236928f1da
@ -87,27 +87,6 @@ profilePath && profilePath.trim() ? `${baseUrl}upload/img/profile/${profilePath}
|
|||||||
const setDefaultImage = (event) => (event.target.src = defaultProfile);
|
const setDefaultImage = (event) => (event.target.src = defaultProfile);
|
||||||
const showImage = (event) => (event.target.style.visibility = "visible");
|
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) => ({
|
const getDynamicStyle = (user) => ({
|
||||||
borderWidth: "3px",
|
borderWidth: "3px",
|
||||||
borderColor: user.usercolor || "#ccc",
|
borderColor: user.usercolor || "#ccc",
|
||||||
|
|||||||
@ -74,6 +74,12 @@
|
|||||||
<div class="text-truncate">Commuters</div>
|
<div class="text-truncate">Commuters</div>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</li>
|
</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' : ''">
|
<!-- <li class="menu-item" :class="$route.path.includes('/sample') ? 'active' : ''">
|
||||||
<RouterLink class="menu-link" to="/sample"> <i class="bi "></i>
|
<RouterLink class="menu-link" to="/sample"> <i class="bi "></i>
|
||||||
<i class="menu-icon tf-icons bx bx-calendar"></i>
|
<i class="menu-icon tf-icons bx bx-calendar"></i>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { useAuthStore } from '@s/useAuthStore';
|
import { useAuthStore } from '@s/useAuthStore';
|
||||||
|
|
||||||
|
|
||||||
// 초기 렌더링 속도를 위해 지연 로딩 사용
|
// 초기 렌더링 속도를 위해 지연 로딩 사용
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -85,8 +84,8 @@ const routes = [
|
|||||||
component: () => import('@v/commuters/TheCommuters.vue'),
|
component: () => import('@v/commuters/TheCommuters.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sample',
|
path: '/authorization',
|
||||||
component: () => import('@c/calendar/SampleCalendar.vue'),
|
component: () => import('@v/admin/TheAuthorization.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/:anything(.*)",
|
path: "/:anything(.*)",
|
||||||
|
|||||||
162
src/views/admin/TheAuthorization.vue
Normal file
162
src/views/admin/TheAuthorization.vue
Normal 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>
|
||||||
Loading…
Reference in New Issue
Block a user