Merge branch 'refactor/permission' into develop-Bright
This commit is contained in:
commit
49208df976
2 changed files with 509 additions and 99 deletions
|
|
@ -57,17 +57,25 @@ export class PermissionController extends Controller {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 ทุกครั้ง
|
||||
let reply = await getAsync("role_" + profile.id);
|
||||
if (reply != null) {
|
||||
reply = JSON.parse(reply);
|
||||
} else {
|
||||
const orgRevision = await this.orgRevisionRepository.findOne({
|
||||
select: ["id"],
|
||||
where: {
|
||||
orgRevisionIsDraft: false,
|
||||
orgRevisionIsCurrent: true,
|
||||
},
|
||||
});
|
||||
let posMaster: any = await this.posMasterRepository.findOne({
|
||||
select: ["authRoleId"],
|
||||
where: {
|
||||
|
|
@ -111,10 +119,139 @@ export class PermissionController extends Controller {
|
|||
where: { authRoleId: getDetail.id },
|
||||
});
|
||||
|
||||
reply = {
|
||||
...getDetail,
|
||||
roles: roleAttrData,
|
||||
};
|
||||
// ถ้า 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("role_" + profile.id, 86400, JSON.stringify(reply));
|
||||
}
|
||||
return new HttpSuccess(reply);
|
||||
|
|
@ -151,6 +288,13 @@ export class PermissionController extends Controller {
|
|||
}
|
||||
}
|
||||
|
||||
// Query ตำแหน่งรักษาการ
|
||||
const actingData = await actingPositionService.getActingPositionsWithPrivilege(
|
||||
profile.id,
|
||||
orgRevision?.id
|
||||
);
|
||||
|
||||
// ใช้ cache key เดิม
|
||||
let reply = await getAsync("menu_" + profile.id);
|
||||
if (reply != null) {
|
||||
reply = JSON.parse(reply);
|
||||
|
|
@ -187,10 +331,47 @@ export class PermissionController extends Controller {
|
|||
if (!authRole) {
|
||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์");
|
||||
}
|
||||
const roleAttrData = await this.authRoleAttrRepo.find({
|
||||
|
||||
// ดึง roleAttrData ของ user ปกติ
|
||||
let roleAttrData = await this.authRoleAttrRepo.find({
|
||||
select: ["authSysId", "parentNode"],
|
||||
where: { authRoleId: authRole.id, attrIsList: true },
|
||||
});
|
||||
|
||||
// ถ้ามี 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const parentNode = roleAttrData.map((x) => x.parentNode);
|
||||
const authSysId = roleAttrData.map((x) => x.authSysId);
|
||||
const sysId = parentNode.concat(authSysId);
|
||||
|
|
@ -686,17 +867,25 @@ export class PermissionController extends Controller {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 เดิม
|
||||
let reply = await getAsync("role_" + profile.id);
|
||||
if (reply != null) {
|
||||
reply = JSON.parse(reply);
|
||||
} else {
|
||||
const orgRevision = await this.orgRevisionRepository.findOne({
|
||||
select: ["id"],
|
||||
where: {
|
||||
orgRevisionIsDraft: false,
|
||||
orgRevisionIsCurrent: true,
|
||||
},
|
||||
});
|
||||
let posMaster: any = await this.posMasterRepository.findOne({
|
||||
select: ["authRoleId"],
|
||||
where: {
|
||||
|
|
@ -740,10 +929,128 @@ export class PermissionController extends Controller {
|
|||
where: { authRoleId: getDetail.id },
|
||||
});
|
||||
|
||||
reply = {
|
||||
...getDetail,
|
||||
roles: roleAttrData,
|
||||
};
|
||||
// ถ้ามี 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("role_" + profile.id, 86400, JSON.stringify(reply));
|
||||
}
|
||||
return reply;
|
||||
|
|
@ -794,77 +1101,156 @@ export class PermissionController extends Controller {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 เดิม
|
||||
let reply = await getAsync("posMaster_" + profile.id);
|
||||
if (reply != null) {
|
||||
reply = JSON.parse(reply);
|
||||
} else {
|
||||
let privilege = await this.Permission(request, system, action);
|
||||
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) {
|
||||
|
||||
// ถ้ากำลังรักษาการ ให้ดึง 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);
|
||||
reply = {
|
||||
orgRootId: null,
|
||||
orgChild1Id: null,
|
||||
orgChild2Id: null,
|
||||
orgChild3Id: null,
|
||||
orgChild4Id: null,
|
||||
orgRootId: actingOrgData.orgRootId,
|
||||
orgChild1Id: actingOrgData.orgChild1Id,
|
||||
orgChild2Id: actingOrgData.orgChild2Id,
|
||||
orgChild3Id: actingOrgData.orgChild3Id,
|
||||
orgChild4Id: actingOrgData.orgChild4Id,
|
||||
privilege: privilege,
|
||||
};
|
||||
} else {
|
||||
reply = {
|
||||
orgRootId: posMaster.orgRootId,
|
||||
orgChild1Id: posMaster.orgChild1Id,
|
||||
orgChild2Id: posMaster.orgChild2Id,
|
||||
orgChild3Id: posMaster.orgChild3Id,
|
||||
orgChild4Id: posMaster.orgChild4Id,
|
||||
privilege: privilege,
|
||||
};
|
||||
// ระบบนี้มาจากตำแหน่งปกติ ใช้ org ปกติ
|
||||
reply = await this.getBaseOrgScope(profile.id, orgRevision?.id, profileType, privilege);
|
||||
}
|
||||
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
||||
} 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,
|
||||
privilege: privilege,
|
||||
};
|
||||
} else {
|
||||
reply = {
|
||||
orgRootId: posMaster.orgRootId,
|
||||
orgChild1Id: posMaster.orgChild1Id,
|
||||
orgChild2Id: posMaster.orgChild2Id,
|
||||
orgChild3Id: posMaster.orgChild3Id,
|
||||
orgChild4Id: posMaster.orgChild4Id,
|
||||
privilege: privilege,
|
||||
};
|
||||
}
|
||||
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
||||
// ไม่มี acting ใช้ org ปกติ
|
||||
reply = await this.getBaseOrgScope(profile.id, orgRevision?.id, profileType, privilege);
|
||||
}
|
||||
|
||||
redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
// 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,
|
||||
};
|
||||
}
|
||||
|
||||
public async PermissionOrg(req: RequestWithUser, system: string, action: string) {
|
||||
let x: any = await this.listAuthSysOrgFunc(req, system, action);
|
||||
let privilege = x.privilege;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ import Extension from "../interfaces/extension";
|
|||
import { ProfileActposition } from "../entities/ProfileActposition";
|
||||
import { RequestWithUser } from "../middlewares/user";
|
||||
import { escape } from "querystring";
|
||||
import { promisify } from "util";
|
||||
|
||||
const REDIS_HOST = process.env.REDIS_HOST;
|
||||
const REDIS_PORT = process.env.REDIS_PORT;
|
||||
|
||||
@Route("api/v1/org/pos/act")
|
||||
@Tags("PosMasterAct")
|
||||
|
|
@ -37,6 +41,7 @@ export class PosMasterActController extends Controller {
|
|||
private posMasterActRepository = AppDataSource.getRepository(PosMasterAct);
|
||||
private posMasterRepository = AppDataSource.getRepository(PosMaster);
|
||||
private actpositionRepository = AppDataSource.getRepository(ProfileActposition);
|
||||
private redis = require("redis");
|
||||
|
||||
/**
|
||||
* API เพิ่มรักษาการในตำแหน่ง
|
||||
|
|
@ -92,7 +97,6 @@ export class PosMasterActController extends Controller {
|
|||
return new HttpSuccess(posMasterAct);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* API ค้นหาตำแหน่งในระบบสมัครสอบ ขรก.
|
||||
*
|
||||
|
|
@ -125,9 +129,7 @@ export class PosMasterActController extends Controller {
|
|||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
|
||||
}
|
||||
|
||||
let posId: any[] = posMasterMain.posMasterActs.map(
|
||||
(x) => x.posMasterChildId
|
||||
);
|
||||
let posId: any[] = posMasterMain.posMasterActs.map((x) => x.posMasterChildId);
|
||||
posId.push(body.posmasterId);
|
||||
|
||||
const query = await AppDataSource.getRepository(PosMaster)
|
||||
|
|
@ -172,31 +174,31 @@ export class PosMasterActController extends Controller {
|
|||
posMasterMain.orgRootId == null
|
||||
? "posMaster.orgRootId IS NULL"
|
||||
: "posMaster.orgRootId = :orgRootId",
|
||||
{ orgRootId: posMasterMain.orgRootId }
|
||||
{ orgRootId: posMasterMain.orgRootId },
|
||||
)
|
||||
.andWhere(
|
||||
posMasterMain.orgChild1Id == null
|
||||
? "posMaster.orgChild1Id IS NULL"
|
||||
: "posMaster.orgChild1Id = :orgChild1Id",
|
||||
{ orgChild1Id: posMasterMain.orgChild1Id }
|
||||
{ orgChild1Id: posMasterMain.orgChild1Id },
|
||||
)
|
||||
.andWhere(
|
||||
posMasterMain.orgChild2Id == null
|
||||
? "posMaster.orgChild2Id IS NULL"
|
||||
: "posMaster.orgChild2Id = :orgChild2Id",
|
||||
{ orgChild2Id: posMasterMain.orgChild2Id }
|
||||
{ orgChild2Id: posMasterMain.orgChild2Id },
|
||||
)
|
||||
.andWhere(
|
||||
posMasterMain.orgChild3Id == null
|
||||
? "posMaster.orgChild3Id IS NULL"
|
||||
: "posMaster.orgChild3Id = :orgChild3Id",
|
||||
{ orgChild3Id: posMasterMain.orgChild3Id }
|
||||
{ orgChild3Id: posMasterMain.orgChild3Id },
|
||||
)
|
||||
.andWhere(
|
||||
posMasterMain.orgChild4Id == null
|
||||
? "posMaster.orgChild4Id IS NULL"
|
||||
: "posMaster.orgChild4Id = :orgChild4Id",
|
||||
{ orgChild4Id: posMasterMain.orgChild4Id }
|
||||
{ orgChild4Id: posMasterMain.orgChild4Id },
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -210,7 +212,7 @@ export class PosMasterActController extends Controller {
|
|||
new Brackets((qb) => {
|
||||
qb.where(
|
||||
`CONCAT(current_holder.prefix, current_holder.firstName, ' ', current_holder.lastName) LIKE :keyword`,
|
||||
{ keyword: `%${keyword}%` }
|
||||
{ keyword: `%${keyword}%` },
|
||||
)
|
||||
.orWhere(`current_holder.citizenId LIKE :keyword`, {
|
||||
keyword: `%${keyword}%`,
|
||||
|
|
@ -228,7 +230,7 @@ export class PosMasterActController extends Controller {
|
|||
' ',
|
||||
posMaster.posMasterNo
|
||||
) LIKE :keyword`,
|
||||
{ keyword: `%${keyword}%` }
|
||||
{ keyword: `%${keyword}%` },
|
||||
)
|
||||
.orWhere(`posLevel.posLevelName LIKE :keyword`, {
|
||||
keyword: `%${keyword}%`,
|
||||
|
|
@ -238,8 +240,8 @@ export class PosMasterActController extends Controller {
|
|||
})
|
||||
.orWhere(`current_holder.position LIKE :keyword`, {
|
||||
keyword: `%${keyword}%`,
|
||||
})
|
||||
})
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +282,6 @@ export class PosMasterActController extends Controller {
|
|||
return new HttpSuccess({ data: data, total });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* API ลบรักษาการในตำแหน่ง
|
||||
*
|
||||
|
|
@ -690,12 +691,12 @@ export class PosMasterActController extends Controller {
|
|||
x.posMasterChild?.orgRoot?.orgRootShortName,
|
||||
].find((name) => !!name) && x.posMasterChild?.posMasterNo
|
||||
? `${[
|
||||
x.posMasterChild?.orgChild4?.orgChild4ShortName,
|
||||
x.posMasterChild?.orgChild3?.orgChild3ShortName,
|
||||
x.posMasterChild?.orgChild2?.orgChild2ShortName,
|
||||
x.posMasterChild?.orgChild1?.orgChild1ShortName,
|
||||
x.posMasterChild?.orgRoot?.orgRootShortName,
|
||||
].find((name) => !!name)} ${x.posMasterChild.posMasterNo}`
|
||||
x.posMasterChild?.orgChild4?.orgChild4ShortName,
|
||||
x.posMasterChild?.orgChild3?.orgChild3ShortName,
|
||||
x.posMasterChild?.orgChild2?.orgChild2ShortName,
|
||||
x.posMasterChild?.orgChild1?.orgChild1ShortName,
|
||||
x.posMasterChild?.orgRoot?.orgRootShortName,
|
||||
].find((name) => !!name)} ${x.posMasterChild.posMasterNo}`
|
||||
: x.posMasterChild?.posMasterNo || null;
|
||||
const orgShortNameAct =
|
||||
[
|
||||
|
|
@ -768,6 +769,9 @@ export class PosMasterActController extends Controller {
|
|||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรักษาการในตำแหน่งของหน่วยงานนี้");
|
||||
}
|
||||
|
||||
// เก็บรวบรวม profileIds ทั้งหมดเพื่อ clear cache หลังจากบันทึกเสร็จ
|
||||
const profileIdsToClearCache = new Set<string>();
|
||||
|
||||
await Promise.all(
|
||||
posMasterActs.map(async (posMasterAct) => {
|
||||
const orgShortName =
|
||||
|
|
@ -782,6 +786,8 @@ export class PosMasterActController extends Controller {
|
|||
const profileId = posMasterAct.posMasterChild?.current_holderId;
|
||||
|
||||
if (profileId) {
|
||||
profileIdsToClearCache.add(profileId);
|
||||
|
||||
const existingActivePositions = await this.actpositionRepository.find({
|
||||
select: [
|
||||
"id",
|
||||
|
|
@ -790,7 +796,7 @@ export class PosMasterActController extends Controller {
|
|||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
"dateEnd",
|
||||
"isDeleted"
|
||||
"isDeleted",
|
||||
],
|
||||
where: { profileId, status: true, isDeleted: false },
|
||||
});
|
||||
|
|
@ -834,6 +840,24 @@ export class PosMasterActController extends Controller {
|
|||
}),
|
||||
);
|
||||
|
||||
// Clear Redis cache หลังจากบันทึกข้อมูลเสร็จแล้ว
|
||||
// ทำงานนอก loop เพื่อ clear รอบเดียว ไม่ใช่ทุก iteration
|
||||
if (profileIdsToClearCache.size > 0) {
|
||||
await Promise.all(
|
||||
Array.from(profileIdsToClearCache).map(async (profileId) => {
|
||||
const redisClient = await this.redis.createClient({
|
||||
host: REDIS_HOST,
|
||||
port: REDIS_PORT,
|
||||
});
|
||||
|
||||
const delAsync = promisify(redisClient.del).bind(redisClient);
|
||||
await delAsync("role_" + profileId);
|
||||
await delAsync("menu_" + profileId);
|
||||
|
||||
redisClient.quit();
|
||||
}),
|
||||
);
|
||||
}
|
||||
return new HttpSuccess();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue