:Qrge branch 'jskim-node' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node

This commit is contained in:
kmh
2026-03-10 16:16:52 +09:00
parent 5abce62d89
commit 6d2cdc1782
8 changed files with 267 additions and 143 deletions

View File

@@ -1046,6 +1046,7 @@
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.3",
@@ -2373,6 +2374,7 @@
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz",
"integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==",
"license": "MIT",
"peer": true,
"dependencies": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
@@ -3485,6 +3487,7 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.17.tgz",
"integrity": "sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -3721,6 +3724,7 @@
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0",
@@ -3938,6 +3942,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -4463,6 +4468,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.3",
"caniuse-lite": "^1.0.30001741",
@@ -5673,6 +5679,7 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -5951,6 +5958,7 @@
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
"peer": true,
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
@@ -7486,6 +7494,7 @@
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -8455,7 +8464,6 @@
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
@@ -9343,6 +9351,7 @@
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
"license": "MIT",
"peer": true,
"dependencies": {
"pg-connection-string": "^2.9.1",
"pg-pool": "^3.10.1",
@@ -10198,7 +10207,6 @@
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
@@ -11006,6 +11014,7 @@
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -11111,6 +11120,7 @@
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"

View File

@@ -181,20 +181,92 @@ export async function getDistinctColumnValues(req: AuthenticatedRequest, res: Re
? `WHERE ${whereConditions.join(" AND ")}`
: "";
// DISTINCT 쿼리 실행
const query = `
// 1단계: DISTINCT 값 조회
const distinctQuery = `
SELECT DISTINCT "${columnName}" as value, "${effectiveLabelColumn}" as label
FROM "${tableName}"
${whereClause}
ORDER BY "${effectiveLabelColumn}" ASC
LIMIT 500
`;
const result = await pool.query(distinctQuery, params);
const result = await pool.query(query, params);
// 2단계: 카테고리/코드 라벨 변환 (값이 있을 때만)
if (result.rows.length > 0) {
const rawValues = result.rows.map((r: any) => r.value);
const labelMap: Record<string, string> = {};
// category_values에서 라벨 조회
try {
const cvCompanyCondition = companyCode !== "*"
? `AND (company_code = $4 OR company_code = '*')`
: "";
const cvParams = companyCode !== "*"
? [tableName, columnName, rawValues, companyCode]
: [tableName, columnName, rawValues];
const cvResult = await pool.query(
`SELECT value_code, value_label FROM category_values
WHERE table_name = $1 AND column_name = $2
AND value_code = ANY($3) AND is_active = true
${cvCompanyCondition}`,
cvParams
);
cvResult.rows.forEach((r: any) => {
labelMap[r.value_code] = r.value_label;
});
} catch (e) {
// category_values 조회 실패 시 무시
}
// code_info에서 라벨 조회 (code_category 기반)
try {
const ttcResult = await pool.query(
`SELECT code_category FROM table_type_columns
WHERE table_name = $1 AND column_name = $2 AND code_category IS NOT NULL
LIMIT 1`,
[tableName, columnName]
);
const codeCategory = ttcResult.rows[0]?.code_category;
if (codeCategory) {
const ciCompanyCondition = companyCode !== "*"
? `AND (company_code = $3 OR company_code = '*')`
: "";
const ciParams = companyCode !== "*"
? [codeCategory, rawValues, companyCode]
: [codeCategory, rawValues];
const ciResult = await pool.query(
`SELECT code_value, code_name FROM code_info
WHERE code_category = $1 AND code_value = ANY($2) AND is_active = 'Y'
${ciCompanyCondition}`,
ciParams
);
ciResult.rows.forEach((r: any) => {
if (!labelMap[r.code_value]) {
labelMap[r.code_value] = r.code_name;
}
});
}
} catch (e) {
// code_info 조회 실패 시 무시
}
// 라벨 매핑 적용
if (Object.keys(labelMap).length > 0) {
result.rows.forEach((row: any) => {
if (labelMap[row.value]) {
row.label = labelMap[row.value];
}
});
}
}
logger.info("컬럼 DISTINCT 값 조회 성공", {
tableName,
columnName,
columnInputType: columnInputType || "none",
labelColumn: effectiveLabelColumn,
companyCode,
hasFilters: !!filtersParam,