20260205 업데이트(컨텐츠 페이지 연결)

This commit is contained in:
2026-02-05 10:06:09 +09:00
parent 5d52f6d37a
commit 6dcc2eb796
208 changed files with 8143 additions and 1524 deletions

View File

@@ -25,6 +25,7 @@ $isAdmin = in_array(
['BS100100','BS100200','BS100300','BS100400'],
true
);
$isSuperAdmin = in_array($auth_bc, ['BS100100','BS100200'], true);
/* =========================
입력

View File

@@ -5,23 +5,37 @@ require_once 'db_conn.php';
header('Content-Type: application/json');
try {
// 2. 프로시저 호출 (컬럼명: itm_cd, itm_nm, area, itm_amt 등)
$stmt = $pdo->prepare("SELECT * FROM kngil.sp_fa_comments_r()");
// 1. 직접 SQL 실행
// 함수 호출 대신 테이블에 직접 쿼리를 날립니다.
$sql = "
SELECT * FROM kngil.fa_comments
WHERE use_yn = 'Y'
ORDER BY sq_no ASC, fa_id DESC
";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 3. W2UI를 위해 각 행에 'recid' 필드 강제 주입
// 2. W2UI 호환성: recid 필드 매핑
$records = [];
foreach ($rows as $row) {
$row['recid'] = $row['fa_id']; // 상품코드를 고유 키로 지정
// fa_id를 그리드의 고유 키(recid)로 사용합니다.
$row['recid'] = $row['fa_id'];
$records[] = $row;
}
// 4. 순수 JSON 출력 (다른 echo나 공백이 섞이면 에러 발생)
echo json_encode($records);
// 3. JSON 출력 (한글 깨짐 방지 및 숫자 형변환)
echo json_encode($records, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
} catch (PDOException $e) {
// 에러 발생 시 그리드가 이해할 수 있게 JSON으로 출력
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
// 에러 발생 시 로그 기록 및 JSON 에러 메시지 출력
error_log("Query Error: " . $e->getMessage());
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => '데이터 조회 중 오류가 발생했습니다.'
], JSON_UNESCAPED_UNICODE);
}
?>

View File

@@ -37,8 +37,10 @@ try {
$pdo->beginTransaction();
// 3. 삭제 실행
$stmt = $pdo->prepare("SELECT kngil.sp_fa_comments_d(:fa_id)");
// 3. 삭제 실행 (함수 대신 직접 DELETE 쿼리 사용)
// 루프 밖에서 prepare를 한 번만 수행하여 성능을 높입니다.
$sql = "DELETE FROM kngil.fa_comments WHERE fa_id = :fa_id";
$stmt = $pdo->prepare($sql);
foreach ($ids as $code) {
$stmt->execute([':fa_id' => $code]);

View File

@@ -37,34 +37,63 @@ try {
$pdo->beginTransaction();
/* ---------- 신규 추가(INSERT) ---------- */
/* ---------- 신규 추가(INSERT) 직접 쿼리 방식 ---------- */
if ($inserts) {
// 호출 시 파라미터 개수와 이름을 정확히 맞춤
$stmtI = $pdo->prepare("SELECT kngil.sp_fa_comments_i(:fa_subject, :fa_content, :sq_no, :use_yn, :cid)");
// 1. 함수 대신 직접 INSERT 쿼리 준비
// fa_id는 자동 생성이므로 제외, cdt는 DB 함수 사용
$sqlI = "INSERT INTO kngil.fa_comments (
fa_subject,
fa_content,
sq_no,
use_yn,
cid,
cdt
) VALUES (
:fa_subject,
:fa_content,
:sq_no,
:use_yn,
:cid,
CURRENT_TIMESTAMP
)";
$stmtI = $pdo->prepare($sqlI);
foreach ($inserts as $r) {
$stmtI->execute([
':fa_subject' => $r['fa_subject'] ?? '', // 데이터가 없으면 빈 글자라도 보냄
':fa_content' => $r['fa_content'] ?? '',
':sq_no' => $r['sq_no'] ?? 0,
':use_yn' => $r['use_yn'] ?? 'Y',
':cid' => $user_id
':fa_subject' => $r['fa_subject'] ?? '',
':fa_content' => $r['fa_content'] ?? '',
':sq_no' => (int)($r['sq_no'] ?? 0), // 숫자형 보장
':use_yn' => $r['use_yn'] ?? 'Y',
':cid' => $user_id
]);
}
}
/* ---------- 수정(UPDATE) ---------- */
/* ---------- 수정(UPDATE) 직접 쿼리 방식 ---------- */
if ($updates) {
$stmtU = $pdo->prepare("SELECT kngil.sp_fa_comments_u(:fa_id, :fa_subject, :fa_content, :sq_no, :use_yn, :mid)");
// 1. 함수 대신 직접 UPDATE 쿼리 준비
$sqlU = "UPDATE kngil.fa_comments
SET
fa_subject = :fa_subject,
fa_content = :fa_content,
sq_no = :sq_no,
use_yn = :use_yn,
mid = :mid,
mdt = CURRENT_TIMESTAMP
WHERE
fa_id = :fa_id";
$stmtU = $pdo->prepare($sqlU);
foreach ($updates as $r) {
$stmtU->execute([
':fa_id' => $r['fa_id'] ?? '',
':fa_subject' => $r['fa_subject'] ?? '', // 데이터가 없으면 빈 글자라도 보냄
':fa_content' => $r['fa_content'] ?? '',
':sq_no' => $r['sq_no'] ?? 0,
':use_yn' => $r['use_yn'] ?? 'Y',
':mid' => $user_id
':fa_id' => $r['fa_id'], // 필수 조건
':fa_subject' => $r['fa_subject'] ?? '',
':fa_content' => $r['fa_content'] ?? '',
':sq_no' => (int)($r['sq_no'] ?? 0),
':use_yn' => $r['use_yn'] ?? 'Y',
':mid' => $user_id
]);
}
}

