edit search commander
This commit is contained in:
parent
83a5d96548
commit
9b9cb56868
1 changed files with 318 additions and 522 deletions
|
|
@ -811,299 +811,200 @@ export class WorkflowController extends Controller {
|
||||||
type?: string | null;
|
type?: string | null;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
let posMasterUser = null;
|
const userKeycloak = body.keycloakId ?? request.user.sub;
|
||||||
if (body.keycloakId) {
|
|
||||||
if (body.type == "employee") {
|
// 1. Cache user lookup - ใช้ select เฉพาะ field ที่จำเป็น
|
||||||
posMasterUser = await this.posMasterEmpRepo.findOne({
|
const userSelectFields = {
|
||||||
where: {
|
id: true,
|
||||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
orgRootId: true,
|
||||||
current_holder: { keycloak: body.keycloakId },
|
orgChild1Id: true,
|
||||||
},
|
orgChild2Id: true,
|
||||||
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
orgChild3Id: true,
|
||||||
});
|
orgChild4Id: true,
|
||||||
} else {
|
orgRevisionId: true,
|
||||||
posMasterUser = await this.posMasterRepo.findOne({
|
current_holder: {
|
||||||
where: {
|
id: true,
|
||||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
posType: { id: true, posTypeName: true },
|
||||||
current_holder: { keycloak: body.keycloakId },
|
posLevel: { id: true, posLevelName: true },
|
||||||
},
|
},
|
||||||
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
};
|
||||||
});
|
|
||||||
}
|
let posMasterUser: any = null;
|
||||||
|
|
||||||
|
if (body.type === "employee") {
|
||||||
|
posMasterUser = await this.posMasterEmpRepo.findOne({
|
||||||
|
where: {
|
||||||
|
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||||
|
current_holder: { keycloak: userKeycloak },
|
||||||
|
},
|
||||||
|
select: userSelectFields,
|
||||||
|
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
if (body.type == "employee") {
|
posMasterUser = await this.posMasterRepo.findOne({
|
||||||
posMasterUser = await this.posMasterEmpRepo.findOne({
|
where: {
|
||||||
where: {
|
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
current_holder: { keycloak: userKeycloak },
|
||||||
current_holder: { keycloak: request.user.sub },
|
},
|
||||||
},
|
select: userSelectFields,
|
||||||
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
posMasterUser = await this.posMasterRepo.findOne({
|
|
||||||
where: {
|
|
||||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
|
||||||
current_holder: { keycloak: request.user.sub },
|
|
||||||
},
|
|
||||||
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!posMasterUser || !posMasterUser.orgRootId) {
|
if (!posMasterUser?.orgRootId) {
|
||||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบตำแหน่งผู้ใช้งาน");
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบตำแหน่งผู้ใช้งาน");
|
||||||
}
|
}
|
||||||
|
|
||||||
let condition: any = [];
|
// 2. Pre-calculate conditions - ย้ายออกมาข้างนอก
|
||||||
|
const posType = posMasterUser.current_holder?.posType?.posTypeName;
|
||||||
|
const posLevel = posMasterUser.current_holder?.posLevel?.posLevelName;
|
||||||
|
|
||||||
let conditionOfficer: any = {
|
const isLowLevel =
|
||||||
|
(posType === "ทั่วไป" && ["ชำนาญงาน", "ปฏิบัติงาน"].includes(posLevel)) ||
|
||||||
|
(posType === "วิชาการ" && ["ปฏิบัติการ", "ชำนาญการ"].includes(posLevel));
|
||||||
|
|
||||||
|
const isMidLevel =
|
||||||
|
(posType === "ทั่วไป" && posLevel === "อาวุโส") ||
|
||||||
|
(posType === "วิชาการ" && posLevel === "ชำนาญการพิเศษ") ||
|
||||||
|
(posType === "อำนวยการ" && posLevel === "ต้น");
|
||||||
|
|
||||||
|
// 3. สร้าง conditions แบบ optimized
|
||||||
|
const baseCondition = {
|
||||||
isDirector: true,
|
isDirector: true,
|
||||||
isOfficer: true,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
orgRevisionId: posMasterUser.orgRevisionId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const conditionOfficer = {
|
||||||
|
...baseCondition,
|
||||||
|
isOfficer: true,
|
||||||
orgChild1Id: IsNull(),
|
orgChild1Id: IsNull(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type.trim().toUpperCase() == "OPERATE" || body.type == "employee") {
|
let mainConditions: any[] = [];
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
if (type.trim().toUpperCase() === "OPERATE" || body.type === "employee") {
|
||||||
orgRootId: posMasterUser.orgRootId,
|
mainConditions = [
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
{ ...baseCondition, orgRootId: posMasterUser.orgRootId, orgChild1Id: IsNull() },
|
||||||
orgChild1Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: posMasterUser.orgChild2Id,
|
|
||||||
orgChild3Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: posMasterUser.orgChild2Id,
|
|
||||||
orgChild3Id: posMasterUser.orgChild3Id,
|
|
||||||
orgChild4Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: posMasterUser.orgChild2Id,
|
|
||||||
orgChild3Id: posMasterUser.orgChild3Id,
|
|
||||||
orgChild4Id: posMasterUser.orgChild4Id,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
condition = [
|
|
||||||
{
|
{
|
||||||
isDirector: true,
|
...baseCondition,
|
||||||
orgRootId: posMasterUser.orgRootId,
|
orgRootId: posMasterUser.orgRootId,
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: IsNull(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...baseCondition,
|
||||||
|
orgRootId: posMasterUser.orgRootId,
|
||||||
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: posMasterUser.orgChild2Id,
|
||||||
|
orgChild3Id: IsNull(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...baseCondition,
|
||||||
|
orgRootId: posMasterUser.orgRootId,
|
||||||
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: posMasterUser.orgChild2Id,
|
||||||
|
orgChild3Id: posMasterUser.orgChild3Id,
|
||||||
|
orgChild4Id: IsNull(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...baseCondition,
|
||||||
|
orgRootId: posMasterUser.orgRootId,
|
||||||
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: posMasterUser.orgChild2Id,
|
||||||
|
orgChild3Id: posMasterUser.orgChild3Id,
|
||||||
|
orgChild4Id: posMasterUser.orgChild4Id,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (
|
} else if (isLowLevel) {
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
|
mainConditions = [
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญงาน") ||
|
{
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
|
...baseCondition,
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ปฏิบัติงาน") ||
|
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
|
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ปฏิบัติการ") ||
|
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
|
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญการ")
|
|
||||||
) {
|
|
||||||
condition = {
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
orgRootId: posMasterUser.orgRootId,
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: IsNull(),
|
orgChild1Id: IsNull(),
|
||||||
orgChild2Id: IsNull(),
|
orgChild2Id: IsNull(),
|
||||||
orgChild3Id: IsNull(),
|
orgChild3Id: IsNull(),
|
||||||
orgChild4Id: IsNull(),
|
orgChild4Id: IsNull(),
|
||||||
};
|
},
|
||||||
} else if (
|
];
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
|
} else if (isMidLevel) {
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "อาวุโส") ||
|
mainConditions = [
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
|
{
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญการพิเศษ") ||
|
...baseCondition,
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "อำนวยการ" &&
|
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ต้น")
|
|
||||||
) {
|
|
||||||
condition = {
|
|
||||||
isDirector: true,
|
|
||||||
isDeputy: true,
|
isDeputy: true,
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: IsNull(),
|
orgChild1Id: IsNull(),
|
||||||
orgChild2Id: IsNull(),
|
orgChild2Id: IsNull(),
|
||||||
orgChild3Id: IsNull(),
|
orgChild3Id: IsNull(),
|
||||||
orgChild4Id: IsNull(),
|
orgChild4Id: IsNull(),
|
||||||
};
|
},
|
||||||
} else {
|
];
|
||||||
}
|
} else {
|
||||||
|
mainConditions = [{ ...baseCondition, orgRootId: posMasterUser.orgRootId }];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.isAct == true) {
|
// 4. สร้าง optimized query builder
|
||||||
const [lists, total] = await AppDataSource.getRepository(viewDirectorActing)
|
const repository = body.isAct
|
||||||
.createQueryBuilder("viewDirectorActing")
|
? AppDataSource.getRepository(viewDirectorActing)
|
||||||
.andWhere(
|
: AppDataSource.getRepository(viewDirector);
|
||||||
new Brackets((qb) => {
|
|
||||||
qb.orWhere(condition).orWhere(conditionOfficer);
|
const queryBuilder = repository.createQueryBuilder("entity");
|
||||||
}),
|
|
||||||
)
|
// 5. แยก WHERE conditions ให้เร็วขึ้น
|
||||||
.andWhere(
|
queryBuilder.where(
|
||||||
new Brackets((qb) => {
|
new Brackets((qb) => {
|
||||||
qb.orWhere(
|
mainConditions.forEach((condition, index) => {
|
||||||
body.keyword != null && body.keyword != ""
|
if (index === 0) {
|
||||||
? "CONCAT(viewDirectorActing.prefix,viewDirectorActing.firstName,' ',viewDirectorActing.lastName) LIKE :keyword"
|
qb.where(condition);
|
||||||
: "1=1",
|
} else {
|
||||||
{
|
qb.orWhere(condition);
|
||||||
keyword: `%${body.keyword}%`,
|
}
|
||||||
},
|
});
|
||||||
)
|
qb.orWhere(conditionOfficer);
|
||||||
.orWhere(
|
}),
|
||||||
body.keyword != null && body.keyword != ""
|
);
|
||||||
? "viewDirectorActing.citizenId LIKE :keyword"
|
|
||||||
: "1=1",
|
// 6. ปรับ search conditions ให้เร็วขึ้น
|
||||||
{
|
if (body.keyword?.trim()) {
|
||||||
keyword: `%${body.keyword}%`,
|
const keyword = `%${body.keyword.trim()}%`;
|
||||||
},
|
const searchFields = [
|
||||||
)
|
"CONCAT(entity.prefix, entity.firstName, ' ', entity.lastName)",
|
||||||
.orWhere(
|
"entity.citizenId",
|
||||||
body.keyword != null && body.keyword != ""
|
"entity.position",
|
||||||
? "viewDirectorActing.position LIKE :keyword"
|
"entity.posLevel",
|
||||||
: "1=1",
|
"entity.posType",
|
||||||
{
|
"entity.posNo",
|
||||||
keyword: `%${body.keyword}%`,
|
"entity.posExecutiveName",
|
||||||
},
|
];
|
||||||
)
|
|
||||||
.orWhere(
|
if (body.isAct) {
|
||||||
body.keyword != null && body.keyword != ""
|
searchFields.push("entity.actFullName");
|
||||||
? "viewDirectorActing.posLevel LIKE :keyword"
|
}
|
||||||
: "1=1",
|
|
||||||
{
|
queryBuilder.andWhere(
|
||||||
keyword: `%${body.keyword}%`,
|
`(${searchFields.map((field) => `${field} LIKE :keyword`).join(" OR ")})`,
|
||||||
},
|
{ keyword },
|
||||||
)
|
);
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.posType LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.actFullName LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.posNo LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.posExecutiveName LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.skip((body.page - 1) * body.pageSize)
|
|
||||||
.take(body.pageSize)
|
|
||||||
.getManyAndCount();
|
|
||||||
return new HttpSuccess({ data: lists, total });
|
|
||||||
} else {
|
|
||||||
const [lists, total] = await AppDataSource.getRepository(viewDirector)
|
|
||||||
.createQueryBuilder("viewDirector")
|
|
||||||
.andWhere(
|
|
||||||
new Brackets((qb) => {
|
|
||||||
qb.orWhere(condition).orWhere(conditionOfficer);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.andWhere(
|
|
||||||
new Brackets((qb) => {
|
|
||||||
qb.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "CONCAT(viewDirector.prefix,viewDirector.firstName,' ',viewDirector.lastName) LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.citizenId LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.position LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posLevel LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posType LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posNo LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posExecutiveName LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.skip((body.page - 1) * body.pageSize)
|
|
||||||
.take(body.pageSize)
|
|
||||||
.getManyAndCount();
|
|
||||||
return new HttpSuccess({ data: lists, total });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 7. Execute พร้อมกัน - ใช้ Promise.all
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
queryBuilder
|
||||||
|
.skip((body.page - 1) * body.pageSize)
|
||||||
|
.take(body.pageSize)
|
||||||
|
.getMany(),
|
||||||
|
queryBuilder.getCount(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 8. ปรับ response mapping (ถ้าจำเป็น)
|
||||||
|
const processedData = body.isAct
|
||||||
|
? data
|
||||||
|
: data.map((x: any) => ({
|
||||||
|
...x,
|
||||||
|
posExecutiveNameOrg:
|
||||||
|
x.posExecutiveName +
|
||||||
|
(x.orgChild4 ?? x.orgChild3 ?? x.orgChild2 ?? x.orgChild1 ?? x.orgRoot ?? ""),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess({ data: processedData, total });
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -1122,290 +1023,185 @@ export class WorkflowController extends Controller {
|
||||||
keycloakId?: string | null;
|
keycloakId?: string | null;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
let posMasterUser: PosMaster = new PosMaster();
|
const userKeycloak = body.keycloakId ?? request.user.sub;
|
||||||
if (body.keycloakId) {
|
|
||||||
posMasterUser = (await this.posMasterRepo.findOne({
|
// 1. ใช้ select เฉพาะ field ที่จำเป็น - เหมือน getProfilePlacement
|
||||||
where: {
|
const userSelectFields = {
|
||||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
id: true,
|
||||||
current_holder: { keycloak: body.keycloakId },
|
orgRootId: true,
|
||||||
},
|
orgChild1Id: true,
|
||||||
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
orgChild2Id: true,
|
||||||
})) as PosMaster;
|
orgChild3Id: true,
|
||||||
} else {
|
orgChild4Id: true,
|
||||||
posMasterUser = (await this.posMasterRepo.findOne({
|
orgRevisionId: true,
|
||||||
where: {
|
current_holder: {
|
||||||
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
id: true,
|
||||||
current_holder: { keycloak: request.user.sub },
|
posType: { id: true, posTypeName: true },
|
||||||
},
|
posLevel: { id: true, posLevelName: true },
|
||||||
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
},
|
||||||
})) as PosMaster;
|
};
|
||||||
|
|
||||||
|
const posMasterUser = await this.posMasterRepo.findOne({
|
||||||
|
where: {
|
||||||
|
orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
|
||||||
|
current_holder: { keycloak: userKeycloak },
|
||||||
|
},
|
||||||
|
select: userSelectFields,
|
||||||
|
relations: ["current_holder", "current_holder.posType", "current_holder.posLevel"],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!posMasterUser?.orgRootId) {
|
||||||
|
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบตำแหน่งผู้ใช้งาน");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!posMasterUser || !posMasterUser.orgRootId)
|
// 2. Pre-calculate conditions - ปรับให้เหมือน getProfilePlacement
|
||||||
throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบตำแหน่งผู้ใช้งาน");
|
const posType = posMasterUser.current_holder?.posType?.posTypeName;
|
||||||
|
const posLevel = posMasterUser.current_holder?.posLevel?.posLevelName;
|
||||||
|
|
||||||
let condition: any = [];
|
const isLowLevel =
|
||||||
|
(posType === "ทั่วไป" && ["ชำนาญงาน", "ปฏิบัติงาน"].includes(posLevel)) ||
|
||||||
|
(posType === "วิชาการ" && ["ปฏิบัติการ", "ชำนาญการ"].includes(posLevel));
|
||||||
|
|
||||||
let conditionOfficer: any = {
|
const isMidLevel =
|
||||||
|
(posType === "ทั่วไป" && posLevel === "อาวุโส") ||
|
||||||
|
(posType === "วิชาการ" && posLevel === "ชำนาญการพิเศษ") ||
|
||||||
|
(posType === "อำนวยการ" && posLevel === "ต้น");
|
||||||
|
|
||||||
|
// 3. สร้าง conditions แบบ optimized
|
||||||
|
const baseCondition = {
|
||||||
isDirector: true,
|
isDirector: true,
|
||||||
isOfficer: true,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
orgRevisionId: posMasterUser.orgRevisionId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const conditionOfficer = {
|
||||||
|
...baseCondition,
|
||||||
|
isOfficer: true,
|
||||||
orgChild1Id: IsNull(),
|
orgChild1Id: IsNull(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type.trim().toUpperCase() == "OPERATE") {
|
let mainConditions: any[] = [];
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
if (type.trim().toUpperCase() === "OPERATE") {
|
||||||
orgRootId: posMasterUser.orgRootId,
|
mainConditions = [
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
{ ...baseCondition, orgRootId: posMasterUser.orgRootId, orgChild1Id: IsNull() },
|
||||||
orgChild1Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: posMasterUser.orgChild2Id,
|
|
||||||
orgChild3Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: posMasterUser.orgChild2Id,
|
|
||||||
orgChild3Id: posMasterUser.orgChild3Id,
|
|
||||||
orgChild4Id: IsNull(),
|
|
||||||
});
|
|
||||||
condition.push({
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: posMasterUser.orgChild1Id,
|
|
||||||
orgChild2Id: posMasterUser.orgChild2Id,
|
|
||||||
orgChild3Id: posMasterUser.orgChild3Id,
|
|
||||||
orgChild4Id: posMasterUser.orgChild4Id,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
condition = [
|
|
||||||
{
|
{
|
||||||
isDirector: true,
|
...baseCondition,
|
||||||
orgRootId: posMasterUser.orgRootId,
|
orgRootId: posMasterUser.orgRootId,
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: IsNull(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...baseCondition,
|
||||||
|
orgRootId: posMasterUser.orgRootId,
|
||||||
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: posMasterUser.orgChild2Id,
|
||||||
|
orgChild3Id: IsNull(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...baseCondition,
|
||||||
|
orgRootId: posMasterUser.orgRootId,
|
||||||
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: posMasterUser.orgChild2Id,
|
||||||
|
orgChild3Id: posMasterUser.orgChild3Id,
|
||||||
|
orgChild4Id: IsNull(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...baseCondition,
|
||||||
|
orgRootId: posMasterUser.orgRootId,
|
||||||
|
orgChild1Id: posMasterUser.orgChild1Id,
|
||||||
|
orgChild2Id: posMasterUser.orgChild2Id,
|
||||||
|
orgChild3Id: posMasterUser.orgChild3Id,
|
||||||
|
orgChild4Id: posMasterUser.orgChild4Id,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
if (
|
} else if (isLowLevel) {
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
|
mainConditions = [
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญงาน") ||
|
{
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
|
...baseCondition,
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ปฏิบัติงาน") ||
|
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
|
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ปฏิบัติการ") ||
|
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
|
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญการ")
|
|
||||||
) {
|
|
||||||
condition = {
|
|
||||||
isDirector: true,
|
|
||||||
orgRootId: posMasterUser.orgRootId,
|
orgRootId: posMasterUser.orgRootId,
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: IsNull(),
|
orgChild1Id: IsNull(),
|
||||||
orgChild2Id: IsNull(),
|
orgChild2Id: IsNull(),
|
||||||
orgChild3Id: IsNull(),
|
orgChild3Id: IsNull(),
|
||||||
orgChild4Id: IsNull(),
|
orgChild4Id: IsNull(),
|
||||||
};
|
},
|
||||||
} else if (
|
];
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "ทั่วไป" &&
|
} else if (isMidLevel) {
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "อาวุโส") ||
|
mainConditions = [
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "วิชาการ" &&
|
{
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ชำนาญการพิเศษ") ||
|
...baseCondition,
|
||||||
(posMasterUser.current_holder.posType.posTypeName == "อำนวยการ" &&
|
|
||||||
posMasterUser.current_holder.posLevel.posLevelName == "ต้น")
|
|
||||||
) {
|
|
||||||
condition = {
|
|
||||||
isDirector: true,
|
|
||||||
isDeputy: true,
|
isDeputy: true,
|
||||||
orgRevisionId: posMasterUser.orgRevisionId,
|
|
||||||
orgChild1Id: IsNull(),
|
orgChild1Id: IsNull(),
|
||||||
orgChild2Id: IsNull(),
|
orgChild2Id: IsNull(),
|
||||||
orgChild3Id: IsNull(),
|
orgChild3Id: IsNull(),
|
||||||
orgChild4Id: IsNull(),
|
orgChild4Id: IsNull(),
|
||||||
};
|
},
|
||||||
} else {
|
];
|
||||||
}
|
} else {
|
||||||
|
mainConditions = [{ ...baseCondition, orgRootId: posMasterUser.orgRootId }];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.isAct == true) {
|
// 4. สร้าง optimized query builder
|
||||||
const [lists, total] = await AppDataSource.getRepository(viewDirectorActing)
|
const repository = body.isAct
|
||||||
.createQueryBuilder("viewDirectorActing")
|
? AppDataSource.getRepository(viewDirectorActing)
|
||||||
.andWhere(
|
: AppDataSource.getRepository(viewDirector);
|
||||||
new Brackets((qb) => {
|
|
||||||
qb.orWhere(condition).orWhere(conditionOfficer);
|
const queryBuilder = repository.createQueryBuilder("entity");
|
||||||
}),
|
|
||||||
)
|
// 5. แยก WHERE conditions ให้เร็วขึ้น
|
||||||
.andWhere(
|
queryBuilder.where(
|
||||||
new Brackets((qb) => {
|
new Brackets((qb) => {
|
||||||
qb.orWhere(
|
mainConditions.forEach((condition, index) => {
|
||||||
body.keyword != null && body.keyword != ""
|
if (index === 0) {
|
||||||
? "CONCAT(viewDirectorActing.prefix,viewDirectorActing.firstName,' ',viewDirectorActing.lastName) LIKE :keyword"
|
qb.where(condition);
|
||||||
: "1=1",
|
} else {
|
||||||
{
|
qb.orWhere(condition);
|
||||||
keyword: `%${body.keyword}%`,
|
}
|
||||||
},
|
});
|
||||||
)
|
qb.orWhere(conditionOfficer);
|
||||||
.orWhere(
|
}),
|
||||||
body.keyword != null && body.keyword != ""
|
);
|
||||||
? "viewDirectorActing.citizenId LIKE :keyword"
|
|
||||||
: "1=1",
|
// 6. ปรับ search conditions ให้เร็วขึ้น - แบบเดียวกับ getProfilePlacement
|
||||||
{
|
if (body.keyword?.trim()) {
|
||||||
keyword: `%${body.keyword}%`,
|
const keyword = `%${body.keyword.trim()}%`;
|
||||||
},
|
const searchFields = [
|
||||||
)
|
"CONCAT(entity.prefix, entity.firstName, ' ', entity.lastName)",
|
||||||
.orWhere(
|
"entity.citizenId",
|
||||||
body.keyword != null && body.keyword != ""
|
"entity.position",
|
||||||
? "viewDirectorActing.position LIKE :keyword"
|
"entity.posLevel",
|
||||||
: "1=1",
|
"entity.posType",
|
||||||
{
|
"entity.posNo",
|
||||||
keyword: `%${body.keyword}%`,
|
"entity.posExecutiveName",
|
||||||
},
|
];
|
||||||
)
|
|
||||||
.orWhere(
|
if (body.isAct) {
|
||||||
body.keyword != null && body.keyword != ""
|
searchFields.push("entity.actFullName");
|
||||||
? "viewDirectorActing.posLevel LIKE :keyword"
|
}
|
||||||
: "1=1",
|
|
||||||
{
|
queryBuilder.andWhere(
|
||||||
keyword: `%${body.keyword}%`,
|
`(${searchFields.map((field) => `${field} LIKE :keyword`).join(" OR ")})`,
|
||||||
},
|
{ keyword },
|
||||||
)
|
);
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.posType LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.actFullName LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.posNo LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirectorActing.posExecutiveName LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.skip((body.page - 1) * body.pageSize)
|
|
||||||
.take(body.pageSize)
|
|
||||||
.getManyAndCount();
|
|
||||||
const data = lists.map((x) => ({
|
|
||||||
...x,
|
|
||||||
posExecutiveNameOrg:
|
|
||||||
x.posExecutiveName +
|
|
||||||
(x.orgChild4 ?? x.orgChild3 ?? x.orgChild2 ?? x.orgChild1 ?? x.orgRoot ?? ""),
|
|
||||||
}));
|
|
||||||
return new HttpSuccess({ data: data, total });
|
|
||||||
} else {
|
|
||||||
const [lists, total] = await AppDataSource.getRepository(viewDirector)
|
|
||||||
.createQueryBuilder("viewDirector")
|
|
||||||
.andWhere(
|
|
||||||
new Brackets((qb) => {
|
|
||||||
qb.orWhere(condition).orWhere(conditionOfficer);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.andWhere(
|
|
||||||
new Brackets((qb) => {
|
|
||||||
qb.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "CONCAT(viewDirector.prefix,viewDirector.firstName,' ',viewDirector.lastName) LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.citizenId LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.position LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posLevel LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posType LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posNo LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.orWhere(
|
|
||||||
body.keyword != null && body.keyword != ""
|
|
||||||
? "viewDirector.posExecutiveName LIKE :keyword"
|
|
||||||
: "1=1",
|
|
||||||
{
|
|
||||||
keyword: `%${body.keyword}%`,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.skip((body.page - 1) * body.pageSize)
|
|
||||||
.take(body.pageSize)
|
|
||||||
.getManyAndCount();
|
|
||||||
const data = lists.map((x) => ({
|
|
||||||
...x,
|
|
||||||
posExecutiveNameOrg:
|
|
||||||
x.posExecutiveName +
|
|
||||||
(x.orgChild4 ?? x.orgChild3 ?? x.orgChild2 ?? x.orgChild1 ?? x.orgRoot ?? ""),
|
|
||||||
}));
|
|
||||||
return new HttpSuccess({ data: data, total });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 7. Execute พร้อมกัน - ใช้ Promise.all
|
||||||
|
const [data, total] = await Promise.all([
|
||||||
|
queryBuilder
|
||||||
|
.skip((body.page - 1) * body.pageSize)
|
||||||
|
.take(body.pageSize)
|
||||||
|
.getMany(),
|
||||||
|
queryBuilder.getCount(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 8. ปรับ response mapping
|
||||||
|
const processedData = data.map((x: any) => ({
|
||||||
|
...x,
|
||||||
|
posExecutiveNameOrg:
|
||||||
|
x.posExecutiveName +
|
||||||
|
(x.orgChild4 ?? x.orgChild3 ?? x.orgChild2 ?? x.orgChild1 ?? x.orgRoot ?? ""),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess({ data: processedData, total });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue