แก้ไข rabbitMQ เผยแพร่โครงสร้างค้าง
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m2s

This commit is contained in:
Adisak 2026-04-29 14:27:50 +07:00
parent 7c6991abe5
commit d822626404

View file

@ -631,43 +631,67 @@ async function handler_org(msg: amqp.ConsumeMessage): Promise<boolean> {
}
const _null: any = null;
for (const item of posMaster) {
// ===== BATCH PROCESSING: เตรียมข้อมูลก่อน loop =====
// 1. รวบรวม profileIds ทั้งหมดที่ต้องอัพเดท
const profileIds = posMaster
.filter(item => item.next_holderId != null)
.map(item => item.next_holderId!)
.filter(id => id != null && id !== "");
// 2. Batch load profiles ทั้งหมดในครั้งเดียว (แก้ปัญหา N+1 Query)
const profilesMap = new Map<string, Profile>();
if (profileIds.length > 0) {
const profiles = await repoProfile.findBy({
id: In(profileIds)
});
profiles.forEach(p => profilesMap.set(p.id, p));
}
// 3. เตรียม arrays สำหรับ batch operations
const profilesToSave: Profile[] = [];
const posMasterAssignsToSave: PosMasterAssign[] = [];
const historyCreateIds: string[] = [];
const posMasterUpdates: { id: string; current_holderId: string | null | undefined }[] = [];
// ===== LOOP: เก็บข้อมูลทั้งหมด =====
for (const item of posMaster) {
const dna = item.ancestorDNA?.trim();
const oldPm = dna ? oldPosMasterMap.get(dna) : null;
// Task #2160 Clone posMasterAssign
// Task #2160 Clone posMasterAssign
const assigns = assignMap.get(item.ancestorDNA);
if (assigns && assigns.length > 0) {
const newAssigns = assigns.map(({ id, ...fields }) => ({
...fields, // copy ทุก field ยกเว้น id
posMasterId: item.id, // ผูกกับ posMasterId ใหม่
createdAt: lastUpdatedAt,
createdFullName: lastUpdateFullName,
createdUserId: lastUpdateUserId,
lastUpdatedAt: lastUpdatedAt,
lastUpdateFullName: lastUpdateFullName,
lastUpdateUserId: lastUpdateUserId,
}));
await posMasterAssignRepository.save(newAssigns);
const newAssigns = assigns.map(({ id, ...fields }) =>
posMasterAssignRepository.create({
...fields,
posMasterId: item.id,
createdAt: lastUpdatedAt,
createdFullName: lastUpdateFullName,
createdUserId: lastUpdateUserId,
lastUpdatedAt: lastUpdatedAt,
lastUpdateFullName: lastUpdateFullName,
lastUpdateUserId: lastUpdateUserId,
})
);
posMasterAssignsToSave.push(...newAssigns);
}
// อัพเดท org และ posMasterNo ตลอดไม่ต้องดัก isSit
if (item.next_holderId != null) {
const profile = await repoProfile.findOne({
where: { id: item.next_holderId == null ? "" : item.next_holderId },
});
if (profile != null) {
// เตรียมข้อมูลสำหรับ update profile
if (item.next_holderId != null && item.next_holderId !== "") {
const profile = profilesMap.get(item.next_holderId);
if (profile) {
profile.posMasterNo = getPosMasterNo(item) ?? _null;
profile.org = getOrgFullName(item) ?? _null;
// ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ
if (!item.isSit && item.positions.length > 0) {
let position = await item.positions.find((x) => x.positionIsSelected == true);
let position = item.positions.find((x) => x.positionIsSelected == true);
if (position == null) {
position = await item.positions.find((x) => x.posLevelId == profile?.posLevelId);
position = item.positions.find((x) => x.posLevelId == profile?.posLevelId);
if (position == null) {
position = await item.positions.sort((a, b) => a.orderNo - b.orderNo)[0];
const sorted = [...item.positions].sort((a, b) => a.orderNo - b.orderNo);
position = sorted[0];
}
}
@ -679,29 +703,59 @@ async function handler_org(msg: amqp.ConsumeMessage): Promise<boolean> {
profile.positionArea = position?.positionArea ?? _null;
profile.positionExecutiveField = position?.positionExecutiveField ?? _null;
}
await repoProfile.save(profile);
profilesToSave.push(profile);
}
}
// item.current_holderId = item.next_holderId;
// item.next_holderId = null;
// item.lastUpdateUserId = lastUpdateUserId;
// item.lastUpdateFullName = lastUpdateFullName;
// item.lastUpdatedAt = lastUpdatedAt;
await repoPosmaster.update(item.id, {
// เก็บข้อมูลสำหรับ update posMaster
posMasterUpdates.push({
id: item.id,
current_holderId: item.next_holderId,
});
// เก็บ IDs ที่ต้องสร้าง history
const oldHolderId = oldPm ? oldPm.current_holderId : null;
const newHolderId = item?.next_holderId;
const isHolderChanged = oldHolderId !== newHolderId;
if (isHolderChanged) {
historyCreateIds.push(item.id);
}
}
// ===== BATCH EXECUTION: save ทีละ batch =====
// 4. Batch save posMasterAssign (chunk 500)
if (posMasterAssignsToSave.length > 0) {
const chunks = chunkArray(posMasterAssignsToSave, 500);
for (const chunk of chunks) {
await posMasterAssignRepository.save(chunk);
}
}
// 5. Batch save profiles (chunk 200)
if (profilesToSave.length > 0) {
const chunks = chunkArray(profilesToSave, 200);
for (const chunk of chunks) {
await repoProfile.save(chunk);
}
}
// 6. Batch update posMasters
for (const update of posMasterUpdates) {
await repoPosmaster.update(update.id, {
current_holderId: update.current_holderId,
next_holderId: null,
lastUpdateUserId,
lastUpdateFullName,
lastUpdatedAt,
});
}
const oldHolderId = oldPm ? oldPm.current_holderId : null;
const newHolderId = item ? item.next_holderId : null;
const isHolderChanged = oldHolderId !== newHolderId;
if (isHolderChanged) {
await CreatePosMasterHistoryOfficer(item.id, null);
}
// 7. Batch create history
for (const id of historyCreateIds) {
await CreatePosMasterHistoryOfficer(id, null);
}
for (const act of oldposMasterAct) {