View File

@@ -5,23 +5,43 @@ require_once 'db_conn.php';
header('Content-Type: application/json');
try {
// 클라이언트(JS)로부터 전달받은 검색 조건 (POST 또는 GET 방식에 맞춰 수정)
$p_member_id = $_POST['member_id'] ?? '';
$p_member_nm = $_POST['member_nm'] ?? '';
// 날짜가 빈 값('')으로 오면 반드시 null로 치환해야 PostgreSQL date 타입 에러가 안 납니다.
$p_fbuy_dt = (!empty($_POST['fbuy_dt'])) ? $_POST['fbuy_dt'] : null;
$p_tbuy_dt = (!empty($_POST['tbuy_dt'])) ? $_POST['tbuy_dt'] : null;
$p_member_id = isset($_POST['member_id']) ? trim($_POST['member_id']) : '';
$p_fbuy_dt = isset($_POST['fbuy_dt']) ? trim($_POST['fbuy_dt']) : '';
$p_tbuy_dt = isset($_POST['tbuy_dt']) ? trim($_POST['tbuy_dt']) : '';
// 2. 프로시저 호출 - 파라미터 자리에 ?를 사용합니다.
$stmt = $pdo->prepare("SELECT * FROM kngil.sp_buy_item_history_r(?, ?, ?, ?)");
if ($p_fbuy_dt === '') {
$p_fbuy_dt = '1999-01-01';
}
if ($p_tbuy_dt === '') {
$p_tbuy_dt = '2099-12-31';
}
$sql = "
SELECT
a.member_id::text, a.sq_no,
b.member_nm::text as user_nm, b.co_nm::text, b.bs_no::text,
a.buy_dt, a.itm_cd::text, c.itm_nm::text,
c.area::NUMERIC as area, a.itm_qty::NUMERIC,
a.itm_area::NUMERIC, a.add_area::NUMERIC, a.sum_area::NUMERIC,
a.itm_amt::NUMERIC, a.dis_rt::NUMERIC, a.buy_amt::NUMERIC,
a.vat_amt::NUMERIC, a.sum_amt::NUMERIC,
a.end_dt, a.ok_yn::text, a.rmks::text
FROM kngil.buy_item a
LEFT JOIN kngil.members b ON a.member_id = b.member_id
LEFT JOIN kngil.item c ON a.itm_cd = c.itm_cd
WHERE (:member_id = '' OR a.member_id = :member_id)
AND (:fbuy_dt = '' OR a.buy_dt >= :fbuy_dt::date)
AND (:tbuy_dt = '' OR a.buy_dt <= :tbuy_dt::date)
ORDER BY a.buy_dt DESC, a.member_id, a.sq_no DESC
";
$stmt = $pdo->prepare($sql);
// 파라미터 순서대로 배열에 담아 실행합니다.
$stmt->execute([
$p_member_id,
$p_member_nm,
$p_fbuy_dt,
$p_tbuy_dt
':member_id' => $p_member_id,
':fbuy_dt' => $p_fbuy_dt,
':tbuy_dt' => $p_tbuy_dt
]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

View File

@@ -1,41 +1,76 @@
<?php
// 1. DB 연결
/**
* 서비스 사용 이력 조회 API (Direct SQL 방식)
*/
require_once 'db_conn.php';
header('Content-Type: application/json');
try {
// JS의 URLSearchParams에서 보낸 키값과 일치시켜야 합니다.
$p_member_id = $_POST['member_id'] ?? '';
$p_user_nm = $_POST['user_nm'] ?? '';
$p_dept_nm = $_POST['dept_nm'] ?? '';
// 1. 파라미터 수집
$p_member_id = isset($_POST['member_id']) ? trim($_POST['member_id']) : '';
$p_user_nm = isset($_POST['user_nm']) ? trim($_POST['user_nm']) : '';
$p_dept_nm = isset($_POST['dept_nm']) ? trim($_POST['dept_nm']) : '';
$p_fuse_dt = isset($_POST['fuse_dt']) ? trim($_POST['fuse_dt']) : '';
$p_tuse_dt = isset($_POST['tuse_dt']) ? trim($_POST['tuse_dt']) : '';
// 2. 프로시저 호출
// PostgreSQL 함수 호출 시 파라미터가 비어있으면 전체 조회가 되도록 설계됨
$stmt = $pdo->prepare("SELECT * FROM kngil.sp_use_history(?, ?, ?)");
if ($p_fuse_dt === '') {
$p_fuse_dt = '1999-01-01';
}
if ($p_tuse_dt === '') {
$p_tuse_dt = '2099-12-31';
}
// 2. 직접 SQL 쿼리 작성 (함수 내부 로직을 그대로 가져옴)
$sql = "
SELECT
b.member_id::character varying,
a.use_dt, -- DATE 타입
a.user_id::character varying,
a.sq_no,
b.user_nm::character varying,
b.dept_nm::character varying,
b.posit_nm::character varying,
b.use_yn::character varying,
a.use_area,
kngil.fn_base_nm(a.ser_bc)::character varying as ser_bc,
a.cdt
FROM kngil.use_history a
INNER JOIN kngil.users b ON a.user_id = b.user_id
WHERE (:member_id = '' OR b.member_id = :member_id) -- ID가 없어도 나오게
-- 검색 조건: 값이 있을 때만 필터링
AND (:user_nm = '' OR b.user_nm LIKE '%' || :user_nm || '%')
AND (:dept_nm = '' OR b.dept_nm LIKE '%' || :dept_nm || '%')
AND a.use_dt::date >= :fuse_dt::date
AND a.use_dt::date <= :tuse_dt::date
ORDER BY a.use_dt DESC, a.sq_no DESC
";
$stmt = $pdo->prepare($sql);
// 파라미터 바인딩 (이름 기반 바인딩이 더 직관적입니다)
$stmt->execute([
$p_member_id,
$p_user_nm,
$p_dept_nm
':member_id' => $p_member_id,
':user_nm' => $p_user_nm,
':dept_nm' => $p_dept_nm,
':fuse_dt' => $p_fuse_dt,
':tuse_dt' => $p_tuse_dt
]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 3. W2UI를 위해 각 행에 'recid' 필드 주입
// 3. W2UI용 recid 가공
$records = [];
foreach ($rows as $index => $row) {
// user_id와 sq_no 조합으로 유일키 생성 (권장)
// 만약 데이터가 없을 경우를 대비해 $index를 활용할 수도 있음
$row['recid'] = ($row['user_id'] ?? 'unknown') . '_' . ($row['sq_no'] ?? $index);
$row['recid'] = $row['user_id'] . '_' . ($row['sq_no'] ?? $index);
$records[] = $row;
}
// 4. 결과 출력
echo json_encode($records, JSON_UNESCAPED_UNICODE); // 한글 깨짐 방지
echo json_encode($records, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
} catch (PDOException $e) {
error_log("DB Error: " . $e->getMessage());
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
?>

View File

@@ -2,9 +2,9 @@
// /kngil/bbs/oidc_config.php
return [
'issuer' => 'https://api.descope.com/v1/apps/P2x26KgEwOu0xIwgNZutJjIZc1zz', // 예: https://idp.example.com/auth/realms/master
'client_id' => 'UDJ4MjZLZ0V3T3UweEl3Z05adXRKaklaYzF6ejpUUEEzOTVtSmx5MXhiczFwZWxrUHdDVFlvU2hiYXc=',
'client_secret' => 'uTjiKweHYUINalroA1LVu9OacbEEMPtPbfFITfHu3r5',
'issuer' => 'https://sss.hmac.kr/oidc', // 예: https://idp.example.com/auth/realms/master
'client_id' => 'cc6f2f41-2705-4c7d-bffc-24c1d6b484f1',
'client_secret' => 'ebjOE4I-gLnANV5KY623hClSAy',
'redirect_url' => "https://kngil.hmac.kr/kngil/auth/oidc-callback.php",
'scopes' => ['openid'],
'scopes' => ['openid', 'profile', 'email'],
];