2024-10-18 11:33:04 +07:00
|
|
|
import { Controller, Get, Path, Request, Route, Security, Tags } from "tsoa";
|
2024-07-23 19:06:51 +07:00
|
|
|
import { AppDataSource } from "../database/data-source";
|
|
|
|
|
import { RequestWithUser } from "../middlewares/user";
|
|
|
|
|
import HttpError from "../interfaces/http-error";
|
|
|
|
|
import HttpStatus from "../interfaces/http-status";
|
|
|
|
|
import HttpSuccess from "../interfaces/http-success";
|
|
|
|
|
import { AuthRole } from "../entities/AuthRole";
|
|
|
|
|
import { AuthRoleAttr } from "../entities/AuthRoleAttr";
|
|
|
|
|
import { PosMaster } from "../entities/PosMaster";
|
|
|
|
|
import { Profile } from "../entities/Profile";
|
2024-07-24 15:44:34 +07:00
|
|
|
import { AuthSys } from "../entities/AuthSys";
|
2024-07-25 09:54:44 +07:00
|
|
|
import { promisify } from "util";
|
|
|
|
|
import { In } from "typeorm";
|
2024-08-14 17:27:11 +07:00
|
|
|
import permission from "../interfaces/permission";
|
2024-08-26 22:44:22 +07:00
|
|
|
import { ProfileEmployee } from "../entities/ProfileEmployee";
|
|
|
|
|
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
|
2024-08-27 11:47:03 +07:00
|
|
|
import { OrgRevision } from "../entities/OrgRevision";
|
2026-04-29 14:39:23 +07:00
|
|
|
import { PosMasterAct } from "../entities/PosMasterAct";
|
2026-04-17 14:18:54 +07:00
|
|
|
import { actingPositionService } from "../services/ActingPositionService";
|
2024-07-24 09:42:34 +07:00
|
|
|
const REDIS_HOST = process.env.REDIS_HOST;
|
|
|
|
|
const REDIS_PORT = process.env.REDIS_PORT;
|
2024-07-23 19:06:51 +07:00
|
|
|
|
|
|
|
|
@Route("api/v1/org/permission")
|
|
|
|
|
@Tags("Permission")
|
|
|
|
|
@Security("bearerAuth")
|
|
|
|
|
export class PermissionController extends Controller {
|
|
|
|
|
private profileRepo = AppDataSource.getRepository(Profile);
|
2024-08-26 22:44:22 +07:00
|
|
|
private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee);
|
2024-07-23 19:06:51 +07:00
|
|
|
private posMasterRepository = AppDataSource.getRepository(PosMaster);
|
2024-08-26 22:44:22 +07:00
|
|
|
private posMasterEmpRepository = AppDataSource.getRepository(EmployeePosMaster);
|
2024-07-23 19:06:51 +07:00
|
|
|
private authRoleRepo = AppDataSource.getRepository(AuthRole);
|
|
|
|
|
private authRoleAttrRepo = AppDataSource.getRepository(AuthRoleAttr);
|
2024-07-24 15:44:34 +07:00
|
|
|
private authSysRepo = AppDataSource.getRepository(AuthSys);
|
2024-08-27 11:47:03 +07:00
|
|
|
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
|
2026-04-29 14:39:23 +07:00
|
|
|
private posMasterActRepo = AppDataSource.getRepository(PosMasterAct);
|
2024-07-24 09:42:34 +07:00
|
|
|
private redis = require("redis");
|
2024-07-23 19:06:51 +07:00
|
|
|
|
2025-03-07 12:19:04 +07:00
|
|
|
@Get("")
|
2024-09-06 15:24:56 +07:00
|
|
|
public async getPermission(@Request() request: RequestWithUser) {
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-09-04 17:05:25 +07:00
|
|
|
});
|
|
|
|
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
|
|
|
|
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-07 13:27:27 +07:00
|
|
|
// Query ตำแหน่งรักษาการโดยใช้ service ที่มีอยู่
|
|
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const actingData = await actingPositionService.getActingPositionsWithPrivilege(
|
|
|
|
|
profile.id,
|
|
|
|
|
orgRevision?.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ใช้ cache key ที่รวมสถานะ acting
|
|
|
|
|
const cacheKey = `role_${profile.id}_${actingData.isAct ? 'acting' : 'normal'}`;
|
|
|
|
|
let reply = await getAsync(cacheKey);
|
2024-09-04 17:05:25 +07:00
|
|
|
if (reply != null) {
|
|
|
|
|
reply = JSON.parse(reply);
|
|
|
|
|
} else {
|
|
|
|
|
let posMaster: any = await this.posMasterRepository.findOne({
|
|
|
|
|
select: ["authRoleId"],
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
posMaster = await this.posMasterEmpRepository.findOne({
|
|
|
|
|
select: ["authRoleId"],
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const getDetail = await this.authRoleRepo.findOne({
|
|
|
|
|
select: ["id", "roleName", "roleDescription"],
|
|
|
|
|
where: { id: posMaster.authRoleId },
|
|
|
|
|
});
|
2025-03-06 18:25:27 +07:00
|
|
|
|
2024-09-04 17:05:25 +07:00
|
|
|
if (!getDetail) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const roleAttrData = await this.authRoleAttrRepo.find({
|
|
|
|
|
select: [
|
|
|
|
|
"authSysId",
|
|
|
|
|
"parentNode",
|
|
|
|
|
"attrOwnership",
|
|
|
|
|
"attrIsCreate",
|
|
|
|
|
"attrIsList",
|
|
|
|
|
"attrIsGet",
|
|
|
|
|
"attrIsUpdate",
|
|
|
|
|
"attrIsDelete",
|
|
|
|
|
"attrPrivilege",
|
|
|
|
|
],
|
|
|
|
|
where: { authRoleId: getDetail.id },
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-07 13:27:27 +07:00
|
|
|
// ถ้า User มีตำแหน่งรักษาการ ให้รวมสิทธิ์
|
|
|
|
|
if (actingData.isAct && actingData.posMasterActs.length > 0) {
|
|
|
|
|
// ดึง authRoleId ของทุกตำแหน่งรักษาการ
|
|
|
|
|
const actingAuthRoleIds = await this.posMasterActRepo
|
|
|
|
|
.createQueryBuilder("posMasterAct")
|
|
|
|
|
.leftJoin("posMasterAct.posMaster", "posMaster")
|
|
|
|
|
.select("posMaster.authRoleId", "authRoleId")
|
|
|
|
|
.leftJoin("posMasterAct.posMasterChild", "posMasterChild")
|
|
|
|
|
.leftJoin("posMasterChild.current_holder", "profile")
|
|
|
|
|
.where("profile.id = :profileId", { profileId: profile.id })
|
|
|
|
|
.andWhere("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: orgRevision?.id })
|
|
|
|
|
.getRawMany();
|
|
|
|
|
|
|
|
|
|
// ดึง AuthRoleAttr ทั้งหมดของ acting roles
|
|
|
|
|
const actingRoleIds = actingAuthRoleIds.map(x => x.authRoleId).filter(id => id != null);
|
|
|
|
|
const actingRoleAttrs = await this.authRoleAttrRepo.find({
|
|
|
|
|
select: [
|
|
|
|
|
"authSysId",
|
|
|
|
|
"parentNode",
|
|
|
|
|
"attrOwnership",
|
|
|
|
|
"attrIsCreate",
|
|
|
|
|
"attrIsList",
|
|
|
|
|
"attrIsGet",
|
|
|
|
|
"attrIsUpdate",
|
|
|
|
|
"attrIsDelete",
|
|
|
|
|
"attrPrivilege",
|
|
|
|
|
],
|
|
|
|
|
where: { authRoleId: In(actingRoleIds) as any },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// สร้าง map ของ authSysId -> สิทธิ์ที่ดีที่สุดจาก acting
|
|
|
|
|
const actingPermissionMap = new Map<string, any>();
|
|
|
|
|
|
|
|
|
|
// ลำดับความสำคัญของ privilege (มากไปน้อย)
|
|
|
|
|
const privilegePriority: Record<string, number> = {
|
|
|
|
|
"OWNER": 7,
|
|
|
|
|
"PARENT": 6,
|
|
|
|
|
"ROOT": 5,
|
|
|
|
|
"BROTHER": 4,
|
|
|
|
|
"CHILD": 3,
|
|
|
|
|
"NORMAL": 2,
|
|
|
|
|
"SPECIFIC": 1,
|
|
|
|
|
"null": 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ฟังก์ชันเปรียบเทียบ privilege
|
|
|
|
|
const getHigherPrivilege = (priv1: string | null, priv2: string | null): string | null => {
|
|
|
|
|
const p1 = priv1 ?? "null";
|
|
|
|
|
const p2 = priv2 ?? "null";
|
|
|
|
|
const priority1 = privilegePriority[p1] ?? 0;
|
|
|
|
|
const priority2 = privilegePriority[p2] ?? 0;
|
|
|
|
|
return priority1 >= priority2 ? priv1 : priv2;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ฟังก์ชันเปรียบเทียบ ownership (OWNER > STAFF > null)
|
|
|
|
|
const getHigherOwnership = (own1: string | null, own2: string | null): string | null => {
|
|
|
|
|
// OWNER สูงสุด
|
|
|
|
|
if (own1 === "OWNER" || own2 === "OWNER") return "OWNER";
|
|
|
|
|
// STAFF รองลงมา
|
|
|
|
|
if (own1 === "STAFF" || own2 === "STAFF") return "STAFF";
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const attr of actingRoleAttrs) {
|
|
|
|
|
const key = attr.authSysId;
|
|
|
|
|
if (!actingPermissionMap.has(key)) {
|
|
|
|
|
actingPermissionMap.set(key, attr);
|
|
|
|
|
} else {
|
|
|
|
|
// รวมสิทธิ์: ใช้ OR logic สำหรับ CRUD
|
|
|
|
|
// สำหรับ attrOwnership และ attrPrivilege ใช้ค่าที่ใหญ่ที่สุด
|
|
|
|
|
const existing = actingPermissionMap.get(key);
|
|
|
|
|
actingPermissionMap.set(key, {
|
|
|
|
|
...attr,
|
|
|
|
|
attrIsCreate: existing.attrIsCreate || attr.attrIsCreate,
|
|
|
|
|
attrIsList: existing.attrIsList || attr.attrIsList,
|
|
|
|
|
attrIsGet: existing.attrIsGet || attr.attrIsGet,
|
|
|
|
|
attrIsUpdate: existing.attrIsUpdate || attr.attrIsUpdate,
|
|
|
|
|
attrIsDelete: existing.attrIsDelete || attr.attrIsDelete,
|
|
|
|
|
attrPrivilege: getHigherPrivilege(attr.attrPrivilege, existing.attrPrivilege),
|
|
|
|
|
parentNode: attr.parentNode, // ใช้ parentNode ของ acting role
|
|
|
|
|
attrOwnership: getHigherOwnership(attr.attrOwnership, existing.attrOwnership),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// รวมกับสิทธิ์พื้นฐานของ User
|
|
|
|
|
// สำหรับระบบที่อยู่ใน acting: ใช้สิทธิ์จาก acting
|
|
|
|
|
// สำหรับระบบที่ไม่อยู่ใน acting: ใช้สิทธิ์พื้นฐาน
|
|
|
|
|
const mergedRoleAttrs = roleAttrData.map((baseAttr) => {
|
|
|
|
|
const actingAttr = actingPermissionMap.get(baseAttr.authSysId);
|
|
|
|
|
if (actingAttr) {
|
|
|
|
|
// ระบบนี้มีสิทธิ์จาก acting - ใช้ค่าจาก acting role
|
|
|
|
|
return {
|
|
|
|
|
...baseAttr,
|
|
|
|
|
parentNode: actingAttr.parentNode,
|
|
|
|
|
attrOwnership: actingAttr.attrOwnership,
|
|
|
|
|
attrIsCreate: actingAttr.attrIsCreate,
|
|
|
|
|
attrIsList: actingAttr.attrIsList,
|
|
|
|
|
attrIsGet: actingAttr.attrIsGet,
|
|
|
|
|
attrIsUpdate: actingAttr.attrIsUpdate,
|
|
|
|
|
attrIsDelete: actingAttr.attrIsDelete,
|
|
|
|
|
attrPrivilege: actingAttr.attrPrivilege,
|
|
|
|
|
// เพิ่ม metadata เพื่อระบุว่ามาจาก acting
|
|
|
|
|
_isActing: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
// เก็บสิทธิ์พื้นฐานสำหรับระบบที่ไม่ได้รักษาการ
|
|
|
|
|
return baseAttr;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// เพิ่มระบบที่มีเฉพาะใน acting roles
|
|
|
|
|
for (const [authSysId, actingAttr] of actingPermissionMap) {
|
|
|
|
|
if (!roleAttrData.find(a => a.authSysId === authSysId)) {
|
|
|
|
|
mergedRoleAttrs.push({
|
|
|
|
|
...actingAttr,
|
|
|
|
|
_isActing: true,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reply = {
|
|
|
|
|
...getDetail,
|
|
|
|
|
roles: mergedRoleAttrs,
|
|
|
|
|
isActing: true, // Flag ระบุสถานะ acting
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
// ไม่มี acting - ใช้ response เดิม
|
|
|
|
|
reply = {
|
|
|
|
|
...getDetail,
|
|
|
|
|
roles: roleAttrData,
|
|
|
|
|
isActing: false,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
redisClient.setex(cacheKey, 86400, JSON.stringify(reply));
|
2024-09-04 17:05:25 +07:00
|
|
|
}
|
|
|
|
|
return new HttpSuccess(reply);
|
2024-09-04 16:15:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Get("menu")
|
2024-09-06 15:24:56 +07:00
|
|
|
public async listAuthSys(@Request() request: RequestWithUser) {
|
2024-08-27 13:14:56 +07:00
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
2024-09-04 16:15:36 +07:00
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
2024-08-27 13:14:56 +07:00
|
|
|
},
|
|
|
|
|
});
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-07-23 19:06:51 +07:00
|
|
|
});
|
2024-07-25 09:54:44 +07:00
|
|
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
2024-07-23 19:06:51 +07:00
|
|
|
|
2024-08-26 22:44:22 +07:00
|
|
|
let profileType = "OFFICER";
|
2024-09-04 16:15:36 +07:00
|
|
|
let profile: any = await this.profileRepo.findOne({
|
2024-08-14 17:37:20 +07:00
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
2024-09-04 16:15:36 +07:00
|
|
|
profileType = "EMPLOYEE";
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
2024-08-26 22:44:22 +07:00
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
2024-09-04 16:15:36 +07:00
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
2024-08-26 22:44:22 +07:00
|
|
|
}
|
2024-09-04 16:15:36 +07:00
|
|
|
}
|
2024-08-14 17:37:20 +07:00
|
|
|
|
2026-05-07 15:07:30 +07:00
|
|
|
// Query ตำแหน่งรักษาการ
|
|
|
|
|
const actingData = await actingPositionService.getActingPositionsWithPrivilege(
|
|
|
|
|
profile.id,
|
|
|
|
|
orgRevision?.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ใช้ cache key แบบเดียวกับ getPermission
|
|
|
|
|
const cacheKey = `menu_${profile.id}_${actingData.isAct ? 'acting' : 'normal'}`;
|
|
|
|
|
let reply = await getAsync(cacheKey);
|
2024-07-25 09:54:44 +07:00
|
|
|
if (reply != null) {
|
|
|
|
|
reply = JSON.parse(reply);
|
|
|
|
|
} else {
|
2024-09-04 16:15:36 +07:00
|
|
|
let posMaster: any = await this.posMasterRepository.findOne({
|
2024-08-26 22:44:22 +07:00
|
|
|
select: ["authRoleId"],
|
2024-07-25 09:54:44 +07:00
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
2024-09-04 16:15:36 +07:00
|
|
|
orgRevisionId: orgRevision?.id,
|
2024-07-25 09:54:44 +07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
2024-08-26 22:44:22 +07:00
|
|
|
posMaster = await this.posMasterEmpRepository.findOne({
|
2024-09-04 16:15:36 +07:00
|
|
|
select: ["authRoleId"],
|
2024-08-26 22:44:22 +07:00
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
2024-09-04 16:15:36 +07:00
|
|
|
orgRevisionId: orgRevision?.id,
|
2024-08-26 22:44:22 +07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
|
|
|
|
|
}
|
2024-07-25 09:54:44 +07:00
|
|
|
}
|
|
|
|
|
|
2024-08-14 17:37:20 +07:00
|
|
|
if (!posMaster.authRoleId) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-25 09:54:44 +07:00
|
|
|
const authRole = await this.authRoleRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { id: posMaster.authRoleId },
|
|
|
|
|
});
|
2024-08-14 17:37:20 +07:00
|
|
|
|
2024-07-25 09:54:44 +07:00
|
|
|
if (!authRole) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
|
|
|
|
|
}
|
2026-05-07 15:07:30 +07:00
|
|
|
|
|
|
|
|
// ดึง roleAttrData ของ user ปกติ
|
|
|
|
|
let roleAttrData = await this.authRoleAttrRepo.find({
|
2024-08-01 16:51:17 +07:00
|
|
|
select: ["authSysId", "parentNode"],
|
2024-07-31 09:43:23 +07:00
|
|
|
where: { authRoleId: authRole.id, attrIsList: true },
|
2024-07-25 09:54:44 +07:00
|
|
|
});
|
2026-05-07 15:07:30 +07:00
|
|
|
|
|
|
|
|
// ถ้ามี acting positions ให้รวมสิทธิ์
|
|
|
|
|
if (actingData.isAct && actingData.posMasterActs.length > 0) {
|
|
|
|
|
// ดึง authRoleId ของทุกตำแหน่งรักษาการ
|
|
|
|
|
const actingAuthRoleIds = await this.posMasterActRepo
|
|
|
|
|
.createQueryBuilder("posMasterAct")
|
|
|
|
|
.leftJoin("posMasterAct.posMaster", "posMaster")
|
|
|
|
|
.select("posMaster.authRoleId", "authRoleId")
|
|
|
|
|
.leftJoin("posMasterAct.posMasterChild", "posMasterChild")
|
|
|
|
|
.leftJoin("posMasterChild.current_holder", "profile")
|
|
|
|
|
.where("profile.id = :profileId", { profileId: profile.id })
|
|
|
|
|
.andWhere("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: orgRevision?.id })
|
|
|
|
|
.getRawMany();
|
|
|
|
|
|
|
|
|
|
// ดึง AuthRoleAttr ทั้งหมดของ acting roles (เฉพาะที่มี attrIsList: true)
|
|
|
|
|
const actingRoleIds = actingAuthRoleIds.map(x => x.authRoleId).filter(id => id != null);
|
|
|
|
|
const actingRoleAttrs = await this.authRoleAttrRepo.find({
|
|
|
|
|
select: ["authSysId", "parentNode"],
|
|
|
|
|
where: { authRoleId: In(actingRoleIds) as any, attrIsList: true },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// รวม authSysId และ parentNode จาก acting เข้ากับ base
|
|
|
|
|
// สำหรับระบบที่มีในทั้งสอง ให้ใช้ค่าของ acting (parentNode)
|
|
|
|
|
for (const actingAttr of actingRoleAttrs) {
|
|
|
|
|
const existingIndex = roleAttrData.findIndex(x => x.authSysId === actingAttr.authSysId);
|
|
|
|
|
if (existingIndex >= 0) {
|
|
|
|
|
// ระบบนี้มีใน base ด้วย -> ใช้ parentNode ของ acting
|
|
|
|
|
roleAttrData[existingIndex].parentNode = actingAttr.parentNode;
|
|
|
|
|
} else {
|
|
|
|
|
// ระบบนี้มีเฉพาะใน acting -> เพิ่มเข้าไป
|
|
|
|
|
roleAttrData.push(actingAttr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 16:51:17 +07:00
|
|
|
const parentNode = roleAttrData.map((x) => x.parentNode);
|
|
|
|
|
const authSysId = roleAttrData.map((x) => x.authSysId);
|
|
|
|
|
const sysId = parentNode.concat(authSysId);
|
2024-07-24 15:44:34 +07:00
|
|
|
|
2024-07-25 09:54:44 +07:00
|
|
|
const getList = await this.authSysRepo.find({
|
|
|
|
|
select: ["id", "parentId", "sysName", "sysDescription", "icon", "path", "order"],
|
2024-08-14 17:37:20 +07:00
|
|
|
where: {
|
|
|
|
|
id: In(sysId),
|
|
|
|
|
},
|
|
|
|
|
order: { order: "ASC" },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const getListChild = await this.authSysRepo.find({
|
|
|
|
|
select: ["id", "parentId", "sysName", "sysDescription", "icon", "path", "order"],
|
|
|
|
|
where: {
|
|
|
|
|
parentId: In(sysId),
|
|
|
|
|
},
|
|
|
|
|
order: { order: "ASC" },
|
2024-07-25 09:54:44 +07:00
|
|
|
});
|
|
|
|
|
|
2024-08-07 11:49:11 +07:00
|
|
|
reply = await getList
|
2024-07-25 09:54:44 +07:00
|
|
|
.filter((x) => x.parentId == null)
|
2024-08-07 11:49:11 +07:00
|
|
|
.sort((a, b) => a.order - b.order)
|
2024-07-25 09:54:44 +07:00
|
|
|
.map((item) => {
|
|
|
|
|
return {
|
|
|
|
|
...item,
|
|
|
|
|
children: getList
|
|
|
|
|
.filter((x) => x.parentId == item.id)
|
2024-08-07 11:49:11 +07:00
|
|
|
.sort((a, b) => a.order - b.order)
|
|
|
|
|
.map((item2) => {
|
|
|
|
|
return {
|
|
|
|
|
...item2,
|
2024-08-14 17:37:20 +07:00
|
|
|
children: getListChild
|
2024-08-07 11:49:11 +07:00
|
|
|
.filter((x) => x.parentId == item2.id)
|
|
|
|
|
.sort((a, b) => a.order - b.order),
|
|
|
|
|
};
|
|
|
|
|
}),
|
2024-07-25 09:54:44 +07:00
|
|
|
};
|
2024-08-07 11:49:11 +07:00
|
|
|
});
|
|
|
|
|
|
2026-05-07 15:07:30 +07:00
|
|
|
redisClient.setex(cacheKey, 86400, JSON.stringify(reply));
|
2024-07-25 09:54:44 +07:00
|
|
|
}
|
2024-07-24 15:44:34 +07:00
|
|
|
|
2024-07-25 09:54:44 +07:00
|
|
|
return new HttpSuccess(reply);
|
2024-07-24 15:44:34 +07:00
|
|
|
}
|
2024-08-14 17:27:11 +07:00
|
|
|
|
2026-04-29 14:39:23 +07:00
|
|
|
/**
|
|
|
|
|
* API ดึงข้อมูลระบบจากตำแหน่งรักษาการ
|
|
|
|
|
* @summary ดึงข้อมูลระบบจากตำแหน่งรักษาการ
|
|
|
|
|
* @param {string} system authSysId ของระบบที่ต้องการตรวจสอบ
|
|
|
|
|
*/
|
|
|
|
|
@Get("acting/{system}")
|
|
|
|
|
public async getSystemsActing(@Request() request: RequestWithUser, @Path() system: string) {
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const posMasterActs = await this.posMasterActRepo
|
|
|
|
|
.createQueryBuilder("posMasterAct")
|
|
|
|
|
.leftJoinAndSelect("posMasterAct.posMaster", "posMaster")
|
|
|
|
|
.addSelect(["posMaster.authRoleId", "posMaster.posMasterNo"])
|
|
|
|
|
.leftJoinAndSelect("posMaster.orgRoot", "orgRoot")
|
|
|
|
|
.leftJoinAndSelect("posMaster.orgChild1", "orgChild1")
|
|
|
|
|
.leftJoinAndSelect("posMaster.orgChild2", "orgChild2")
|
|
|
|
|
.leftJoinAndSelect("posMaster.orgChild3", "orgChild3")
|
|
|
|
|
.leftJoinAndSelect("posMaster.orgChild4", "orgChild4")
|
|
|
|
|
.leftJoinAndSelect("posMasterAct.posMasterChild", "posMasterChild")
|
|
|
|
|
.leftJoinAndSelect("posMasterChild.current_holder", "profileChild")
|
|
|
|
|
.where("profileChild.id = :profileId", { profileId: profile.id })
|
|
|
|
|
.andWhere("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: orgRevision?.id })
|
|
|
|
|
.getMany();
|
|
|
|
|
|
|
|
|
|
if (posMasterActs.length === 0) {
|
|
|
|
|
return new HttpSuccess([]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const results = await Promise.all(
|
|
|
|
|
posMasterActs.map(async (act) => {
|
|
|
|
|
if (!act.posMaster?.authRoleId) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const roleAttrData = await this.authRoleAttrRepo.findOne({
|
|
|
|
|
select: [
|
|
|
|
|
"authSysId",
|
|
|
|
|
"parentNode",
|
|
|
|
|
"attrOwnership",
|
|
|
|
|
"attrIsCreate",
|
|
|
|
|
"attrIsList",
|
|
|
|
|
"attrIsGet",
|
|
|
|
|
"attrIsUpdate",
|
|
|
|
|
"attrIsDelete",
|
|
|
|
|
"attrPrivilege",
|
|
|
|
|
],
|
|
|
|
|
where: { authRoleId: act.posMaster.authRoleId, authSysId: system },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!roleAttrData) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// const holder = act.posMaster;
|
|
|
|
|
// const posNo = !holder
|
|
|
|
|
// ? null
|
|
|
|
|
// : holder.orgChild4 != null
|
|
|
|
|
// ? `${holder.orgChild4.orgChild4ShortName} ${holder.posMasterNo}`
|
|
|
|
|
// : holder.orgChild3 != null
|
|
|
|
|
// ? `${holder.orgChild3.orgChild3ShortName} ${holder.posMasterNo}`
|
|
|
|
|
// : holder.orgChild2 != null
|
|
|
|
|
// ? `${holder.orgChild2.orgChild2ShortName} ${holder.posMasterNo}`
|
|
|
|
|
// : holder.orgChild1 != null
|
|
|
|
|
// ? `${holder.orgChild1.orgChild1ShortName} ${holder.posMasterNo}`
|
|
|
|
|
// : holder.orgRoot != null
|
|
|
|
|
// ? `${holder.orgRoot.orgRootShortName} ${holder.posMasterNo}`
|
|
|
|
|
// : null;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...roleAttrData,
|
|
|
|
|
actingProfileId: act.posMaster.current_holderId,
|
|
|
|
|
// posNo: posNo,
|
|
|
|
|
};
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const filteredResults = results.filter((r) => r !== null);
|
|
|
|
|
|
|
|
|
|
return new HttpSuccess(filteredResults);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-14 17:27:11 +07:00
|
|
|
/**
|
|
|
|
|
* API permission (dotnet api)
|
|
|
|
|
* @summary permission (dotnet api)
|
2024-08-16 11:44:08 +07:00
|
|
|
* @param {string} action action
|
2024-08-14 17:27:11 +07:00
|
|
|
* @param {string} system authSysId
|
|
|
|
|
*/
|
2024-08-16 11:44:08 +07:00
|
|
|
@Get("dotnet/{action}/{system}")
|
2024-08-14 17:27:11 +07:00
|
|
|
public async dotnet(
|
2024-08-19 17:58:33 +07:00
|
|
|
@Request() req: RequestWithUser,
|
2024-08-16 11:44:08 +07:00
|
|
|
@Path() action: string,
|
2024-08-19 17:58:33 +07:00
|
|
|
@Path() system: string,
|
2024-08-14 17:27:11 +07:00
|
|
|
) {
|
2024-08-19 17:58:33 +07:00
|
|
|
if (!["CREATE", "DELETE", "GET", "LIST", "UPDATE"].includes(action)) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "Action ไม่ถูกต้อง");
|
2024-08-14 17:27:11 +07:00
|
|
|
}
|
|
|
|
|
|
2024-08-16 11:44:08 +07:00
|
|
|
let res = await new permission().Permission(req, system.toLocaleUpperCase(), action);
|
2024-08-14 17:27:11 +07:00
|
|
|
return new HttpSuccess(res);
|
|
|
|
|
}
|
2024-08-19 17:58:33 +07:00
|
|
|
|
2026-04-17 14:18:54 +07:00
|
|
|
/**
|
|
|
|
|
* API permission with acting positions
|
|
|
|
|
* @summary permission with acting positions (dotnet api)
|
|
|
|
|
* @param {string} action action
|
|
|
|
|
* @param {string} system authSysId
|
|
|
|
|
*/
|
|
|
|
|
@Get("dotnet-acting/{action}/{system}")
|
|
|
|
|
public async dotnetActing(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Path() action: string,
|
|
|
|
|
@Path() system: string,
|
|
|
|
|
) {
|
|
|
|
|
if (!["CREATE", "DELETE", "GET", "LIST", "UPDATE"].includes(action)) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "Action ไม่ถูกต้อง");
|
|
|
|
|
}
|
|
|
|
|
// ดึง privilege ตามปกติ
|
|
|
|
|
let privilege = await new permission().Permission(req, system.toLocaleUpperCase(), action);
|
|
|
|
|
|
|
|
|
|
// ดึงข้อมูล profile และ orgRevision
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: req.user.sub },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!profile) {
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: req.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ดึงข้อมูลตำแหน่งที่รักษาการ
|
|
|
|
|
const actingData = await actingPositionService.getActingPositionsWithPrivilege(
|
|
|
|
|
profile.id,
|
|
|
|
|
orgRevision?.id,
|
|
|
|
|
action,
|
|
|
|
|
system.toLocaleUpperCase()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ส่งค่ากลับเหมือน dotnet endpoint แต่เพิ่ม isAct และ posMasterActs
|
|
|
|
|
return new HttpSuccess({
|
|
|
|
|
privilege,
|
|
|
|
|
isAct: actingData.isAct,
|
|
|
|
|
posMasterActs: actingData.posMasterActs,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-05 22:05:12 +07:00
|
|
|
/**
|
|
|
|
|
* API permission (dotnet api)
|
|
|
|
|
* @summary permission (dotnet api)
|
|
|
|
|
* @param {string} action action
|
|
|
|
|
* @param {string} system authSysId
|
|
|
|
|
*/
|
|
|
|
|
@Get("dotnet-org/{action}/{system}/{profileId}")
|
|
|
|
|
public async dotnetOrg(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Path() action: string,
|
|
|
|
|
@Path() system: string,
|
|
|
|
|
) {
|
|
|
|
|
if (!["CREATE", "DELETE", "GET", "LIST", "UPDATE"].includes(action)) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "Action ไม่ถูกต้อง");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let res = await new permission().PermissionOrg(req, system.toLocaleUpperCase(), action);
|
|
|
|
|
return new HttpSuccess(res);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-20 22:41:17 +07:00
|
|
|
/**
|
|
|
|
|
* API permission (dotnet api)
|
|
|
|
|
* @summary permission (dotnet api)
|
|
|
|
|
* @param {string} action action
|
|
|
|
|
* @param {string} system authSysId
|
|
|
|
|
* @param {string} profileId profileId
|
|
|
|
|
*/
|
|
|
|
|
@Get("dotnet-user/{action}/{system}/{profileId}")
|
|
|
|
|
public async dotnetUser(
|
|
|
|
|
@Request() req: RequestWithUser,
|
|
|
|
|
@Path() action: string,
|
|
|
|
|
@Path() system: string,
|
|
|
|
|
@Path() profileId: string,
|
|
|
|
|
) {
|
|
|
|
|
if (!["CREATE", "DELETE", "GET", "LIST", "UPDATE"].includes(action)) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "Action ไม่ถูกต้อง");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let res = await new permission().PermissionOrgByUser(
|
|
|
|
|
req,
|
|
|
|
|
system.toLocaleUpperCase(),
|
|
|
|
|
action,
|
|
|
|
|
profileId,
|
|
|
|
|
);
|
|
|
|
|
return new HttpSuccess(res);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-06 15:24:56 +07:00
|
|
|
@Get("org/{system}/{action}")
|
|
|
|
|
public async listAuthSysOrg(
|
|
|
|
|
@Request() request: RequestWithUser,
|
|
|
|
|
@Path() system: string,
|
|
|
|
|
@Path() action: string,
|
|
|
|
|
) {
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-08-19 17:58:33 +07:00
|
|
|
});
|
|
|
|
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
|
|
|
|
|
2024-08-26 22:44:22 +07:00
|
|
|
let profileType = "OFFICER";
|
2024-09-04 16:15:36 +07:00
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
profileType = "EMPLOYEE";
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
2024-08-26 22:44:22 +07:00
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
2024-09-04 16:15:36 +07:00
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
2024-08-26 22:44:22 +07:00
|
|
|
}
|
2024-09-04 16:15:36 +07:00
|
|
|
}
|
2024-08-19 17:58:33 +07:00
|
|
|
|
2024-09-06 15:24:56 +07:00
|
|
|
let privilege = await this.Permission(request, system, action);
|
2024-08-19 17:58:33 +07:00
|
|
|
let reply = await getAsync("posMaster_" + profile.id);
|
|
|
|
|
if (reply != null) {
|
|
|
|
|
reply = JSON.parse(reply);
|
2024-09-06 15:24:56 +07:00
|
|
|
reply.privilege = privilege;
|
2024-08-19 17:58:33 +07:00
|
|
|
} else {
|
2024-09-04 19:24:01 +07:00
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
2024-09-04 16:15:36 +07:00
|
|
|
if (profileType == "OFFICER") {
|
|
|
|
|
const posMaster = await this.posMasterRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
2024-09-06 15:24:56 +07:00
|
|
|
privilege: privilege,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
2024-09-06 15:24:56 +07:00
|
|
|
privilege: privilege,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
2024-08-22 14:35:53 +07:00
|
|
|
} else {
|
2024-09-04 16:15:36 +07:00
|
|
|
const posMaster = await this.posMasterEmpRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
2024-09-06 15:24:56 +07:00
|
|
|
privilege: privilege,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
2024-09-06 15:24:56 +07:00
|
|
|
privilege: privilege,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
2024-08-19 17:58:33 +07:00
|
|
|
}
|
2024-09-04 16:15:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new HttpSuccess(reply);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-06 15:24:56 +07:00
|
|
|
@Get("user/{system}/{action}/{id}")
|
|
|
|
|
public async listOrgUser(
|
|
|
|
|
@Request() request: RequestWithUser,
|
|
|
|
|
@Path() system: string,
|
|
|
|
|
@Path() action: string,
|
|
|
|
|
@Path() id: string,
|
|
|
|
|
) {
|
2024-08-27 13:14:56 +07:00
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
2024-09-04 16:15:36 +07:00
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
2024-08-27 13:14:56 +07:00
|
|
|
},
|
|
|
|
|
});
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-08-20 13:33:03 +07:00
|
|
|
});
|
|
|
|
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
|
|
|
|
|
2024-09-06 15:24:56 +07:00
|
|
|
let org = this.PermissionOrg(request, system, action);
|
2024-09-04 19:24:01 +07:00
|
|
|
let reply = await getAsync("user_" + id);
|
|
|
|
|
if (reply != null) {
|
|
|
|
|
reply = JSON.parse(reply);
|
2024-09-06 15:24:56 +07:00
|
|
|
reply.org = org;
|
2024-09-04 19:24:01 +07:00
|
|
|
} else {
|
|
|
|
|
let profileType = "OFFICER";
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
2024-09-04 16:15:36 +07:00
|
|
|
select: ["id"],
|
2024-09-04 17:05:25 +07:00
|
|
|
where: { id: id },
|
2024-09-04 16:15:36 +07:00
|
|
|
});
|
|
|
|
|
if (!profile) {
|
2024-09-04 19:24:01 +07:00
|
|
|
profileType = "EMPLOYEE";
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { id: id },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
}
|
2024-09-04 16:15:36 +07:00
|
|
|
}
|
|
|
|
|
if (profileType == "OFFICER") {
|
|
|
|
|
const posMaster = await this.posMasterRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
2024-08-26 22:44:22 +07:00
|
|
|
});
|
2024-09-04 16:15:36 +07:00
|
|
|
if (!posMaster) {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
2024-09-06 15:24:56 +07:00
|
|
|
org: org,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
2024-09-06 15:24:56 +07:00
|
|
|
org: org,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
}
|
2024-09-04 17:05:25 +07:00
|
|
|
redisClient.setex("user_" + profile.id, 86400, JSON.stringify(reply));
|
2024-09-04 16:15:36 +07:00
|
|
|
} else {
|
|
|
|
|
const posMaster = await this.posMasterEmpRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
2024-09-06 15:24:56 +07:00
|
|
|
org: org,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
2024-09-06 15:24:56 +07:00
|
|
|
org: org,
|
2024-09-04 16:15:36 +07:00
|
|
|
};
|
2024-08-26 22:44:22 +07:00
|
|
|
}
|
2024-09-04 17:05:25 +07:00
|
|
|
redisClient.setex("user_" + profile.id, 86400, JSON.stringify(reply));
|
2024-09-04 16:15:36 +07:00
|
|
|
}
|
2024-08-20 13:33:03 +07:00
|
|
|
}
|
|
|
|
|
|
2024-09-04 16:15:36 +07:00
|
|
|
return new HttpSuccess(reply);
|
|
|
|
|
}
|
2024-09-06 15:24:56 +07:00
|
|
|
|
|
|
|
|
public async getPermissionFunc(@Request() request: RequestWithUser) {
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-09-06 15:24:56 +07:00
|
|
|
});
|
|
|
|
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
|
|
|
|
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-07 15:07:30 +07:00
|
|
|
// Query ตำแหน่งรักษาการ
|
|
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const actingData = await actingPositionService.getActingPositionsWithPrivilege(
|
|
|
|
|
profile.id,
|
|
|
|
|
orgRevision?.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ใช้ cache key แบบเดียวกับ getPermission()
|
|
|
|
|
const cacheKey = `role_${profile.id}_${actingData.isAct ? 'acting' : 'normal'}`;
|
|
|
|
|
let reply = await getAsync(cacheKey);
|
2024-09-06 15:24:56 +07:00
|
|
|
if (reply != null) {
|
|
|
|
|
reply = JSON.parse(reply);
|
|
|
|
|
} else {
|
|
|
|
|
let posMaster: any = await this.posMasterRepository.findOne({
|
|
|
|
|
select: ["authRoleId"],
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
posMaster = await this.posMasterEmpRepository.findOne({
|
|
|
|
|
select: ["authRoleId"],
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getDetail = await this.authRoleRepo.findOne({
|
|
|
|
|
select: ["id", "roleName", "roleDescription"],
|
|
|
|
|
where: { id: posMaster.authRoleId },
|
|
|
|
|
});
|
|
|
|
|
if (!getDetail) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const roleAttrData = await this.authRoleAttrRepo.find({
|
|
|
|
|
select: [
|
|
|
|
|
"authSysId",
|
|
|
|
|
"parentNode",
|
|
|
|
|
"attrOwnership",
|
|
|
|
|
"attrIsCreate",
|
|
|
|
|
"attrIsList",
|
|
|
|
|
"attrIsGet",
|
|
|
|
|
"attrIsUpdate",
|
|
|
|
|
"attrIsDelete",
|
|
|
|
|
"attrPrivilege",
|
|
|
|
|
],
|
|
|
|
|
where: { authRoleId: getDetail.id },
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-07 15:07:30 +07:00
|
|
|
// ถ้ามี acting positions ให้รวมสิทธิ์
|
|
|
|
|
if (actingData.isAct && actingData.posMasterActs.length > 0) {
|
|
|
|
|
// ดึง authRoleId ของทุกตำแหน่งรักษาการ
|
|
|
|
|
const actingAuthRoleIds = await this.posMasterActRepo
|
|
|
|
|
.createQueryBuilder("posMasterAct")
|
|
|
|
|
.leftJoin("posMasterAct.posMaster", "posMaster")
|
|
|
|
|
.select("posMaster.authRoleId", "authRoleId")
|
|
|
|
|
.leftJoin("posMasterAct.posMasterChild", "posMasterChild")
|
|
|
|
|
.leftJoin("posMasterChild.current_holder", "profile")
|
|
|
|
|
.where("profile.id = :profileId", { profileId: profile.id })
|
|
|
|
|
.andWhere("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: orgRevision?.id })
|
|
|
|
|
.getRawMany();
|
|
|
|
|
|
|
|
|
|
// ดึง AuthRoleAttr ทั้งหมดของ acting roles
|
|
|
|
|
const actingRoleIds = actingAuthRoleIds.map(x => x.authRoleId).filter(id => id != null);
|
|
|
|
|
const actingRoleAttrs = await this.authRoleAttrRepo.find({
|
|
|
|
|
select: [
|
|
|
|
|
"authSysId",
|
|
|
|
|
"parentNode",
|
|
|
|
|
"attrOwnership",
|
|
|
|
|
"attrIsCreate",
|
|
|
|
|
"attrIsList",
|
|
|
|
|
"attrIsGet",
|
|
|
|
|
"attrIsUpdate",
|
|
|
|
|
"attrIsDelete",
|
|
|
|
|
"attrPrivilege",
|
|
|
|
|
],
|
|
|
|
|
where: { authRoleId: In(actingRoleIds) as any },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ลำดับความสำคัญของ privilege (มากไปน้อย)
|
|
|
|
|
const privilegePriority: Record<string, number> = {
|
|
|
|
|
"OWNER": 7,
|
|
|
|
|
"PARENT": 6,
|
|
|
|
|
"ROOT": 5,
|
|
|
|
|
"BROTHER": 4,
|
|
|
|
|
"CHILD": 3,
|
|
|
|
|
"NORMAL": 2,
|
|
|
|
|
"SPECIFIC": 1,
|
|
|
|
|
"null": 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ฟังก์ชันเปรียบเทียบ privilege
|
|
|
|
|
const getHigherPrivilege = (priv1: string | null, priv2: string | null): string | null => {
|
|
|
|
|
const p1 = priv1 ?? "null";
|
|
|
|
|
const p2 = priv2 ?? "null";
|
|
|
|
|
const priority1 = privilegePriority[p1] ?? 0;
|
|
|
|
|
const priority2 = privilegePriority[p2] ?? 0;
|
|
|
|
|
return priority1 >= priority2 ? priv1 : priv2;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ฟังก์ชันเปรียบเทียบ ownership (OWNER > STAFF > null)
|
|
|
|
|
const getHigherOwnership = (own1: string | null, own2: string | null): string | null => {
|
|
|
|
|
if (own1 === "OWNER" || own2 === "OWNER") return "OWNER";
|
|
|
|
|
if (own1 === "STAFF" || own2 === "STAFF") return "STAFF";
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// สร้าง map ของ authSysId -> สิทธิ์ที่ดีที่สุดจาก acting
|
|
|
|
|
const actingPermissionMap = new Map<string, any>();
|
|
|
|
|
|
|
|
|
|
for (const attr of actingRoleAttrs) {
|
|
|
|
|
const key = attr.authSysId;
|
|
|
|
|
if (!actingPermissionMap.has(key)) {
|
|
|
|
|
actingPermissionMap.set(key, attr);
|
|
|
|
|
} else {
|
|
|
|
|
const existing = actingPermissionMap.get(key);
|
|
|
|
|
actingPermissionMap.set(key, {
|
|
|
|
|
...attr,
|
|
|
|
|
attrIsCreate: existing.attrIsCreate || attr.attrIsCreate,
|
|
|
|
|
attrIsList: existing.attrIsList || attr.attrIsList,
|
|
|
|
|
attrIsGet: existing.attrIsGet || attr.attrIsGet,
|
|
|
|
|
attrIsUpdate: existing.attrIsUpdate || attr.attrIsUpdate,
|
|
|
|
|
attrIsDelete: existing.attrIsDelete || attr.attrIsDelete,
|
|
|
|
|
attrPrivilege: getHigherPrivilege(attr.attrPrivilege, existing.attrPrivilege),
|
|
|
|
|
parentNode: attr.parentNode,
|
|
|
|
|
attrOwnership: getHigherOwnership(attr.attrOwnership, existing.attrOwnership),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// รวมกับสิทธิ์พื้นฐานของ User
|
|
|
|
|
const mergedRoleAttrs = roleAttrData.map((baseAttr) => {
|
|
|
|
|
const actingAttr = actingPermissionMap.get(baseAttr.authSysId);
|
|
|
|
|
if (actingAttr) {
|
|
|
|
|
return {
|
|
|
|
|
...baseAttr,
|
|
|
|
|
parentNode: actingAttr.parentNode,
|
|
|
|
|
attrOwnership: actingAttr.attrOwnership,
|
|
|
|
|
attrIsCreate: actingAttr.attrIsCreate,
|
|
|
|
|
attrIsList: actingAttr.attrIsList,
|
|
|
|
|
attrIsGet: actingAttr.attrIsGet,
|
|
|
|
|
attrIsUpdate: actingAttr.attrIsUpdate,
|
|
|
|
|
attrIsDelete: actingAttr.attrIsDelete,
|
|
|
|
|
attrPrivilege: actingAttr.attrPrivilege,
|
|
|
|
|
_isActing: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return baseAttr;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// เพิ่มระบบที่มีเฉพาะใน acting roles
|
|
|
|
|
for (const [authSysId, actingAttr] of actingPermissionMap) {
|
|
|
|
|
if (!roleAttrData.find(a => a.authSysId === authSysId)) {
|
|
|
|
|
mergedRoleAttrs.push({
|
|
|
|
|
...actingAttr,
|
|
|
|
|
_isActing: true,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reply = {
|
|
|
|
|
...getDetail,
|
|
|
|
|
roles: mergedRoleAttrs,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
reply = {
|
|
|
|
|
...getDetail,
|
|
|
|
|
roles: roleAttrData,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
redisClient.setex(cacheKey, 86400, JSON.stringify(reply));
|
2024-09-06 15:24:56 +07:00
|
|
|
}
|
|
|
|
|
return reply;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Permission(req: RequestWithUser, system: string, action: string) {
|
|
|
|
|
// if (
|
|
|
|
|
// req.headers.hasOwnProperty("api_key") &&
|
|
|
|
|
// req.headers["api_key"] &&
|
|
|
|
|
// req.headers["api_key"] == process.env.API_KEY
|
|
|
|
|
// ) {
|
|
|
|
|
// return null;
|
|
|
|
|
// }
|
|
|
|
|
let x: any = await this.getPermissionFunc(req);
|
|
|
|
|
let permission = false;
|
|
|
|
|
let role = x.roles.find((x: any) => x.authSysId == system);
|
|
|
|
|
if (!role) throw "ไม่มีสิทธิ์เข้าระบบ";
|
|
|
|
|
if (role.attrOwnership == "OWNER") return "OWNER";
|
|
|
|
|
if (action.trim().toLocaleUpperCase() == "CREATE") permission = role.attrIsCreate;
|
|
|
|
|
if (action.trim().toLocaleUpperCase() == "DELETE") permission = role.attrIsDelete;
|
|
|
|
|
if (action.trim().toLocaleUpperCase() == "GET") permission = role.attrIsGet;
|
|
|
|
|
if (action.trim().toLocaleUpperCase() == "LIST") permission = role.attrIsList;
|
|
|
|
|
if (action.trim().toLocaleUpperCase() == "UPDATE") permission = role.attrIsUpdate;
|
|
|
|
|
if (permission == false) throw "ไม่มีสิทธิ์ใช้งานระบบนี้";
|
|
|
|
|
return role.attrPrivilege;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async listAuthSysOrgFunc(request: RequestWithUser, system: string, action: string) {
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-09-06 15:24:56 +07:00
|
|
|
});
|
|
|
|
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
|
|
|
|
|
|
|
|
|
let profileType = "OFFICER";
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
profileType = "EMPLOYEE";
|
|
|
|
|
profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: request.user.sub },
|
|
|
|
|
});
|
|
|
|
|
if (!profile) {
|
|
|
|
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-07 15:07:30 +07:00
|
|
|
// Query ตำแหน่งรักษาการ
|
|
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const actingData = await actingPositionService.getActingPositionsWithPrivilege(
|
|
|
|
|
profile.id,
|
|
|
|
|
orgRevision?.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ใช้ cache key แบบใหม่
|
|
|
|
|
const cacheKey = `posMaster_${profile.id}_${actingData.isAct ? 'acting' : 'normal'}`;
|
|
|
|
|
let reply = await getAsync(cacheKey);
|
2024-09-06 15:24:56 +07:00
|
|
|
if (reply != null) {
|
|
|
|
|
reply = JSON.parse(reply);
|
|
|
|
|
} else {
|
|
|
|
|
let privilege = await this.Permission(request, system, action);
|
2026-05-07 15:07:30 +07:00
|
|
|
|
|
|
|
|
// ถ้ากำลังรักษาการ ให้ดึง org จาก acting position
|
|
|
|
|
if (actingData.isAct) {
|
|
|
|
|
// ดึงข้อมูล permission เพื่อเช็คว่าระบบนี้มาจาก acting หรือไม่
|
|
|
|
|
const permData: any = await this.getPermissionFunc(request);
|
|
|
|
|
const role = permData.roles.find((r: any) => r.authSysId === system);
|
|
|
|
|
|
|
|
|
|
if (role && role._isActing) {
|
|
|
|
|
// ระบบนี้มาจาก acting position ดึง org จาก acting
|
|
|
|
|
const actingOrgData = await this.getActingOrgScope(profile.id, orgRevision?.id, system, profileType);
|
2024-09-06 15:24:56 +07:00
|
|
|
reply = {
|
2026-05-07 15:07:30 +07:00
|
|
|
orgRootId: actingOrgData.orgRootId,
|
|
|
|
|
orgChild1Id: actingOrgData.orgChild1Id,
|
|
|
|
|
orgChild2Id: actingOrgData.orgChild2Id,
|
|
|
|
|
orgChild3Id: actingOrgData.orgChild3Id,
|
|
|
|
|
orgChild4Id: actingOrgData.orgChild4Id,
|
2024-09-06 15:24:56 +07:00
|
|
|
privilege: privilege,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
2026-05-07 15:07:30 +07:00
|
|
|
// ระบบนี้มาจากตำแหน่งปกติ ใช้ org ปกติ
|
|
|
|
|
reply = await this.getBaseOrgScope(profile.id, orgRevision?.id, profileType, privilege);
|
2024-09-06 15:24:56 +07:00
|
|
|
}
|
|
|
|
|
} else {
|
2026-05-07 15:07:30 +07:00
|
|
|
// ไม่มี acting ใช้ org ปกติ
|
|
|
|
|
reply = await this.getBaseOrgScope(profile.id, orgRevision?.id, profileType, privilege);
|
2024-09-06 15:24:56 +07:00
|
|
|
}
|
2026-05-07 15:07:30 +07:00
|
|
|
|
|
|
|
|
redisClient.setex(cacheKey, 86400, JSON.stringify(reply));
|
2024-09-06 15:24:56 +07:00
|
|
|
}
|
|
|
|
|
return reply;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-07 15:07:30 +07:00
|
|
|
// Helper method: ดึง org scope จากตำแหน่งปกติ
|
|
|
|
|
private async getBaseOrgScope(profileId: string, orgRevisionId: string | undefined, profileType: string, privilege: any) {
|
|
|
|
|
if (profileType == "OFFICER") {
|
|
|
|
|
const posMaster = await this.posMasterRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profileId,
|
|
|
|
|
orgRevisionId: orgRevisionId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
return {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
|
|
|
|
privilege: privilege,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
|
|
|
|
privilege: privilege,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const posMaster = await this.posMasterEmpRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profileId,
|
|
|
|
|
orgRevisionId: orgRevisionId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
return {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
|
|
|
|
privilege: privilege,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
|
|
|
|
privilege: privilege,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper method: ดึง org scope จาก acting position ที่มีสิทธิ์ในระบบนั้น
|
|
|
|
|
private async getActingOrgScope(profileId: string, orgRevisionId: string | undefined, system: string, profileType: string) {
|
|
|
|
|
const repo = profileType === "OFFICER" ? this.posMasterRepository : this.posMasterEmpRepository;
|
|
|
|
|
|
|
|
|
|
const actingOrgData = await this.posMasterActRepo
|
|
|
|
|
.createQueryBuilder("posMasterAct")
|
|
|
|
|
.leftJoin("posMasterAct.posMaster", "posMaster")
|
|
|
|
|
.select([
|
|
|
|
|
"posMaster.orgRootId",
|
|
|
|
|
"posMaster.orgChild1Id",
|
|
|
|
|
"posMaster.orgChild2Id",
|
|
|
|
|
"posMaster.orgChild3Id",
|
|
|
|
|
"posMaster.orgChild4Id",
|
|
|
|
|
])
|
|
|
|
|
.leftJoin("posMasterAct.posMasterChild", "posMasterChild")
|
|
|
|
|
.leftJoin("posMasterChild.current_holder", "profile")
|
|
|
|
|
.where("profile.id = :profileId", { profileId })
|
|
|
|
|
.andWhere("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId })
|
|
|
|
|
.orderBy("posMasterAct.posMasterOrder", "ASC")
|
|
|
|
|
.getRawOne();
|
|
|
|
|
|
|
|
|
|
if (!actingOrgData) {
|
|
|
|
|
// ไม่พบ acting position คืนค่า null
|
|
|
|
|
return {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
orgRootId: actingOrgData.orgRootId,
|
|
|
|
|
orgChild1Id: actingOrgData.orgChild1Id,
|
|
|
|
|
orgChild2Id: actingOrgData.orgChild2Id,
|
|
|
|
|
orgChild3Id: actingOrgData.orgChild3Id,
|
|
|
|
|
orgChild4Id: actingOrgData.orgChild4Id,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-06 15:24:56 +07:00
|
|
|
public async PermissionOrg(req: RequestWithUser, system: string, action: string) {
|
|
|
|
|
let x: any = await this.listAuthSysOrgFunc(req, system, action);
|
|
|
|
|
let privilege = x.privilege;
|
|
|
|
|
|
|
|
|
|
let data: any = {
|
|
|
|
|
root: [null],
|
|
|
|
|
child1: [null],
|
|
|
|
|
child2: [null],
|
|
|
|
|
child3: [null],
|
|
|
|
|
child4: [null],
|
|
|
|
|
};
|
|
|
|
|
let node = 4;
|
|
|
|
|
if (x.orgChild1Id == null) {
|
|
|
|
|
node = 0;
|
|
|
|
|
} else if (x.orgChild2Id == null) {
|
|
|
|
|
node = 1;
|
|
|
|
|
} else if (x.orgChild3Id == null) {
|
|
|
|
|
node = 2;
|
|
|
|
|
} else if (x.orgChild4Id == null) {
|
|
|
|
|
node = 3;
|
|
|
|
|
}
|
|
|
|
|
if (privilege == "ROOT") {
|
|
|
|
|
data = {
|
|
|
|
|
root: [x.orgRootId],
|
|
|
|
|
child1: null,
|
|
|
|
|
child2: null,
|
|
|
|
|
child3: null,
|
|
|
|
|
child4: null,
|
|
|
|
|
};
|
2025-10-07 11:14:00 +07:00
|
|
|
} else if (privilege == "PARENT") {
|
|
|
|
|
data = {
|
2026-02-19 14:27:02 +07:00
|
|
|
// root: [x.orgRootId],
|
|
|
|
|
// child1: [null],
|
|
|
|
|
root: null,
|
|
|
|
|
child1: null,
|
2025-10-07 11:14:00 +07:00
|
|
|
child2: null,
|
|
|
|
|
child3: null,
|
|
|
|
|
child4: null,
|
|
|
|
|
};
|
2024-09-06 15:24:56 +07:00
|
|
|
} else if (privilege == "CHILD") {
|
|
|
|
|
data = {
|
|
|
|
|
root: node >= 0 ? [x.orgRootId] : null,
|
|
|
|
|
child1: node >= 1 ? [x.orgChild1Id] : null,
|
|
|
|
|
child2: node >= 2 ? [x.orgChild2Id] : null,
|
|
|
|
|
child3: node >= 3 ? [x.orgChild3Id] : null,
|
|
|
|
|
child4: node >= 4 ? [x.orgChild4Id] : null,
|
|
|
|
|
};
|
2025-12-12 01:36:51 +07:00
|
|
|
} else if (privilege == "BROTHER") {
|
|
|
|
|
data = {
|
|
|
|
|
// root: node >= 0 ? null : null,
|
|
|
|
|
root: node >= 0 ? [x.orgRootId] : null,
|
|
|
|
|
child1: node >= 2 ? [x.orgChild1Id] : null,
|
|
|
|
|
child2: node >= 3 ? [x.orgChild2Id] : null,
|
|
|
|
|
child3: node >= 4 ? [x.orgChild3Id] : null,
|
|
|
|
|
};
|
2024-09-06 15:24:56 +07:00
|
|
|
} else if (privilege == "NORMAL") {
|
|
|
|
|
data = {
|
|
|
|
|
root: [x.orgRootId],
|
|
|
|
|
child1: [x.orgChild1Id],
|
|
|
|
|
child2: [x.orgChild2Id],
|
|
|
|
|
child3: [x.orgChild3Id],
|
|
|
|
|
child4: [x.orgChild4Id],
|
|
|
|
|
};
|
|
|
|
|
} else if (privilege == "SPECIFIC") {
|
|
|
|
|
} else if (privilege == "OWNER") {
|
|
|
|
|
data = {
|
|
|
|
|
root: null,
|
|
|
|
|
child1: null,
|
|
|
|
|
child2: null,
|
|
|
|
|
child3: null,
|
|
|
|
|
child4: null,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
}
|
2024-10-25 13:01:27 +07:00
|
|
|
|
|
|
|
|
@Get("checkOrg/{keycloakId}")
|
2024-11-05 22:05:12 +07:00
|
|
|
public async checkOrg(@Path() keycloakId: string) {
|
2026-02-27 09:30:46 +07:00
|
|
|
const redisClient = await this.redis.createClient({
|
|
|
|
|
host: REDIS_HOST,
|
|
|
|
|
port: REDIS_PORT,
|
2024-10-25 13:01:27 +07:00
|
|
|
});
|
|
|
|
|
// const getAsync = promisify(redisClient.get).bind(redisClient);
|
2024-11-05 22:05:12 +07:00
|
|
|
|
2024-10-25 13:01:27 +07:00
|
|
|
// let profileType = "OFFICER";
|
|
|
|
|
let profile: any = await this.profileRepo.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: { keycloak: keycloakId },
|
|
|
|
|
});
|
|
|
|
|
// if (!profile) {
|
|
|
|
|
// profileType = "EMPLOYEE";
|
|
|
|
|
// profile = await this.profileEmployeeRepo.findOne({
|
|
|
|
|
// select: ["id"],
|
|
|
|
|
// where: { keycloak: keycloakId },
|
|
|
|
|
// });
|
|
|
|
|
// if (!profile) {
|
|
|
|
|
// throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
let reply: any;
|
2024-11-05 22:05:12 +07:00
|
|
|
const orgRevision = await this.orgRevisionRepository.findOne({
|
|
|
|
|
select: ["id"],
|
|
|
|
|
where: {
|
|
|
|
|
orgRevisionIsDraft: false,
|
|
|
|
|
orgRevisionIsCurrent: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
// if (profileType == "OFFICER") {
|
|
|
|
|
const posMaster = await this.posMasterRepository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
current_holderId: profile.id,
|
|
|
|
|
orgRevisionId: orgRevision?.id,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (!posMaster) {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: null,
|
|
|
|
|
orgChild1Id: null,
|
|
|
|
|
orgChild2Id: null,
|
|
|
|
|
orgChild3Id: null,
|
|
|
|
|
orgChild4Id: null,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
reply = {
|
|
|
|
|
orgRootId: posMaster.orgRootId,
|
|
|
|
|
orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
orgChild4Id: posMaster.orgChild4Id,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
redisClient.setex("org_" + profile.id, 86400, JSON.stringify(reply)); //Create Redis
|
|
|
|
|
// } else {
|
|
|
|
|
// const posMaster = await this.posMasterEmpRepository.findOne({
|
|
|
|
|
// where: {
|
|
|
|
|
// current_holderId: profile.id,
|
|
|
|
|
// orgRevisionId: orgRevision?.id,
|
|
|
|
|
// },
|
|
|
|
|
// });
|
|
|
|
|
// if (!posMaster) {
|
|
|
|
|
// reply = {
|
|
|
|
|
// orgRootId: null,
|
|
|
|
|
// orgChild1Id: null,
|
|
|
|
|
// orgChild2Id: null,
|
|
|
|
|
// orgChild3Id: null,
|
|
|
|
|
// orgChild4Id: null,
|
|
|
|
|
// };
|
|
|
|
|
// } else {
|
|
|
|
|
// reply = {
|
|
|
|
|
// orgRootId: posMaster.orgRootId,
|
|
|
|
|
// orgChild1Id: posMaster.orgChild1Id,
|
|
|
|
|
// orgChild2Id: posMaster.orgChild2Id,
|
|
|
|
|
// orgChild3Id: posMaster.orgChild3Id,
|
|
|
|
|
// orgChild4Id: posMaster.orgChild4Id,
|
|
|
|
|
// };
|
|
|
|
|
// }
|
|
|
|
|
// redisClient.setex("org_" + profile.id, 86400, JSON.stringify(reply));
|
|
|
|
|
// }
|
2024-10-25 13:01:27 +07:00
|
|
|
|
|
|
|
|
return new HttpSuccess(reply);
|
|
|
|
|
}
|
2024-07-23 19:06:51 +07:00
|
|
|
}
|