857 lines
37 KiB
PHP
857 lines
37 KiB
PHP
<?php
|
|
if (!defined('_GNUBOARD_')) define('_GNUBOARD_', true);
|
|
|
|
// 스킨 안에서 쓰는 상수 최소 셋만 “직접” 정의 (필요시 경로 수정)
|
|
if (!defined('G5_URL')) define('G5_URL', '/eng');
|
|
if (!defined('G5_BBS_URL')) define('G5_BBS_URL', '/eng/bbs');
|
|
if (!defined('G5_IMG_URL')) define('G5_IMG_URL', '/eng/img');
|
|
|
|
// 로그인 여부 플래그
|
|
$isLoggedIn = !empty($_SESSION['user']['userId']);
|
|
|
|
// ✅ DB 연결
|
|
$pdo = new PDO("mysql:host=db;dbname=egbim;charset=utf8mb4", "egbim", "baron3840!!", [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
]);
|
|
|
|
// ✅ EG-BIM (product_code=8) 기준 최신 external_version 가져오기
|
|
$stmt = $pdo->prepare("
|
|
SELECT external_version
|
|
FROM deploy_versions
|
|
WHERE product_code = 1
|
|
ORDER BY updated_at DESC
|
|
LIMIT 1
|
|
");
|
|
$stmt->execute();
|
|
$version = $stmt->fetchColumn() ?: '1.0.0'; // fallback
|
|
|
|
// ✅ 다운로드 URL 자동 생성
|
|
$download_url = "https://release-download.hmac.kr/eg-bim/{$version}/setup_eg-bim_{$version}.exe";
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Q&A 상세보기</title>
|
|
<style>
|
|
/* (기존 스타일을 여기에 복사) */
|
|
</style>
|
|
|
|
<link rel="stylesheet" href="../js/font-awesome/css/font-awesome.min.css?ver=2303229">
|
|
|
|
<!-- 디자인팀 작성 -->
|
|
<script type="text/javascript" src="../js/jquery-3.6.1.min.js"></script>
|
|
<script type="text/javascript" src="../js/jquery.mousewheel.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollToPlugin.min.js"></script>
|
|
<link rel="stylesheet" href="https://unpkg.com/aos@2.3.1/dist/aos.css" type="text/css"/>
|
|
<link rel="stylesheet" href="https://unpkg.com/lenis@1.1.9/dist/lenis.css">
|
|
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
|
<script src="https://unpkg.com/lenis@1.1.9/dist/lenis.min.js"></script>
|
|
<script type="text/javascript" src="../js/popup.js?v=20260723"></script>
|
|
<script type="text/javascript" src="../js/common.js"></script>
|
|
<script type="text/javascript" src="../js/index.js"></script>
|
|
|
|
<link rel="stylesheet" href="../css/reset.css"/>
|
|
<link rel="stylesheet" href="../css/font.css"/>
|
|
<link rel="stylesheet" href="../css/style.css"/>
|
|
<!-- //디자인팀 작성 -->
|
|
</head>
|
|
<body>
|
|
<div class="wrapper">
|
|
<!-- Header -->
|
|
<?php include_once(__DIR__ . '/../../member/basic/main_header.skin.php'); ?>
|
|
<!-- //Header -->
|
|
|
|
<div class="container faq">
|
|
<section class="intro">
|
|
<div class="top js__dark">
|
|
<h2>Q&A</h2>
|
|
<span>EG-BIM Q&As</span>
|
|
</div>
|
|
<ul class="sub_tab">
|
|
<li ><a href="/eng/bbs/faq.php">FAQ</a></li>
|
|
<li class="on"><a href="/eng/bbs/descope_qa_list.php">Q&A</a></li>
|
|
<li><a href="https://939.co.kr/saman/" target="_blank">Remote Support</a></li>
|
|
</ul>
|
|
</section>
|
|
|
|
<span class="sub_tit">Q&A</span>
|
|
|
|
<div class="contents">
|
|
<section class="qa-detail">
|
|
<div class="qa-view">
|
|
<div class="meta tbl-area">
|
|
<!-- <div class="tbl-item status-control">
|
|
<?php if (is_qna_admin()): ?>
|
|
<form method="post" action="/eng/bbs/descope_qa_status.php" style="display:inline;">
|
|
<input type="hidden" name="post_id" value="<?= $post['post_id'] ?>">
|
|
<select name="status" onchange="this.form.submit()">
|
|
<option value="await" <?= $post['status']==='await'?'selected':'' ?>>답변대기</option>
|
|
<option value="review" <?= $post['status']==='review'?'selected':'' ?>>검토중</option>
|
|
<option value="done" <?= $post['status']==='done'?'selected':'' ?>>답변완료</option>
|
|
</select>
|
|
</form>
|
|
<?php else: ?>
|
|
<div class="status"><?= htmlspecialchars($post['status_label']) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="tbl-item">
|
|
<span class="cate"><?=htmlspecialchars($post['category_label'])?></span>
|
|
<p class="tit"><?=htmlspecialchars($post['title'])?></p>
|
|
</div> -->
|
|
<div class="tbl-item title-row">
|
|
<!-- 왼쪽: 카테고리 + 제목 -->
|
|
<div class="title-left">
|
|
<span class="cate"><?=htmlspecialchars($post['category_label'])?></span>
|
|
<span class="tit"><?=htmlspecialchars($post['title'])?></span>
|
|
</div>
|
|
|
|
<!-- 오른쪽: 상태 -->
|
|
<div class="title-right">
|
|
<?php if (is_qna_admin()): ?>
|
|
<form method="post" action="/eng/bbs/descope_qa_status.php">
|
|
<input type="hidden" name="post_id" value="<?= $post['post_id'] ?>">
|
|
<select name="status" onchange="this.form.submit()" class="status-select status-<?= htmlspecialchars($post['status']) ?>">
|
|
<option value="new" <?= $post['status']==='new'?'selected':'' ?>>New</option>
|
|
<option value="review" <?= $post['status']==='review'?'selected':'' ?>>Review</option>
|
|
<option value="deep" <?= $post['status']==='deep'?'selected':'' ?>>Checking</option>
|
|
<option value="patch" <?= $post['status']==='patch'?'selected':'' ?>>Patch</option>
|
|
<option value="done" <?= $post['status']==='done'?'selected':'' ?>>Done</option>
|
|
</select>
|
|
</form>
|
|
<?php else: ?>
|
|
<div class="status"><?= htmlspecialchars($post['status_label']) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<div class="tbl-group user-info">
|
|
<div class="tbl-item">
|
|
<span>
|
|
<i class="fa fa-clock-o" aria-hidden="true"></i>
|
|
<?=htmlspecialchars($post['created_at'])?>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="tbl-item">
|
|
<!-- 글번호 -->
|
|
<span class="post">
|
|
<i class="fa fa-hashtag" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['post_id']) ?>
|
|
</span>
|
|
|
|
<?php if ($post['category'] === 'notice'): ?>
|
|
<!-- ✅ 공지사항이면 "관리자"만 표시 -->
|
|
<span>
|
|
<i class="fa fa-user" aria-hidden="true"></i>
|
|
관리자
|
|
</span>
|
|
<?php else: ?>
|
|
<!-- 작성자 이메일 -->
|
|
<span>
|
|
<i class="fa fa-envelope-o" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['login_id']) ?>
|
|
</span>
|
|
|
|
<!-- 회사 -->
|
|
<?php if ((int)$post['is_internal'] === 1 && !empty($post['family_company'])): ?>
|
|
<span>
|
|
<i class="fa fa-building-o" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['family_company']) ?>
|
|
</span>
|
|
<?php elseif (!empty($post['company'])): ?>
|
|
<span>
|
|
<i class="fa fa-building-o" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['company']) ?>
|
|
</span>
|
|
<?php endif; ?>
|
|
|
|
<!-- 부서 -->
|
|
<?php if (!empty($post['department'])): ?>
|
|
<span>
|
|
<i class="fa fa-sitemap" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['department']) ?>
|
|
</span>
|
|
<?php endif; ?>
|
|
|
|
<!-- 작성자 이름 -->
|
|
<span>
|
|
<i class="fa fa-user" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['display_name']) ?>
|
|
</span>
|
|
|
|
<!-- 관리자 전용 -->
|
|
<?php if (is_qna_admin()): ?>
|
|
<?php if (!empty($post['phone'])): ?>
|
|
<span>
|
|
<i class="fa fa-phone" aria-hidden="true"></i>
|
|
<?= htmlspecialchars($post['phone']) ?>
|
|
</span>
|
|
<?php endif; ?>
|
|
<span>
|
|
<i class="fa fa-key" aria-hidden="true"></i>
|
|
Q&A : <?= htmlspecialchars($post['post_id']) ?>
|
|
</span>
|
|
<?php
|
|
// ✅ 최신 login_version 가져오기
|
|
$loginVersion = null;
|
|
$st = $pdo->prepare("
|
|
SELECT login_version
|
|
FROM user_program_info
|
|
WHERE login_id = ?
|
|
ORDER BY id DESC
|
|
LIMIT 1
|
|
");
|
|
$st->execute([$post['login_id']]);
|
|
$loginVersion = $st->fetchColumn();
|
|
?>
|
|
<?php if ($loginVersion): ?>
|
|
<span>
|
|
<i class="fa fa-code-fork" aria-hidden="true"></i>
|
|
Ver <?= htmlspecialchars($loginVersion) ?>
|
|
</span>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
<div class="content">
|
|
<?= $post['content'] ?>
|
|
</div>
|
|
</div>
|
|
<!-- 첨부파일 -->
|
|
<?php if (!empty($attachments)): ?>
|
|
<div class="attachments" style="margin-top:20px;">
|
|
<h3>첨부파일</h3>
|
|
<ul>
|
|
<?php foreach ($attachments as $file): ?>
|
|
<li>
|
|
<?php if (!empty($_SESSION['user']['userId'])): ?>
|
|
<!-- ✅ 로그인한 경우: 다운로드 가능 -->
|
|
<a href="<?= htmlspecialchars($file['save_path']) ?>" download>
|
|
<?= htmlspecialchars($file['ori_name']) ?>
|
|
</a>
|
|
<?php else: ?>
|
|
<!-- 🚫 비회원: 이름만 표시 (다운로드 막음) -->
|
|
<?= htmlspecialchars($file['ori_name']) ?> <span style="color:#888;"></span>
|
|
<?php endif; ?>
|
|
<small>
|
|
(<?= round($file['file_size'] / 1024, 1) ?> KB,
|
|
<?= htmlspecialchars(substr($file['uploaded_at'],0,16)) ?>)
|
|
</small>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
<div class="btn-group">
|
|
|
|
<!-- 수정 버튼 (로그인 사용자 == 작성자 인 경우에만) -->
|
|
<?php if ($me === $post['login_id']): ?>
|
|
<button class="btn btn-save" onclick="location.href='/eng/bbs/descope_qa_write.php?id=<?= $post['post_id'] ?>'">수정</button>
|
|
<!-- <button class="btn btn-save" type="button" onclick="confirmDelete(<?= $post['post_id'] ?>)">삭제</button> -->
|
|
<button class="btn btn-save" id="btn-delete" data-status="<?= $post['status'] ?>" data-id="<?= $post['post_id'] ?>">삭제</button>
|
|
<?php endif; ?>
|
|
<!-- <button onclick="history.back()">닫기</button> -->
|
|
<button class="btn btn-list" onclick="location.href='/eng/bbs/descope_qa_list.php'">
|
|
<i class="fa fa-list" aria-hidden="true"></i> List</button>
|
|
</div>
|
|
</section>
|
|
<script>
|
|
$(document).on('click', '#btn-delete', function(e) {
|
|
e.preventDefault(); // 링크 이동 막기
|
|
const status = $(this).data('status');
|
|
const id = $(this).data('id');
|
|
|
|
if (status === 'review' || status === 'done') {
|
|
alert("검토중이거나 답변완료 된 상태에서는 글을 삭제할 수 없습니다.\n관리자에게 문의해 주세요");
|
|
return false;
|
|
}
|
|
|
|
if (confirm("정말 삭제하시겠습니까?\n댓글과 첨부파일도 함께 삭제됩니다.")) {
|
|
location.href = "/eng/bbs/descope_qa_delete.php?id=" + id;
|
|
}
|
|
});
|
|
|
|
// function confirmDelete(pid) {
|
|
// if (confirm("정말 이 글을 삭제하시겠습니까?\n댓글과 첨부파일도 함께 삭제됩니다.")) {
|
|
// window.location.href = "/eng/bbs/descope_qa_delete.php?id=" + pid;
|
|
// }
|
|
// }
|
|
</script>
|
|
<section class="comment-section">
|
|
<h4>Comment (<span id="comment-count"><?= count($comments) ?></span>)</h4>
|
|
<div class="comment-wrap form-wrap">
|
|
<div id="comments" class="comment-list">
|
|
<?php foreach ($comments as $c): ?>
|
|
<div class="comment" id="comment-<?= $c['comment_id'] ?>">
|
|
<div class="comment-body">
|
|
<!-- 댓글 내용 -->
|
|
<div class="comment-text"><?= nl2br(htmlspecialchars($c['comment_text'])) ?></div>
|
|
|
|
<!-- 작성자 + 날짜 같은 줄 -->
|
|
<div class="comment-meta">
|
|
<span class="comment-author"><strong><?= htmlspecialchars($c['user_name']) ?></strong></span>
|
|
<span class="comment-date"><small><?= $c['created_at'] ?></small></span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 수정/삭제 버튼 -->
|
|
<div class="comment-actions" style="text-align:right;">
|
|
<?php if (!empty($_SESSION['user']['loginIds'][0])): ?>
|
|
<?php if ($_SESSION['user']['loginIds'][0] == $c['login_id']): ?>
|
|
<!-- 본인 댓글: 수정 + 삭제 -->
|
|
<button class="btn-edit" data-id="<?= $c['comment_id'] ?>">Change</button>
|
|
<button class="btn-delete" data-id="<?= $c['comment_id'] ?>">Delete</button>
|
|
<?php elseif (is_qna_admin()): ?>
|
|
<!-- 관리자: 삭제만 -->
|
|
<button class="btn-delete" data-id="<?= $c['comment_id'] ?>">Delete</button>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- 수정 모드 textarea (기본 숨김) -->
|
|
<div class="comment-edit-box" style="display:none; margin-top:5px;">
|
|
<textarea class="comment-edit-input" rows="3"><?= htmlspecialchars($c['comment_text']) ?></textarea>
|
|
<div class="comment-edit-actions" style="text-align:right; margin-top:3px;">
|
|
<button class="btn-save-edit" data-id="<?= $c['comment_id'] ?>">Save</button>
|
|
<button class="btn-cancel-edit">Cancle</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<!-- 신규 댓글 입력 -->
|
|
<?php if ($isLoggedIn): ?>
|
|
<div class="comment-form form-item">
|
|
<textarea id="newComment" class="input-text" rows="3" placeholder="Add a comment"></textarea>
|
|
<button class="btn-save" id="btnSaveComment">Comments</button>
|
|
</div>
|
|
<?php else: ?>
|
|
<p style="color:#888;">Log in to add a comment.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</section>
|
|
</div> <!-- contents END -->
|
|
|
|
|
|
</div> <!-- container END -->
|
|
<!-- FOOTER -->
|
|
<?php include_once(__DIR__ . '/../../member/basic/main_footer.skin.php'); ?>
|
|
<!-- //FOOTER -->
|
|
</div> <!-- wrapper END -->
|
|
<script>
|
|
try{
|
|
AOS.init();
|
|
if (typeof Lenis !== 'undefined') {
|
|
const lenis = new Lenis();
|
|
lenis.on('scroll', ScrollTrigger.update);
|
|
gsap.ticker.add((time)=>{ lenis.raf(time * 1000) });
|
|
gsap.ticker.lagSmoothing(0);
|
|
window.lenis = lenis;
|
|
}
|
|
} catch(e){ console.error(e); }
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
//상태 색상 변경 동적 업데이트
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
document.querySelectorAll('.status-select').forEach(sel => {
|
|
sel.addEventListener('change', function() {
|
|
this.className = 'status-select status-' + this.value;
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
document.getElementById('btnSaveComment').addEventListener('click', async () => {
|
|
const txt = document.getElementById('newComment').value.trim();
|
|
if (!txt) return alert('댓글을 입력해주세요.');
|
|
|
|
const res = await fetch('/eng/bbs/descope_qa_comment.php', {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
headers: {'Content-Type':'application/json'},
|
|
body: JSON.stringify({
|
|
postId: <?= json_encode($post['post_id']) ?>,
|
|
comment: txt
|
|
})
|
|
});
|
|
const json = await res.json();
|
|
if (json.status !== 'ok') return alert(json.message);
|
|
|
|
// ✅ 댓글 DOM 생성 (PHP 출력 구조와 동일하게)
|
|
// 신규 댓글 저장 후 DOM 추가
|
|
const div = document.createElement('div');
|
|
div.className = 'comment';
|
|
div.id = "comment-" + json.comment_id;
|
|
const safeText = (json.comment_text || '').replace(/\r?\n/g, '<br>');
|
|
|
|
// 서버에서 isAdmin 내려줬다고 가정
|
|
const canDelete = (json.login_id === sessionStorage.getItem("loginId")) || (json.isAdmin === true);
|
|
const actions = canDelete ? `
|
|
<button class="btn-edit" data-id="${json.comment_id}">수정</button>
|
|
<button class="btn-delete" data-id="${json.comment_id}">삭제</button>` : '';
|
|
|
|
div.innerHTML = `
|
|
<div class="comment-body">
|
|
<div class="comment-text">${safeText}</div>
|
|
<div class="comment-meta">
|
|
<span class="comment-author"><strong>${json.user_name || json.login_id}</strong></span>
|
|
<span class="comment-date"><small>${json.created_at}</small></span>
|
|
</div>
|
|
</div>
|
|
<div class="comment-actions" style="text-align:right;">
|
|
${actions}
|
|
</div>
|
|
`;
|
|
document.getElementById('comments').append(div);
|
|
|
|
|
|
// ✅ 댓글 수 갱신
|
|
var countEl = document.getElementById("comment-count");
|
|
countEl.textContent = parseInt(countEl.textContent, 10) + 1;
|
|
|
|
// 입력창 비우기
|
|
document.getElementById('newComment').value = '';
|
|
});
|
|
|
|
// 댓글 수정 버튼
|
|
$(document).on('click', '.btn-edit', function() {
|
|
const id = $(this).data('id');
|
|
const $comment = $(this).closest('.comment');
|
|
const $text = $comment.find('.comment-text');
|
|
const original = $text.text().trim();
|
|
|
|
// input으로 교체
|
|
$text.replaceWith(`<textarea class="edit-input" data-id="${id}" rows="3">${original}</textarea>`);
|
|
$(this).text("저장").removeClass("btn-edit").addClass("btn-save-edit").attr("data-id", id);;
|
|
});
|
|
|
|
// 댓글 수정 저장
|
|
$(document).on('click', '.btn-save-edit', function() {
|
|
const id = $(this).data('id');
|
|
const $input = $('.edit-input[data-id="'+id+'"]');
|
|
const newText = $input.val().trim();
|
|
|
|
if (!newText) return alert("내용을 입력하세요");
|
|
console.log("update click", id, newText);
|
|
$.post("/eng/bbs/descope_qa_comment_update.php",
|
|
{ commentId:id, comment:newText },
|
|
function(res) {
|
|
if (res.status === 'ok') {
|
|
alert(res.message || "댓글이 수정되었습니다.");
|
|
$input.replaceWith(`<div class="comment-text">${newText}</div>`);
|
|
$('.btn-save-edit[data-id="'+id+'"]').text("수정")
|
|
.removeClass("btn-save-edit").addClass("btn-edit");
|
|
} else {
|
|
alert(res.message || "수정 실패");
|
|
}
|
|
}, "json");
|
|
});
|
|
|
|
document.addEventListener('click', function(e) {
|
|
// 수정 버튼 클릭 → textarea 열기
|
|
if (e.target.classList.contains('btn-edit')) {
|
|
const comment = e.target.closest('.comment');
|
|
comment.querySelector('.comment-text').style.display = 'none';
|
|
comment.querySelector('.comment-actions').style.display = 'none';
|
|
comment.querySelector('.comment-edit-box').style.display = 'block';
|
|
}
|
|
|
|
// 취소 버튼 → 원래 상태로
|
|
if (e.target.classList.contains('btn-cancel-edit')) {
|
|
const comment = e.target.closest('.comment');
|
|
comment.querySelector('.comment-text').style.display = 'inline';
|
|
comment.querySelector('.comment-actions').style.display = 'block';
|
|
comment.querySelector('.comment-edit-box').style.display = 'none';
|
|
}
|
|
|
|
// 저장 버튼 → AJAX로 수정 요청 (예시)
|
|
if (e.target.classList.contains('btn-save-edit')) {
|
|
const comment = e.target.closest('.comment');
|
|
const id = e.target.dataset.id;
|
|
const newText = comment.querySelector('.comment-edit-input').value;
|
|
|
|
// TODO: AJAX 호출해서 서버 업데이트
|
|
console.log("수정 저장:", id, newText);
|
|
|
|
// UI 갱신
|
|
comment.querySelector('.comment-text').textContent = newText;
|
|
comment.querySelector('.comment-text').style.display = 'inline';
|
|
comment.querySelector('.comment-actions').style.display = 'block';
|
|
comment.querySelector('.comment-edit-box').style.display = 'none';
|
|
}
|
|
});
|
|
|
|
|
|
// 댓글 삭제 버튼
|
|
$(document).on("click", ".btn-delete", function () {
|
|
if (!confirm("정말 삭제하시겠습니까?")) return;
|
|
|
|
var commentId = $(this).data("id");
|
|
|
|
$.ajax({
|
|
url: "/eng/bbs/descope_qa_comment_delete.php",
|
|
type: "POST",
|
|
data: { commentId: commentId },
|
|
dataType: "json",
|
|
success: function (res) {
|
|
if (res.status === "ok") {
|
|
// DOM에서도 삭제
|
|
$("#comment-" + commentId).fadeOut(300, function () {
|
|
$(this).remove();
|
|
});
|
|
// ✅ 댓글 수 감소
|
|
var countEl = $("#comment-count");
|
|
var current = parseInt(countEl.text(), 10);
|
|
if (current > 0) {
|
|
countEl.text(current - 1);
|
|
}
|
|
alert("댓글이 삭제되었습니다.");
|
|
} else {
|
|
alert(res.message || "삭제 실패");
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
alert("삭제 요청 에러: " + xhr.responseText);
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
</script>
|
|
<?php
|
|
// Q&A 상세 페이지에서는 Descope 로그인에 필요한 최소 팝업만 포함합니다.
|
|
$BASE = $_SERVER['DOCUMENT_ROOT'].'/eng/skin/member/basic';
|
|
$partials = [
|
|
'login.skin.php',
|
|
'register.skin.php',
|
|
'privacy.skin.php',
|
|
'password_lost.skin.php',
|
|
];
|
|
|
|
foreach ($partials as $p) {
|
|
$full = $BASE.'/'.$p;
|
|
if (file_exists($full)) {
|
|
include $full;
|
|
echo "<!-- INCLUDED: {$full} -->\n"; // 디버그 표시
|
|
} else {
|
|
echo "<!-- MISSING: {$full} -->\n"; // 경로 문제 확인용
|
|
}
|
|
}
|
|
?>
|
|
</body>
|
|
</html>
|
|
|
|
<script>
|
|
$(function(){
|
|
// footer family site toggle
|
|
$('.family_btn').click(function(e){
|
|
e.stopPropagation();
|
|
$('.family_list, .family_btn').toggleClass('family_on');
|
|
});
|
|
$(document).click(function(e){
|
|
if(!$(e.target).closest('.family_wrap').length){
|
|
$('.family_list, .family_btn').removeClass('family_on');
|
|
}
|
|
});
|
|
});
|
|
|
|
// 회원 탈퇴
|
|
function member_leave() {
|
|
if (confirm("회원에서 탈퇴 하시겠습니까?"))
|
|
location.href = '<?php echo G5_BBS_URL ?>/member_leave.php';
|
|
}
|
|
// 회원 탈퇴
|
|
|
|
|
|
let x = document.cookie;
|
|
if(x.includes("tmp_1=John")){
|
|
deleteCookie("tmp_1");
|
|
$('#pop_mypage02').show();
|
|
}
|
|
|
|
function deleteCookie(name) {
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/eng;";
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/eng/bbs;";
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/eng/faq;";
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/eng/qa;";
|
|
}
|
|
function getCookie(cname) {
|
|
let name = cname + "=";
|
|
let decodedCookie = decodeURIComponent(document.cookie);
|
|
let ca = decodedCookie.split(';');
|
|
for(let i = 0; i <ca.length; i++) {
|
|
let c = ca[i];
|
|
while (c.charAt(0) == ' ') {
|
|
c = c.substring(1);
|
|
}
|
|
if (c.indexOf(name) == 0) {
|
|
return c.substring(name.length, c.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
//descope 로그인, 로그아웃 js
|
|
function updateHeaderMenu() {
|
|
var isLoggedIn = !!sessionStorage.getItem("sessionJwt");
|
|
// role 체크 예시 (로그인 시 저장해놓은 값)
|
|
var isAdmin = sessionStorage.getItem('userRole') === 'super';
|
|
|
|
if (isLoggedIn) {
|
|
$('.my_join2, .my_login2').show();
|
|
$('.my_join, .my_login').hide();
|
|
|
|
// 마이페이지/관리자 메뉴 동적 출력
|
|
if (isAdmin) {
|
|
$('#my_join2').html("<a href='http://eg-bim.com/eng/adm/index.php' target='_blank'>관리페이지</a>");
|
|
} else {
|
|
$('#my_join2').html("<a href='javascript:mypage03();'>My Page</a>");
|
|
}
|
|
} else {
|
|
$('.my_join2, .my_login2').hide();
|
|
$('.my_join, .my_login').show();
|
|
$('#my_join2').html(""); // 혹시모를 내용 초기화
|
|
}
|
|
}
|
|
|
|
function descopeLogout() {
|
|
fetch('/eng/skin/member/basic/descope_logout.php', {
|
|
method: 'POST',
|
|
credentials: 'include' // PHPSESSID 쿠키 전송
|
|
})
|
|
.then(res => {
|
|
if (!res.ok) throw new Error('서버 로그아웃 실패');
|
|
// 1) 로컬 저장소 정리
|
|
// sessionStorage.removeItem("refreshJwt");
|
|
// sessionStorage.removeItem("sessionJwt");
|
|
// sessionStorage.removeItem("userRole");
|
|
// sessionStorage.removeItem("userName");
|
|
// sessionStorage.removeItem("loginId");
|
|
|
|
sessionStorage.clear();
|
|
localStorage.clear();
|
|
// 2) UI 갱신
|
|
updateHeaderMenu();
|
|
// 3) 로그인 페이지로 이동
|
|
window.location.href = '/eng/index.php';
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
alert('로그아웃 중 오류가 발생했습니다.');
|
|
});
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
// 기존에 있던 updateHeaderMenu() 호출 뒤에
|
|
$('#my_login2 a').off('click').on('click', function(e){
|
|
e.preventDefault();
|
|
descopeLogout();
|
|
});
|
|
});
|
|
|
|
$(document).ready(function() {
|
|
updateHeaderMenu();
|
|
// (필요하다면, 로그인 성공 후에도 항상 updateHeaderMenu(); 호출)
|
|
});
|
|
|
|
//descope login
|
|
$('#flogin button[type=submit]').click(function(e){
|
|
e.preventDefault();
|
|
let mb_id = $('#login_id').val();
|
|
let mb_password = $('#login_pw').val();
|
|
|
|
$.ajax({
|
|
url : '/eng/skin/member/basic/descope_login.php',
|
|
data : {
|
|
'mb_id' : mb_id,
|
|
'mb_password' : mb_password
|
|
},
|
|
type : "POST",
|
|
dataType : "json",
|
|
success : function(res){
|
|
if(res.status === "ok") {
|
|
// 토큰 저장
|
|
// sessionStorage.setItem("refreshJwt", res.refreshJwt);
|
|
sessionStorage.setItem("sessionJwt", res.sessionJwt);
|
|
|
|
// ✅ 사용자 정보 저장
|
|
if (res.user) {
|
|
sessionStorage.setItem("loginId", res.user.loginIds?.[0] || '');
|
|
sessionStorage.setItem("userName", res.user.name || '');
|
|
sessionStorage.setItem("company", res.user.customAttributes?.company || '');
|
|
sessionStorage.setItem("familyCompany", res.user.customAttributes?.familyCompany || '');
|
|
sessionStorage.setItem("position", res.user.customAttributes?.position || '');
|
|
sessionStorage.setItem("team", res.user.customAttributes?.team || '');
|
|
sessionStorage.setItem("familyUniqueKey", res.user.customAttributes?.familyUniqueKey || '');
|
|
sessionStorage.setItem("phone", res.user.phone || '');
|
|
}
|
|
|
|
// ✅ 추가: 관리자 등 정보 저장
|
|
if(res.user && res.user.roleNames && res.user.roleNames[0])
|
|
sessionStorage.setItem("userRole", res.user.roleNames[0]);
|
|
else
|
|
sessionStorage.removeItem("userRole");
|
|
|
|
// ✅ 로그인 후 메뉴 갱신
|
|
updateHeaderMenu();
|
|
|
|
// UI 처리
|
|
$('.popup_wrap').hide();
|
|
$('body').css('overflow', '');
|
|
lenis.start();
|
|
// alert('로그인 하셨습니다.');
|
|
} else {
|
|
alert(res.message || "로그인 실패");
|
|
|
|
// 🔴 실패 횟수에 따라 안내 배너 교체
|
|
if (res.failCount && res.failCount >= 8) {
|
|
updateLoginBanner("fail");
|
|
}
|
|
}
|
|
},
|
|
error : function(err){
|
|
alert(err.statusText || "통신 오류");
|
|
}
|
|
});
|
|
});
|
|
|
|
// ✅ 배너 교체 함수
|
|
function updateLoginBanner(type = "default") {
|
|
const $banner = $('#login_notice_banner');
|
|
if (!$banner.length) return;
|
|
|
|
if (type === "default") {
|
|
$banner.css({ background: "#063e01ff", color: "#fff" });
|
|
$banner.find("strong").text("[로그인 시스템 변경 안내]");
|
|
$banner.find("p.left").html(`
|
|
더 나은 보안을 위해 2025년 8월 8일부터 로그인 시스템이 변경되었습니다.<br>
|
|
기존 회원 또한 신규 시스템에 맞춰 재가입을 진행해주시기 바랍니다.
|
|
`);
|
|
$banner.find("p:last").html(`※ 로그인 및 가입 관련 문의: <strong>010-8721-7453</strong>`);
|
|
}
|
|
|
|
if (type === "fail") {
|
|
$banner.css({ background: "#6a0202ff", color: "#faf6f6ff" });
|
|
$banner.find("strong").text("[로그인 시도 제한 안내]");
|
|
$banner.find("p.left").html(`
|
|
비밀번호 입력을 <strong>7회 이상 연속 실패</strong>하셨습니다.<br>
|
|
<strong>8번째 시도부터 3분 대기</strong>가 적용됩니다.<br>
|
|
10회 이상 실패 시 계정이 잠금 처리됩니다.
|
|
`);
|
|
$banner.find("p:last").text("");
|
|
}
|
|
}
|
|
|
|
//회원가입 약관동의
|
|
$('#fregister button[type=submit]').click(function(e){
|
|
e.preventDefault();
|
|
let agree11 = $('#agree11').val();
|
|
let agree21 = $('#agree21').val();
|
|
$.ajax({
|
|
url : '<?php echo G5_URL ?>/bbs/register_form.php',
|
|
type : "POST",
|
|
datatype : "json",
|
|
contentType: 'application/json; charset=utf-8',
|
|
data : {
|
|
'agree11' : agree11,
|
|
'agree21' : agree21
|
|
},
|
|
success : function(data){
|
|
var ss='';
|
|
for(i=0; i<data.length; i++){
|
|
ss=ss + data[i];
|
|
}
|
|
},
|
|
error : function(err){
|
|
alert(err);
|
|
}
|
|
});
|
|
});
|
|
|
|
// 이지빔 프로그램 회원가입 url 쿼리스트링 파싱 함수
|
|
function getQueryString(name) {
|
|
const intro = document.querySelector('.intro_wrap');
|
|
if (intro) {
|
|
intro.style.display = "none";
|
|
}
|
|
const mainMask = document.querySelector('.main_mask');
|
|
if (mainMask) {
|
|
mainMask.classList.add('skip');
|
|
}
|
|
// mainMask.style.aimation = 'none';
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
return urlParams.get(name);
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
const popupParam = getQueryString('popup');
|
|
|
|
if (popupParam === 'signup') {
|
|
console.log('쿼리 감지: signup → 회원가입 팝업 자동 오픈 시도');
|
|
$('#pop_agreement').show(); // 팝업 보여주기
|
|
|
|
// 스크롤 잠금 (사용 중이면)
|
|
$('body').css('overflow', 'hidden');
|
|
if (typeof lenis !== 'undefined') {
|
|
lenis.stop();
|
|
}
|
|
}
|
|
|
|
// 팝업 닫기 버튼 이벤트 연결
|
|
$('#pop_agreement .btn_close').on('click', function() {
|
|
$('#pop_agreement').hide();
|
|
$('body').css('overflow', '');
|
|
if (typeof lenis !== 'undefined') {
|
|
lenis.start();
|
|
}
|
|
});
|
|
});
|
|
|
|
//이지빔 프로그램 비밀번호 재설정 url 쿼리스트링 파싱 함수
|
|
$(document).ready(function() {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const popup = urlParams.get('popup');
|
|
const token = urlParams.get('t');
|
|
|
|
if (popup === 'pwreset') {
|
|
// 팝업 전체 열기
|
|
$('#pop_search').show();
|
|
$('body').css('overflow', 'hidden');
|
|
|
|
// 내부 컨텐츠 모두 숨기기
|
|
$('#pop_search .popup_contents_wrap').hide();
|
|
|
|
if (token) {
|
|
// 토큰이 있으면 비밀번호 재설정 단계
|
|
if (!sessionStorage.getItem('pwreset_shown')) {
|
|
$('#password_reset').show();
|
|
sessionStorage.setItem('pwreset_shown', '1');
|
|
}
|
|
} else {
|
|
// 토큰이 없으면 아이디 입력 단계 (첫 번째 .popup_contents_wrap)
|
|
$('#pop_search .popup_contents_wrap').first().show();
|
|
}
|
|
}
|
|
|
|
// 닫기 버튼
|
|
$('#pop_search .btn_close').on('click', function() {
|
|
$('#pop_search').hide();
|
|
$('body').css('overflow', '');
|
|
});
|
|
});
|
|
</script>
|