Merge branch 'feat/web-service-external' into develop
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m10s
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m10s
* feat/web-service-external: fix api web service
This commit is contained in:
commit
bcc27002db
2 changed files with 367 additions and 36 deletions
|
|
@ -316,12 +316,12 @@ export class ApiManageController extends Controller {
|
|||
description: "ข้อมูลส่วนราชการ ระดับที่ 4",
|
||||
system: ["position"],
|
||||
},
|
||||
{
|
||||
name: "Profile",
|
||||
repository: this.profileRepository,
|
||||
description: "ข้อมูลคนครอง",
|
||||
system: ["position"],
|
||||
},
|
||||
// {
|
||||
// name: "Profile",
|
||||
// repository: this.profileRepository,
|
||||
// description: "ข้อมูลคนครอง",
|
||||
// system: ["position"],
|
||||
// },
|
||||
];
|
||||
|
||||
private readonly DEFAULT_PAGE_SIZE = 10; // ขนาดหน้าเริ่มต้น
|
||||
|
|
@ -443,6 +443,27 @@ export class ApiManageController extends Controller {
|
|||
},
|
||||
};
|
||||
|
||||
// การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ ProfileEmployee entity
|
||||
private readonly PROFILEEMPLOYEE_FIELD_REPLACEMENTS: Record<
|
||||
string,
|
||||
{ propertyName: string; type: string; comment: string; joinTable: string; joinField: string }
|
||||
> = {
|
||||
posLevelId: {
|
||||
propertyName: "posLevelName",
|
||||
type: "string",
|
||||
comment: "ระดับชั้นงาน",
|
||||
joinTable: "EmployeePosLevel",
|
||||
joinField: "posLevelName",
|
||||
},
|
||||
posTypeId: {
|
||||
propertyName: "posTypeName",
|
||||
type: "string",
|
||||
comment: "กลุ่มงาน",
|
||||
joinTable: "EmployeePosType",
|
||||
joinField: "posTypeName",
|
||||
},
|
||||
};
|
||||
|
||||
private validateSuperAdminRole(user: any): void {
|
||||
if (!user.role.includes("SUPER_ADMIN")) {
|
||||
throw new HttpError(HttpStatusCode.FORBIDDEN, "คุณไม่มีสิทธิ์ในการเข้าถึงข้อมูลนี้");
|
||||
|
|
@ -533,6 +554,26 @@ export class ApiManageController extends Controller {
|
|||
columns = [...columns, ...nameFields];
|
||||
}
|
||||
|
||||
// Special handling for ProfileEmployee entity - replace ID fields with name fields
|
||||
if (name === "ProfileEmployee") {
|
||||
const replacementKeys = Object.keys(this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS);
|
||||
|
||||
// Remove ID fields that should be replaced
|
||||
columns = columns.filter(
|
||||
(col: { propertyName: string }) => !replacementKeys.includes(col.propertyName),
|
||||
);
|
||||
|
||||
// Add the corresponding name fields
|
||||
const nameFields = replacementKeys.map((key) => ({
|
||||
propertyName: this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[key].propertyName,
|
||||
type: "string",
|
||||
comment: this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[key].comment,
|
||||
key: this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[key].propertyName,
|
||||
}));
|
||||
|
||||
columns = [...columns, ...nameFields];
|
||||
}
|
||||
|
||||
// Special handling for PosMaster entity - add Profile fields for holder information
|
||||
if (name === "PosMaster") {
|
||||
// Add Profile fields that are accessible via current_holder relation
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ import { isPermissionRequest } from "../middlewares/authWebService";
|
|||
import { RequestWithUserWebService } from "../middlewares/user";
|
||||
import { OrgRevision } from "../entities/OrgRevision";
|
||||
import { ApiHistory } from "../entities/ApiHistory";
|
||||
import { OrgChild1 } from "../entities/OrgChild1";
|
||||
import { OrgChild2 } from "../entities/OrgChild2";
|
||||
import { OrgChild3 } from "../entities/OrgChild3";
|
||||
import { OrgChild4 } from "../entities/OrgChild4";
|
||||
import { SystemCode } from "./../interfaces/api-type";
|
||||
@Route("api/v1/org/api-service")
|
||||
@Tags("ApiKey")
|
||||
|
|
@ -91,6 +95,23 @@ export class ApiWebServiceController extends Controller {
|
|||
},
|
||||
};
|
||||
|
||||
// การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ ProfileEmployee entity
|
||||
private readonly PROFILEEMPLOYEE_FIELD_REPLACEMENTS: Record<
|
||||
string,
|
||||
{ propertyName: string; joinRelation: string; joinField: string }
|
||||
> = {
|
||||
posTypeName: {
|
||||
propertyName: "posTypeId",
|
||||
joinRelation: "posType",
|
||||
joinField: "posTypeName",
|
||||
},
|
||||
posLevelName: {
|
||||
propertyName: "posLevelId",
|
||||
joinRelation: "posLevel",
|
||||
joinField: "posLevelName",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* build posMaster permission condition
|
||||
* @summary สร้างเงื่อนไขการกรองข้อมูลตามสิทธิ์การเข้าถึง
|
||||
|
|
@ -198,6 +219,13 @@ export class ApiWebServiceController extends Controller {
|
|||
await isPermissionRequest(request, apiName.id);
|
||||
const offset = (page - 1) * pageSize;
|
||||
let propertyKey = apiName.apiAttributes.map((attr) => `${attr.tbName}.${attr.propertyKey}`);
|
||||
const selectedFieldsByTable: Record<string, Set<string>> = {};
|
||||
apiName.apiAttributes.forEach((attr) => {
|
||||
if (!selectedFieldsByTable[attr.tbName]) {
|
||||
selectedFieldsByTable[attr.tbName] = new Set<string>();
|
||||
}
|
||||
selectedFieldsByTable[attr.tbName].add(attr.propertyKey);
|
||||
});
|
||||
|
||||
let tbMain: string = "";
|
||||
let condition: string = "1=1";
|
||||
|
|
@ -225,7 +253,7 @@ export class ApiWebServiceController extends Controller {
|
|||
condition = `PosMaster.orgRevisionId = "${revision?.id}"`;
|
||||
}
|
||||
|
||||
let posMasterCondition: string = "";
|
||||
let posMasterCondition: string = "1=1";
|
||||
let posMasterAlias: string = "";
|
||||
|
||||
// Special handling for Profile and ProfileEmployee systems with permission filtering
|
||||
|
|
@ -337,6 +365,13 @@ export class ApiWebServiceController extends Controller {
|
|||
...new Set(propertyKey.map((x) => x.split(".")[0]).filter((tb) => tb !== tbMain)),
|
||||
];
|
||||
|
||||
// Organization hierarchy is assembled in a separate step; keep main query focused on OrgRoot only.
|
||||
if (tbMain === "OrgRoot") {
|
||||
const orgChildTables = new Set(["OrgChild1", "OrgChild2", "OrgChild3", "OrgChild4"]);
|
||||
propertyKey = propertyKey.filter((key) => !orgChildTables.has(key.split(".")[0]));
|
||||
propertyOtherKey = propertyOtherKey.filter((tb) => !orgChildTables.has(tb));
|
||||
}
|
||||
|
||||
// สำหรับ Profile: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey
|
||||
const profileFieldJoins: Record<string, string> = {}; // alias -> relationName
|
||||
if (tbMain === "Profile") {
|
||||
|
|
@ -356,7 +391,7 @@ export class ApiWebServiceController extends Controller {
|
|||
|
||||
// สำหรับ Position: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey
|
||||
const positionFieldJoins: Record<string, string> = {}; // alias -> relationName
|
||||
if (tbMain === "Position") {
|
||||
if (tbMain === "Position" || tbMain === "PosMaster") {
|
||||
propertyKey = propertyKey.map((key) => {
|
||||
const [table, field] = key.split(".");
|
||||
if (table === "Position") {
|
||||
|
|
@ -371,21 +406,56 @@ export class ApiWebServiceController extends Controller {
|
|||
});
|
||||
}
|
||||
|
||||
// สำหรับ ProfileEmployee: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey
|
||||
const profileEmployeeFieldJoins: Record<string, string> = {}; // alias -> relationName
|
||||
if (tbMain === "ProfileEmployee") {
|
||||
propertyKey = propertyKey.map((key) => {
|
||||
const [table, field] = key.split(".");
|
||||
if (table === "ProfileEmployee") {
|
||||
const replacement = this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[field];
|
||||
if (replacement) {
|
||||
const alias = `${table}_${replacement.joinRelation}`;
|
||||
profileEmployeeFieldJoins[alias] = replacement.joinRelation;
|
||||
return `${alias}.${replacement.joinField}`;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
});
|
||||
}
|
||||
|
||||
const queryBuilder = repo.createQueryBuilder(tbMain);
|
||||
|
||||
// join กับตารารอง
|
||||
if (propertyOtherKey.length > 0) {
|
||||
propertyOtherKey.forEach((tb) => {
|
||||
// Skip Profile join for PosMaster - it's handled separately below
|
||||
if (tbMain === "PosMaster" && tb === "Profile") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip Position join for PosMaster - it's handled separately below
|
||||
if (tbMain === "PosMaster" && tb === "Position") {
|
||||
return;
|
||||
}
|
||||
|
||||
const relationName = relationMap[tb];
|
||||
if (relationName) {
|
||||
queryBuilder.leftJoin(
|
||||
`${tbMain}.${relationName === "next_holder" ? "current_holder" : relationName}`, // เช็คว่าถ้าเป็น next_holder ให้ใช้ current_holder แทน
|
||||
tb,
|
||||
);
|
||||
queryBuilder.leftJoin(`${tbMain}.${relationName}`, tb);
|
||||
} else {
|
||||
// Remove fields from this table from propertyKey
|
||||
propertyKey = propertyKey.filter((key) => !key.startsWith(`${tb}.`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check if propertyKey is empty after filtering
|
||||
if (propertyKey.length === 0) {
|
||||
throw new HttpError(
|
||||
HttpStatusCode.BAD_REQUEST,
|
||||
"ไม่พบฟิลด์ที่ต้องการแสดงผล กรุณาตรวจสอบการตั้งค่า API (ไม่สามารถ join ตารางลูกได้)",
|
||||
);
|
||||
}
|
||||
|
||||
// join สำหรับฟิลด์ Profile ที่ต้องการดึงค่าจากตารางอื่น
|
||||
if (tbMain === "Profile" && Object.keys(profileFieldJoins).length > 0) {
|
||||
Object.entries(profileFieldJoins).forEach(([alias, relationName]) => {
|
||||
|
|
@ -394,8 +464,35 @@ export class ApiWebServiceController extends Controller {
|
|||
}
|
||||
|
||||
// join สำหรับฟิลด์ Position ที่ต้องการดึงค่าจากตารางอื่น
|
||||
if (tbMain === "Position" && Object.keys(positionFieldJoins).length > 0) {
|
||||
if (
|
||||
(tbMain === "Position" || tbMain === "PosMaster") &&
|
||||
Object.keys(positionFieldJoins).length > 0
|
||||
) {
|
||||
if (tbMain === "PosMaster") {
|
||||
const posMasterPositionRelation = relationMap["Position"];
|
||||
if (!posMasterPositionRelation) {
|
||||
throw new HttpError(
|
||||
HttpStatusCode.BAD_REQUEST,
|
||||
"ไม่พบความสัมพันธ์ระหว่าง PosMaster กับ Position กรุณาตรวจสอบการตั้งค่า API",
|
||||
);
|
||||
}
|
||||
|
||||
// Join PosMaster -> Position once using actual relation name from metadata
|
||||
queryBuilder.leftJoin(`PosMaster.${posMasterPositionRelation}`, "Position");
|
||||
}
|
||||
|
||||
Object.entries(positionFieldJoins).forEach(([alias, relationName]) => {
|
||||
if (tbMain === "PosMaster") {
|
||||
queryBuilder.leftJoin(`Position.${relationName}`, alias);
|
||||
} else {
|
||||
queryBuilder.leftJoin(`${tbMain}.${relationName}`, alias);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// join สำหรับฟิลด์ ProfileEmployee ที่ต้องการดึงค่าจากตารางอื่น
|
||||
if (tbMain === "ProfileEmployee" && Object.keys(profileEmployeeFieldJoins).length > 0) {
|
||||
Object.entries(profileEmployeeFieldJoins).forEach(([alias, relationName]) => {
|
||||
queryBuilder.leftJoin(`${tbMain}.${relationName}`, alias);
|
||||
});
|
||||
}
|
||||
|
|
@ -403,15 +500,24 @@ export class ApiWebServiceController extends Controller {
|
|||
// join สำหรับ PosMaster เมื่อต้องการดึงค่าจาก Profile (ข้อมูลคนครอง)
|
||||
const posMasterProfileFields: string[] = [];
|
||||
if (tbMain === "PosMaster") {
|
||||
propertyKey.forEach((key) => {
|
||||
if (key.startsWith("Profile.")) {
|
||||
posMasterProfileFields.push(key);
|
||||
}
|
||||
});
|
||||
// Collect Profile fields from both formats: "Profile.xxx" and "PosMaster.Profile.xxx"
|
||||
const extractedProfileFields = propertyKey
|
||||
.filter((key) => key.startsWith("Profile.") || key.startsWith("PosMaster.Profile."))
|
||||
.map((key) => key.replace(/^PosMaster\.Profile\./, "Profile."));
|
||||
|
||||
posMasterProfileFields.push(...new Set(extractedProfileFields));
|
||||
|
||||
// Remove Profile fields then add back normalized "Profile.xxx" form
|
||||
propertyKey = propertyKey.filter(
|
||||
(key) => !key.startsWith("Profile.") && !key.startsWith("PosMaster.Profile."),
|
||||
);
|
||||
propertyKey.push(...posMasterProfileFields);
|
||||
}
|
||||
|
||||
// join PosMaster กับ Profile เมื่อมีการขอ Profile fields
|
||||
if (tbMain === "PosMaster" && posMasterProfileFields.length > 0) {
|
||||
// Always join via current_holder (not next_holder) because PosMaster has two relations
|
||||
// to Profile and relationMap["Profile"] would resolve to next_holder (last defined in entity)
|
||||
queryBuilder.leftJoin("PosMaster.current_holder", "Profile");
|
||||
}
|
||||
|
||||
|
|
@ -434,7 +540,7 @@ export class ApiWebServiceController extends Controller {
|
|||
// propertyKey.push(`${Main}.id`);
|
||||
// }
|
||||
|
||||
// add FK
|
||||
// add PK - ensure propertyKey is never empty
|
||||
let pk: string = "";
|
||||
const primaryColumns = metadata.primaryColumns;
|
||||
primaryColumns.forEach((col) => {
|
||||
|
|
@ -444,14 +550,27 @@ export class ApiWebServiceController extends Controller {
|
|||
}
|
||||
});
|
||||
|
||||
const [items, total] = await queryBuilder
|
||||
.select(propertyKey)
|
||||
.where(condition)
|
||||
.andWhere(posMasterCondition)
|
||||
.orderBy(propertyKey[0], "ASC")
|
||||
.skip(offset)
|
||||
.take(pageSize)
|
||||
.getManyAndCount();
|
||||
let items: any[] = [];
|
||||
let total = 0;
|
||||
|
||||
if (tbMain === "OrgRoot") {
|
||||
// Organization API should always return full hierarchy regardless of page/pageSize.
|
||||
[items, total] = await queryBuilder
|
||||
.select(propertyKey)
|
||||
.where(condition)
|
||||
.andWhere(posMasterCondition)
|
||||
.orderBy(propertyKey[0] || `${tbMain}.${pk}`, "ASC")
|
||||
.getManyAndCount();
|
||||
} else {
|
||||
[items, total] = await queryBuilder
|
||||
.select(propertyKey)
|
||||
.where(condition)
|
||||
.andWhere(posMasterCondition)
|
||||
.orderBy(propertyKey[0] || `${tbMain}.${pk}`, "ASC")
|
||||
.skip(offset)
|
||||
.take(pageSize)
|
||||
.getManyAndCount();
|
||||
}
|
||||
|
||||
// ลบ Main.id
|
||||
// const results = items.map(({ id, ...x }) => x);
|
||||
|
|
@ -480,9 +599,30 @@ export class ApiWebServiceController extends Controller {
|
|||
}
|
||||
|
||||
// สำหรับ Position: แปลงฟิลด์ที่มาจาก join กลับเป็นชื่อเดิม
|
||||
if (tbMain === "Position") {
|
||||
if (tbMain === "Position" || tbMain === "PosMaster") {
|
||||
const flattened: any = { ...rest };
|
||||
Object.entries(this.POSITION_FIELD_REPLACEMENTS).forEach(([nameField, config]) => {
|
||||
// Remove the original ID field
|
||||
delete flattened[config.propertyName];
|
||||
// Add the name field from joined table
|
||||
const alias = `Position_${config.joinRelation}`;
|
||||
if (rest[alias] && rest[alias][config.joinField] !== undefined) {
|
||||
flattened[nameField] = rest[alias][config.joinField];
|
||||
}
|
||||
// Remove the joined table object
|
||||
delete flattened[alias];
|
||||
});
|
||||
// Remove Position object if exists
|
||||
if (flattened["Position"]) {
|
||||
delete flattened["Position"];
|
||||
}
|
||||
return flattened;
|
||||
}
|
||||
|
||||
// สำหรับ ProfileEmployee: แปลงฟิลด์ที่มาจาก join กลับเป็นชื่อเดิม
|
||||
if (tbMain === "ProfileEmployee") {
|
||||
const flattened: any = { ...rest };
|
||||
Object.entries(this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS).forEach(([nameField, config]) => {
|
||||
// Remove the original ID field
|
||||
delete flattened[config.propertyName];
|
||||
// Add the name field from joined table
|
||||
|
|
@ -499,23 +639,173 @@ export class ApiWebServiceController extends Controller {
|
|||
// สำหรับ PosMaster: แปลงฟิลด์ Profile ที่มาจาก join กลับเป็นฟิลด์ระดับบน
|
||||
if (tbMain === "PosMaster" && posMasterProfileFields.length > 0) {
|
||||
const flattened: any = { ...rest };
|
||||
// Extract Profile fields and add them at top level with "profile_" prefix to avoid conflicts
|
||||
const profileFieldNames = posMasterProfileFields
|
||||
.filter((field) => field.startsWith("Profile."))
|
||||
.map((field) => field.replace("Profile.", ""));
|
||||
|
||||
// Extract only requested Profile fields and add top-level aliases
|
||||
if (rest["Profile"]) {
|
||||
flattened["profile_prefix"] = rest["Profile"].prefix;
|
||||
flattened["profile_rank"] = rest["Profile"].rank;
|
||||
flattened["profile_firstName"] = rest["Profile"].firstName;
|
||||
flattened["profile_lastName"] = rest["Profile"].lastName;
|
||||
flattened["profile_citizenId"] = rest["Profile"].citizenId;
|
||||
profileFieldNames.forEach((fieldName) => {
|
||||
if (rest["Profile"][fieldName] !== undefined) {
|
||||
flattened[`profile_${fieldName}`] = rest["Profile"][fieldName];
|
||||
}
|
||||
});
|
||||
// Remove the nested Profile object
|
||||
delete flattened["Profile"];
|
||||
}
|
||||
return flattened;
|
||||
}
|
||||
|
||||
// สำหรับ OrgRoot: เก็บ primary key ไว้ใช้ group ข้อมูล แล้วแยก children ภายหลัง
|
||||
if (tbMain === "OrgRoot") {
|
||||
return { __rootPk: removedPk, ...rest };
|
||||
}
|
||||
|
||||
return rest;
|
||||
});
|
||||
|
||||
// console.log("queryBuilder ===> ", queryBuilder.getQuery());
|
||||
let responseData: any[] = data;
|
||||
let responseTotal = total;
|
||||
|
||||
// สำหรับ Organization: รวมข้อมูลให้เหลือ 1 root ต่อ 1 object และจัด children ตาม hierarchy
|
||||
if (tbMain === "OrgRoot") {
|
||||
const rootVisibleFields = Array.from(selectedFieldsByTable["OrgRoot"] || []);
|
||||
const child1VisibleFields = Array.from(selectedFieldsByTable["OrgChild1"] || []);
|
||||
const child2VisibleFields = Array.from(selectedFieldsByTable["OrgChild2"] || []);
|
||||
const child3VisibleFields = Array.from(selectedFieldsByTable["OrgChild3"] || []);
|
||||
const child4VisibleFields = Array.from(selectedFieldsByTable["OrgChild4"] || []);
|
||||
|
||||
const pickVisibleFields = (obj: any, fields: string[]) => {
|
||||
const out: any = {};
|
||||
fields.forEach((field) => {
|
||||
if (obj[field] !== undefined) {
|
||||
out[field] = obj[field];
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
const rootMap = new Map<string, any>();
|
||||
data.forEach((row: any) => {
|
||||
if (!row.__rootPk || rootMap.has(row.__rootPk)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rootNode = {
|
||||
...pickVisibleFields(row, rootVisibleFields),
|
||||
children: [],
|
||||
};
|
||||
rootMap.set(row.__rootPk, rootNode);
|
||||
});
|
||||
|
||||
const rootIds = Array.from(rootMap.keys());
|
||||
|
||||
if (rootIds.length > 0) {
|
||||
const buildSelect = (alias: string, required: string[], visible: string[]) =>
|
||||
Array.from(new Set([...required, ...visible])).map((field) => `${alias}.${field}`);
|
||||
|
||||
const [child1Rows, child2Rows, child3Rows, child4Rows] = await Promise.all([
|
||||
AppDataSource.getRepository(OrgChild1)
|
||||
.createQueryBuilder("OrgChild1")
|
||||
.select(buildSelect("OrgChild1", ["id", "orgRootId"], child1VisibleFields))
|
||||
.where("OrgChild1.orgRootId IN (:...rootIds)", { rootIds })
|
||||
.orderBy("OrgChild1.id", "ASC")
|
||||
.getMany(),
|
||||
AppDataSource.getRepository(OrgChild2)
|
||||
.createQueryBuilder("OrgChild2")
|
||||
.select(
|
||||
buildSelect("OrgChild2", ["id", "orgRootId", "orgChild1Id"], child2VisibleFields),
|
||||
)
|
||||
.where("OrgChild2.orgRootId IN (:...rootIds)", { rootIds })
|
||||
.orderBy("OrgChild2.id", "ASC")
|
||||
.getMany(),
|
||||
AppDataSource.getRepository(OrgChild3)
|
||||
.createQueryBuilder("OrgChild3")
|
||||
.select(
|
||||
buildSelect(
|
||||
"OrgChild3",
|
||||
["id", "orgRootId", "orgChild1Id", "orgChild2Id"],
|
||||
child3VisibleFields,
|
||||
),
|
||||
)
|
||||
.where("OrgChild3.orgRootId IN (:...rootIds)", { rootIds })
|
||||
.orderBy("OrgChild3.id", "ASC")
|
||||
.getMany(),
|
||||
AppDataSource.getRepository(OrgChild4)
|
||||
.createQueryBuilder("OrgChild4")
|
||||
.select(
|
||||
buildSelect(
|
||||
"OrgChild4",
|
||||
["id", "orgRootId", "orgChild1Id", "orgChild2Id", "orgChild3Id"],
|
||||
child4VisibleFields,
|
||||
),
|
||||
)
|
||||
.where("OrgChild4.orgRootId IN (:...rootIds)", { rootIds })
|
||||
.orderBy("OrgChild4.id", "ASC")
|
||||
.getMany(),
|
||||
]);
|
||||
|
||||
const child1Map = new Map<string, any>();
|
||||
const child2Map = new Map<string, any>();
|
||||
const child3Map = new Map<string, any>();
|
||||
|
||||
child1Rows.forEach((row) => {
|
||||
const node = {
|
||||
...pickVisibleFields(row, child1VisibleFields),
|
||||
children: [],
|
||||
};
|
||||
child1Map.set(row.id, node);
|
||||
|
||||
const rootNode = rootMap.get(row.orgRootId);
|
||||
if (rootNode) {
|
||||
rootNode.children.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
child2Rows.forEach((row) => {
|
||||
const node = {
|
||||
...pickVisibleFields(row, child2VisibleFields),
|
||||
children: [],
|
||||
};
|
||||
child2Map.set(row.id, node);
|
||||
|
||||
const parent = child1Map.get(row.orgChild1Id);
|
||||
if (parent) {
|
||||
parent.children.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
child3Rows.forEach((row) => {
|
||||
const node = {
|
||||
...pickVisibleFields(row, child3VisibleFields),
|
||||
children: [],
|
||||
};
|
||||
child3Map.set(row.id, node);
|
||||
|
||||
const parent = child2Map.get(row.orgChild2Id);
|
||||
if (parent) {
|
||||
parent.children.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
child4Rows.forEach((row) => {
|
||||
const node = {
|
||||
...pickVisibleFields(row, child4VisibleFields),
|
||||
};
|
||||
|
||||
const parent = child3Map.get(row.orgChild3Id);
|
||||
if (parent) {
|
||||
if (!Array.isArray(parent.children)) {
|
||||
parent.children = [];
|
||||
}
|
||||
parent.children.push(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
responseData = Array.from(rootMap.values());
|
||||
responseTotal = responseData.length;
|
||||
}
|
||||
|
||||
// save api history after query success
|
||||
const history = {
|
||||
|
|
@ -565,6 +855,6 @@ export class ApiWebServiceController extends Controller {
|
|||
|
||||
// return flattenedItem;
|
||||
// });
|
||||
return new HttpSuccess({ data: data, total });
|
||||
return new HttpSuccess({ data: responseData, total: responseTotal });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue