add permission

This commit is contained in:
Warunee Tamkoo 2024-06-10 20:25:42 +07:00
parent b9b26f18de
commit 2842279165
9 changed files with 101 additions and 433 deletions

View file

@ -49,7 +49,7 @@ const menuList = readonly<any[]>([
activeIcon: "mdi-home-variant",
label: "หน้าแรก",
path: "dashboard",
role: "dashboard",
role: ["SUPER_ADMIN", "ADMIN"],
},
{
key: 2,
@ -57,7 +57,7 @@ const menuList = readonly<any[]>([
activeIcon: "person",
label: "ข้อมูลหลัก",
path: "metadata",
role: "metadata",
role: ["SUPER_ADMIN", "ADMIN"],
children: [
{
key: 2.0,
@ -91,7 +91,7 @@ const menuList = readonly<any[]>([
icon: "mdi-account-badge",
activeIcon: "groups",
label: "จัดการผู้ใช้งานและสิทธิ์",
role: "user_role",
role: ["SUPER_ADMIN", "ADMIN"],
children: [
{
key: 2.0,
@ -115,141 +115,10 @@ const menuList = readonly<any[]>([
icon: "history",
activeIcon: "groups",
label: "ประวัติกิจกรรม (Logs)",
role: "user_role",
path: "viewLogs",
role: ["SUPER_ADMIN", "ADMIN"],
},
]);
const tabList = readonly<tabType[]>([
{
key: 1,
label: "ข้อมูลทั่วไป",
tag: "information",
},
{
key: 19,
label: "ประวัติการเปลี่ยนชื่อ",
tag: "oldName",
},
{
key: 16,
label: "ข้อมูลราชการ",
tag: "government",
},
{
key: 17,
label: "ข้อมูลที่อยู่",
tag: "address",
},
{
key: 18,
label: "ข้อมูลครอบครัว",
tag: "family",
},
{
key: 15,
label: "ใบอนุญาตประกอบวิชาชีพ",
tag: "certicate",
},
{
key: 2,
label: "ประวัติการศึกษา",
tag: "education",
},
{
key: 3,
label: "การฝึกอบรม/ดูงาน",
tag: "training",
},
{
key: 4,
label: "เครื่องราชอิสริยาภรณ์",
tag: "insignia",
},
{
key: 5,
label: "ประกาศเกียรติคุณ",
tag: "coined",
},
{
key: 6,
label: "ผลการประเมินปฏิบัติราชการ",
tag: "assessment",
},
{
key: 7,
label: "ตำแหน่ง/เงินเดือน/ค่าจ้าง",
tag: "position",
},
{
key: 8,
label: "วินัย",
tag: "rule",
},
{
key: 9,
label: "การลา",
tag: "leave",
},
{
key: 10,
label: "ความสามารถพิเศษ",
tag: "talent",
},
{
key: 11,
label: "ปฎิบัติราชการพิเศษ",
tag: "work",
},
{
key: 12,
label: "บันทึกวันที่ไม่ได้รับเงินเดือนฯ",
tag: "record",
},
{
key: 13,
label: "อื่นๆ",
tag: "other",
},
{
key: 14,
label: "เอกสารหลักฐาน",
tag: "document",
},
]);
const tabListPlacement = readonly<tabType[]>([
{
key: 1,
label: "ข้อมูลทั่วไป",
tag: "information",
},
{
key: 2,
label: "ใบอนุญาตประกอบอาชีพ",
tag: "certicate",
},
{
key: 3,
label: "ประวัติการศึกษา",
tag: "education",
},
{
key: 4,
label: "ผลการสอบ",
tag: "examresult",
},
{
key: 5,
label: "การคัดกรองคุณสมบัติ",
tag: "qualification",
},
{
key: 6,
label: "เอกสารหลักฐาน",
tag: "document",
},
]);
export { menuList, tabList, tabListPlacement };
export { menuList };
export type { ScrollType, tabType, menuType, notiType, optionType };

View file

@ -68,7 +68,14 @@ function fetchlistRole() {
.get(config.API.managementRole)
.then((res) => {
const rolesIds = roles.value?.map((e) => e.id);
rows.value = res.data.filter((v: Roles) => !rolesIds?.includes(v.id));
rows.value = res.data.filter(
(v: Roles) =>
!rolesIds?.includes(v.id) &&
(v.name == "USER" ||
v.name == "ADMIN" ||
v.name == "SUPER_ADMIN" ||
v.name == "STAFF")
);
})
.catch((err) => {
messageError($q, err);

View file

@ -2,17 +2,13 @@ const ListsPage = () => import("@/modules/03_logs/views/lists.vue");
export default [
{
path: "/users",
name: "manageUsers",
path: "/lists",
name: "viewLogs",
component: ListsPage,
meta: {
Auth: true,
Key: [7],
Role: "user_role",
Role: ["SUPER_ADMIN", "ADMIN"],
},
},
{
path: "/users/:id",
name: "masterInsignia",
},
];

View file

@ -1 +1,3 @@
<template>
<div>ประวจกรรม (Logs)</div>
</template>

View file

@ -11,7 +11,21 @@ const initOptions = {
const keycloak = Keycloak(initOptions);
keycloak.onAuthSuccess = () => {}; //เพิ่มlogin สำเร็จจะมาทำฟังก์ชันนี้
keycloak.onAuthSuccess = () => {
// check role user
const hasCommonValues = (array1: string[], array2: string[]): boolean => {
return array1.some((element) => array2.includes(element));
};
const role = keycloak.tokenParsed?.role;
const roleSys = ["SUPER_ADMIN", "ADMIN"];
const checkPermission = hasCommonValues(role, roleSys);
if (!checkPermission) {
keycloak.logout({
redirectUri: `${window.location.protocol}//${window.location.host}/`,
});
}
}; //เพิ่มlogin สำเร็จจะมาทำฟังก์ชันนี้
await keycloak.init({ onLoad: "check-sso", checkLoginIframe: false }); //ทำการ connect keycloak
export default keycloak;

View file

@ -6,6 +6,7 @@ const Error404NotFound = () => import("@/views/Error404NotFound.vue");
import ModuleMetadata from "@/modules/01_metadata/router";
import ModuleUser from "@/modules/02_users/router";
import ModuleLogs from "@/modules/03_logs/router";
// TODO: ใช้หรือไม่?
import keycloak from "@/plugins/keycloak";
@ -25,11 +26,12 @@ const router = createRouter({
meta: {
Auth: true,
Key: [7],
Role: "dashboard",
Role: ["SUPER_ADMIN", "ADMIN"],
},
},
...ModuleMetadata,
...ModuleUser,
...ModuleLogs,
],
},
/**
@ -64,17 +66,17 @@ router.beforeEach((to, from, next) => {
});
} else {
// keycloak.updateToken(60);
const role = keycloak.tokenParsed?.role;
// const role = keycloak.tokenParsed?.role;
// console.log("tokenParsed===>", keycloak.tokenParsed?.role);
// console.log("Role===>", to.meta.Role);
// console.log(hasCommonValues(role, to.meta.Role));
// ถ้าเป็นคนกรอกข้อมูล
if (role.includes("keyregistry") && to.meta.Role != "registry") {
next({ path: "/registry" });
} else if (role.includes(to.meta.Role)) {
next();
} else {
next({ path: "" });
// next();
}
// if (role.includes(to.meta.Role)) {
next();
// } else {
// next({ path: "" });
// // next();
// }
}
} else {
next();

View file

@ -2,39 +2,40 @@ import { defineStore } from "pinia";
import { ref } from "vue";
export const useroleUserDataStore = defineStore("roleusers", () => {
const insignia1Role = ref<boolean>(false)
const insignia2Role = ref<boolean>(false)
const caregiverRole = ref<boolean>(false)
const chairmanRole = ref<boolean>(false)
const commanderRole = ref<boolean>(false)
const admin2Role = ref<boolean>(false)
const adminRole = ref<boolean>(false)
const oligarchRole = ref<boolean>(false)
const insignia1Role = ref<boolean>(false);
const insignia2Role = ref<boolean>(false);
const caregiverRole = ref<boolean>(false);
const chairmanRole = ref<boolean>(false);
const commanderRole = ref<boolean>(false);
const admin2Role = ref<boolean>(false);
const adminRole = ref<boolean>(false);
const oligarchRole = ref<boolean>(false);
// const hasCommonValues = (array1: number[], array2: number[]): boolean => {
// return array1.some((element) => array2.includes(element));
// };
const fetchroleUser = async (keycloak: any) => {
if (keycloak != null) {
insignia1Role.value = await keycloak.includes("insignia1");
insignia2Role.value = await keycloak.includes("insignia2");
caregiverRole.value = await keycloak.includes("caregiver");
chairmanRole.value = await keycloak.includes("chairman");
commanderRole.value = await keycloak.includes("commander");
admin2Role.value = await keycloak.includes("admin2");
adminRole.value = await keycloak.includes("admin");
oligarchRole.value = await keycloak.includes("oligarch");
}
const fetchroleUser = async (keycloak: any) => {
if (keycloak != null) {
insignia1Role.value = await keycloak.includes("insignia1");
insignia2Role.value = await keycloak.includes("insignia2");
caregiverRole.value = await keycloak.includes("caregiver");
chairmanRole.value = await keycloak.includes("chairman");
commanderRole.value = await keycloak.includes("commander");
admin2Role.value = await keycloak.includes("admin2");
adminRole.value = await keycloak.includes("admin");
oligarchRole.value = await keycloak.includes("oligarch");
}
};
return {
fetchroleUser,
insignia1Role,
insignia2Role,
caregiverRole,
chairmanRole,
commanderRole,
admin2Role,
adminRole,
};
});
return {
fetchroleUser,
insignia1Role,
insignia2Role,
caregiverRole,
chairmanRole,
commanderRole,
admin2Role,
adminRole,
};
});

View file

@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from "vue";
import keycloak from "@/plugins/keycloak";
import { useRoute, useRouter } from "vue-router";
import { useRoute } from "vue-router";
import { useDataStore } from "@/stores/data";
import { storeToRefs } from "pinia";
import { scroll, useQuasar } from "quasar";
@ -15,17 +15,12 @@ import type {
notiType,
optionType,
} from "../interface/request/main/main";
import {
menuList,
tabList,
tabListPlacement,
} from "../interface/request/main/main";
import { useroleUserDataStore } from "@/stores/roleUser";
import { menuList } from "../interface/request/main/main";
// import { useroleUserDataStore } from "@/stores/roleUser";
const { setVerticalScrollPosition, getVerticalScrollPosition } = scroll;
const { setVerticalScrollPosition } = scroll;
const store = useDataStore();
const route = useRoute();
const router = useRouter();
const link = ref<string>("");
const mixin = useCounterMixin(); //
const {
@ -37,12 +32,12 @@ const {
date2Thai,
dialogConfirm,
} = mixin;
const DataStore = useroleUserDataStore();
const { fetchroleUser } = DataStore;
// const DataStore = useroleUserDataStore();
// const { fetchroleUser } = DataStore;
const id = ref<string>("");
const $q = useQuasar();
const { tabData, loader } = storeToRefs(store);
const { loader } = storeToRefs(store);
const { changeTab } = store;
const miniState = ref<boolean>(false);
const drawerR = ref<boolean>(false);
@ -53,7 +48,6 @@ const drawerL = ref<boolean>(false);
const fullname = ref<string>("");
const role = ref<string[]>([]);
const notiTrigger = ref<boolean>(false);
const text = ref<string>("");
const notiList = ref<notiType[]>([]);
const options = ref<optionType[]>([
@ -127,13 +121,6 @@ const getDataNotification = async (index: number, type: string) => {
.finally(() => {});
};
/**
* ใหแสดง แทปดานขวา เมอเขาหน รายละเอยดทะเบยนประว
*/
const tabScroll = () => {
return route.name == "registryDetail";
};
/**
* toggleBtnRight มย ขยาย drawer ขวา
*/
@ -159,11 +146,8 @@ const toggleBtnLeft = () => {
*/
const onScroll = (scroll: ScrollType) => {
const { position } = scroll;
if (route.name == "PlacementPersonalDetail") {
updateScrollPlacement(position);
} else {
updateScroll(position);
}
updateScroll(position);
};
/**
@ -176,32 +160,7 @@ const updateScroll = (position: number) => {
}
let last;
/**
* วนหา id ของ div
*/
for (const i in tabList) {
const section = tabList[i];
const item = document.getElementById(section.tag);
/**
* วนหา id ของ div หนาน
* เมอหาไมเจอใหไปตอตวตอไป
* เมอเจอแล ให ตำแหนงบนสดของ div มากกวาหรอเทาก ตำแหน top scroll บวกก แทปดานบน 155
* last เป undifind ให last เทาก tag แล หยดล
* าไมใช undifind ให last เทาก tag แล ปหาต กรณ div นยาว
*/
if (item === null) {
continue;
}
if (item.offsetTop >= position + 155) {
if (last === void 0) {
last = section.tag;
}
break;
} else {
last = section.tag;
}
}
/**
* last ไมเทาก undifind
* ใช เซ active ใหเปนแทปส
@ -230,9 +189,9 @@ const activeBtn = () => {
* งจ boolean งตอง set
*/
onMounted(async () => {
if (keycloak.tokenParsed) {
await fetchroleUser(keycloak.tokenParsed.role);
}
// if (keycloak.tokenParsed) {
// await fetchroleUser(keycloak.tokenParsed.role);
// }
await fetchmsgNoread();
// await getDataNotification(1, "NOMAL");
myEventHandler(null, false);
@ -288,119 +247,10 @@ const myEventHandler = (e: any, setSCroll: boolean) => {
* @param path string
*/
const activeMenu = (path: string) => {
// if (path == "dashboard" && route.fullPath == "/") return true;
// if (path == "registry" && route.fullPath == "/registry-employee")
// return false;
// if (path == "registry" && route.fullPath.includes(`/registry-employee/edit`))
// return false;
// if (path == "registry" && route.fullPath.includes(`/registry-employee/add`))
// return false;
// if (path == "registry" && route.fullPath == "/") return false;
// if (path != "registry" && path == "registryEmployee" && route.fullPath == "/registryEmployee") return true;
// const bool = route.fullPath.includes(`/${path}`) || route.name === path;
const bool = route.name === path;
return bool;
};
/**
* เปนฟงกนทนตลอด เพอให active ตรงตามเงอนไขใหเป true
* @param tag string เปนชอของ วนนๆ
*/
const activeTab = (tag: string) => {
return tabData.value == tag;
};
/**
* คลกเพอให router หร scroll ไปยงตำแหนงนนๆ
* @param tag string เปนชอของ วนนๆ
*/
const tagClick = (tag: string) => {
const hash = `#${tag}`;
const items = document.getElementById(tag);
const offset = Math.max(0, items == null ? 0 : items.offsetTop - 84);
// router.replace({ hash });
if (route.hash !== hash) {
const check = activeBtn();
if (check) {
// router.replace({ hash, position: { x: 0, y: 0 } });
// router.replace({ hash }).then(() => {
// setVerticalScrollPosition(window, offset, 300);
// });
drawerR.value = !drawerR.value;
setVerticalScrollPosition(window, offset, 300);
} else {
setVerticalScrollPosition(window, offset, 300);
}
} else {
setVerticalScrollPosition(window, offset, 300);
}
};
//**** Tab Right ****\\
const tabScrollPlacement = () => {
return route.name == "PlacementPersonalDetail";
};
const updateScrollPlacement = (position: number) => {
if (position === void 0) {
position = document.documentElement.scrollTop || document.body.scrollTop;
}
let last;
for (const i in tabListPlacement) {
const section = tabListPlacement[i];
const item = document.getElementById(section.tag);
if (item === null) {
continue;
}
if (item.offsetTop >= position + 100) {
if (last === void 0) {
last = section.tag;
}
break;
} else {
last = section.tag;
}
}
if (last !== void 0) {
changeTab(last);
const tocEl = document.getElementById("tab--" + last);
if (tocEl) {
tocEl.scrollIntoView({ block: "nearest" });
}
}
};
const activeBtnPlacement = () => {
return route.name == "PlacementPersonalDetail" && rightActive.value;
};
const activeTabPlacement = (tag: string) => {
return tabData.value == tag;
};
const tagClickPlacement = (tag: string) => {
const hash = `#${tag}`;
const items = document.getElementById(tag);
const offset = Math.max(0, items == null ? 0 : items.offsetTop + 50);
// router.replace({ hash });
if (route.hash !== hash) {
const checkPlacement = activeBtnPlacement();
if (checkPlacement) {
drawerR.value = !drawerR.value;
setVerticalScrollPosition(window, offset, 300);
} else {
setVerticalScrollPosition(window, offset, 300);
}
} else {
setVerticalScrollPosition(window, offset, 300);
}
};
//**** End Tab Right ****\\
/**
* logout keycloak
@ -419,6 +269,8 @@ const doLogout = () => {
* งชอผใชงานจาก keycloak
*/
if (keycloak.tokenParsed != null) {
console.log("tokenParsed===>", keycloak.tokenParsed);
fullname.value = keycloak.tokenParsed.name;
role.value = keycloak.tokenParsed.role;
}
@ -445,7 +297,6 @@ const clickDelete = async (id: string, index: number) => {
const totalInbox = ref<number>(0);
const totalNoti = ref<number>(0);
const round = ref<number>(0);
const page = ref<number>(0);
function onLoad(index: any, done: any) {
@ -687,7 +538,7 @@ watch(
<q-btn
size="13px"
class="bg-blue-1"
v-if="activeBtn() || activeBtnPlacement()"
v-if="activeBtn()"
flat
dense
round
@ -725,7 +576,8 @@ watch(
<!-- เมนอย ตอนย -->
<q-list padding>
<div v-for="(menuItem, index) in menuList" :key="index">
<div v-if="role.includes(menuItem.role)">
<!-- v-if="role.includes(menuItem.role)" -->
<div>
<q-item
clickable
v-ripple
@ -910,7 +762,8 @@ watch(
<q-list padding>
<div v-for="(menuItem, index) in menuList" :key="index">
<!-- เมนอย -->
<div v-if="role.includes(menuItem.role)">
<!-- v-if="role.includes(menuItem.role)" -->
<div>
<q-expansion-item
group="somegroup"
class="menuSub"
@ -1048,83 +901,6 @@ watch(
</q-scroll-area>
</q-drawer>
<!-- drawer page registry/:id -->
<q-drawer
side="right"
class="bg-grey-2"
show-if-above
v-if="tabScroll()"
v-model="drawerR"
:width="220"
:breakpoint="1023"
>
<q-scroll-area class="fit">
<q-list padding>
<q-item
v-for="(tabItem, index) in tabList"
:key="index"
:id="'tab--' + tabItem.tag"
class="tabNative"
active-class="text-blue-7 active-item text-weight-medium tabActive"
:active="activeTab(tabItem.tag)"
clickable
v-ripple
dense
exact
@click="tagClick(tabItem.tag)"
>
<q-item-section>
<q-item-label
><q-icon size="11px" name="mdi-circle-medium" /><span
class="q-pl-xs"
>{{ tabItem.label }}</span
></q-item-label
>
</q-item-section>
</q-item>
</q-list>
</q-scroll-area>
</q-drawer>
<!-- drawer page placement2/detail/:id -->
<q-drawer
side="right"
class="bg-grey-2"
show-if-above
v-if="tabScrollPlacement()"
v-model="drawerR"
:width="220"
:breakpoint="1023"
>
<q-scroll-area class="fit">
<q-list padding>
<q-item
v-for="(tabItem, index) in tabListPlacement"
:key="index"
:id="'tab--' + tabItem.tag"
class="tabNative"
active-class="text-blue-7 active-item text-weight-medium tabActive"
:active="activeTabPlacement(tabItem.tag)"
clickable
v-ripple
dense
exact
@click="tagClickPlacement(tabItem.tag)"
>
<q-item-section>
<q-item-label
><q-icon size="11px" name="mdi-circle-medium" /><span
class="q-pl-xs"
>{{ tabItem.label }}</span
></q-item-label
>
</q-item-section>
</q-item>
</q-list>
</q-scroll-area>
</q-drawer>
<!-- drawer -->
<q-page-container class="bg-grey-2">
<q-page style="padding: 0 2%">
<router-view :key="$route.fullPath" />