978 lines
44 KiB
PHP
978 lines
44 KiB
PHP
<?php
|
|
if (!defined('_GNUBOARD_')) define('_GNUBOARD_', true);
|
|
|
|
// 스킨 안에서 쓰는 상수 최소 셋만 “직접” 정의 (필요시 경로 수정)
|
|
if (!defined('G5_URL')) define('G5_URL', '/egbim');
|
|
if (!defined('G5_BBS_URL')) define('G5_BBS_URL', '/egbim/bbs');
|
|
if (!defined('G5_IMG_URL')) define('G5_IMG_URL', '/egbim/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 관련 문의하기</span>
|
|
</div>
|
|
<ul class="sub_tab">
|
|
<li ><a href="/egbim/bbs/faq.php">자주하는 질문(FAQ)</a></li>
|
|
<li class="on"><a href="/egbim/bbs/descope_qa_list.php">문의하기(Q&A)</a></li>
|
|
<li><a href="https://939.co.kr/saman/" target="_blank">원격지원</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="/egbim/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="/egbim/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':'' ?>>문의접수</option>
|
|
<option value="review" <?= $post['status']==='review'?'selected':'' ?>>문의검토</option>
|
|
<option value="deep" <?= $post['status']==='deep'?'selected':'' ?>>정밀검토</option>
|
|
<option value="patch" <?= $post['status']==='patch'?'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>
|
|
<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='/egbim/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='/egbim/bbs/descope_qa_list.php'">
|
|
<i class="fa fa-list" aria-hidden="true"></i> 목록</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 = "/egbim/bbs/descope_qa_delete.php?id=" + id;
|
|
}
|
|
});
|
|
|
|
// function confirmDelete(pid) {
|
|
// if (confirm("정말 이 글을 삭제하시겠습니까?\n댓글과 첨부파일도 함께 삭제됩니다.")) {
|
|
// window.location.href = "/egbim/bbs/descope_qa_delete.php?id=" + pid;
|
|
// }
|
|
// }
|
|
</script>
|
|
<section class="comment-section">
|
|
<h4>댓글 (<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>
|
|
<?php if (!empty($c['images'])): ?>
|
|
<div class="comment-images" style="margin-top:6px; display:flex; gap:12px;">
|
|
<?php foreach ($c['images'] as $img): ?>
|
|
<div style="text-align:center;">
|
|
<img
|
|
src="/egbim<?= htmlspecialchars($img['thumb_path']) ?>"
|
|
onclick="window.open('/egbim<?= htmlspecialchars($img['file_path']) ?>', '_blank')"
|
|
style="width:140px; border-radius:6px; margin:4px; cursor:pointer;">
|
|
<div style="font-size:12px; color:#555; margin-top:4px; max-width:140px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
|
|
<?= htmlspecialchars($img['file_name']) ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- 작성자 + 날짜 같은 줄 -->
|
|
<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'] ?>">수정</button>
|
|
<button class="btn-delete" data-id="<?= $c['comment_id'] ?>">삭제</button>
|
|
<?php elseif (is_qna_admin()): ?>
|
|
<!-- 관리자: 삭제만 -->
|
|
<button class="btn-delete" data-id="<?= $c['comment_id'] ?>">삭제</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'] ?>">저장</button>
|
|
<button class="btn-cancel-edit">취소</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<!-- 신규 댓글 입력 -->
|
|
<?php if ($isLoggedIn): ?>
|
|
<form id="commentForm" enctype="multipart/form-data">
|
|
<div class="comment-row">
|
|
<!-- 댓글 입력 칸 -->
|
|
<textarea id="newComment" name="comment" class="input-text"
|
|
rows="3" placeholder="댓글을 입력하세요"></textarea>
|
|
|
|
<!-- 저장 버튼 -->
|
|
<button type="submit" class="btn-save">저장</button>
|
|
</div>
|
|
|
|
<!-- 댓글 입력칸 바로 아래에 위치하는 업로드 영역 -->
|
|
<div class="upload-wrap">
|
|
<label for="commentImages" class="img-upload-btn">📷 이미지 첨부</label>
|
|
<input type="file" id="commentImages" name="images[]" accept="image/*" multiple>
|
|
<span id="fileName" class="file-name">선택된 파일 없음</span>
|
|
|
|
<div id="previewArea"></div>
|
|
</div>
|
|
</form>
|
|
<?php else: ?>
|
|
<p style="color:#888;">댓글 작성은 로그인 후 이용 가능합니다.</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('commentForm')?.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const textEl = document.getElementById('newComment');
|
|
const fileEl = document.getElementById('commentImages');
|
|
const text = textEl.value.trim();
|
|
const files = fileEl.files;
|
|
|
|
// 댓글 내용이나 이미지가 둘 다 없는 경우 방지
|
|
if (!text && files.length === 0) {
|
|
alert('댓글 또는 이미지를 입력하세요.');
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append('postId', <?= json_encode($post['post_id']) ?>);
|
|
formData.append('comment', text);
|
|
for (let i = 0; i < files.length; i++) {
|
|
formData.append('images[]', files[i]);
|
|
}
|
|
|
|
try {
|
|
const res = await fetch('/egbim/bbs/descope_qa_comment.php', {
|
|
method: 'POST',
|
|
body: formData,
|
|
credentials: 'include'
|
|
});
|
|
|
|
const rawResponse = await res.text();
|
|
let json;
|
|
|
|
try {
|
|
// PHP Warning 메시지가 섞여 나올 경우를 대비해 JSON 시작점({)부터 파싱
|
|
const jsonStart = rawResponse.indexOf('{');
|
|
if (jsonStart === -1) throw new Error("JSON 데이터 없음");
|
|
json = JSON.parse(rawResponse.substring(jsonStart));
|
|
} catch (parseError) {
|
|
console.error("서버 응답 파싱 실패:", rawResponse);
|
|
throw new Error("서버 응답 형식이 올바르지 않습니다.");
|
|
}
|
|
|
|
if (json.status === 'ok') {
|
|
const commentsList = document.getElementById('comments');
|
|
const newCommentDiv = document.createElement('div');
|
|
newCommentDiv.className = 'comment';
|
|
newCommentDiv.id = `comment-${json.comment_id}`;
|
|
|
|
// ✅ 이미지 HTML 생성 (서버에서 넘겨준 imageList 활용)
|
|
let imageHTML = '';
|
|
if (json.images && json.images.length > 0) {
|
|
imageHTML = `<div class="comment-images" style="margin-top:6px; display:flex; gap:12px; flex-wrap:wrap;">`;
|
|
json.images.forEach(img => {
|
|
imageHTML += `
|
|
<div style="text-align:center;">
|
|
<img src="/egbim${img.thumb}"
|
|
onclick="window.open('/egbim${img.full}', '_blank')"
|
|
style="width:140px; border-radius:6px; margin:4px; cursor:pointer;"
|
|
alt="${img.name}">
|
|
<div style="font-size:12px; color:#555; margin-top:4px; max-width:140px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
|
|
${img.name}
|
|
</div>
|
|
</div>`;
|
|
});
|
|
imageHTML += `</div>`;
|
|
}
|
|
|
|
newCommentDiv.innerHTML = `
|
|
<div class="comment-body">
|
|
<div class="comment-text">${text.replace(/\n/g, '<br>')}</div>
|
|
${imageHTML}
|
|
<div class="comment-meta">
|
|
<span class="comment-author"><strong>${json.user_name}</strong></span>
|
|
<span class="comment-date"><small>${json.created_at}</small></span>
|
|
</div>
|
|
</div>
|
|
<div class="comment-actions" style="text-align:right;">
|
|
<button class="btn-edit" data-id="${json.comment_id}">수정</button>
|
|
<button class="btn-delete" data-id="${json.comment_id}">삭제</button>
|
|
</div>
|
|
<div class="comment-edit-box" style="display:none; margin-top:5px;">
|
|
<textarea class="comment-edit-input" rows="3">${text}</textarea>
|
|
<div class="comment-edit-actions" style="text-align:right; margin-top:3px;">
|
|
<button class="btn-save-edit" data-id="${json.comment_id}">저장</button>
|
|
<button class="btn-cancel-edit">취소</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
commentsList.appendChild(newCommentDiv);
|
|
|
|
// ✅ 댓글 수 카운트 갱신
|
|
const countEl = document.getElementById('comment-count');
|
|
if (countEl) {
|
|
countEl.innerText = parseInt(countEl.innerText || 0) + 1;
|
|
}
|
|
|
|
// 입력창 초기화
|
|
textEl.value = '';
|
|
fileEl.value = '';
|
|
document.getElementById('previewArea').innerHTML = '';
|
|
const fileNameEl = document.getElementById('fileName');
|
|
if (fileNameEl) fileNameEl.innerText = '선택된 파일 없음';
|
|
|
|
alert("댓글이 등록되었습니다.");
|
|
} else {
|
|
alert(json.message || "저장 중 오류가 발생했습니다.");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error:", error);
|
|
alert("통신 오류가 발생했습니다. 서버 응답을 확인하세요.");
|
|
}
|
|
});
|
|
|
|
// 댓글 수정 버튼
|
|
$(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("/egbim/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: "/egbim/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'].'/egbim/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 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=/egbim;";
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/egbim/bbs;";
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/egbim/faq;";
|
|
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/egbim/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/egbim/adm/index.php' target='_blank'>관리페이지</a>");
|
|
} else {
|
|
$('#my_join2').html("<a href='javascript:mypage03();'>마이페이지</a>");
|
|
}
|
|
} else {
|
|
$('.my_join2, .my_login2').hide();
|
|
$('.my_join, .my_login').show();
|
|
$('#my_join2').html(""); // 혹시모를 내용 초기화
|
|
}
|
|
}
|
|
|
|
function descopeLogout() {
|
|
fetch('/egbim/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 = '/egbim/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 : '/egbim/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', '');
|
|
});
|
|
});
|
|
|
|
// ✅ 댓글 이미지 미리보기
|
|
document.addEventListener("change", function(e) {
|
|
if (e.target.id === "commentImages") {
|
|
const preview = document.getElementById("previewArea");
|
|
preview.innerHTML = ""; // 초기화
|
|
|
|
[...e.target.files].forEach(file => {
|
|
|
|
// ▶ 개별 박스 생성
|
|
const box = document.createElement("div");
|
|
box.style.width = "80px";
|
|
box.style.marginRight = "6px";
|
|
box.style.textAlign = "center";
|
|
box.style.fontSize = "12px";
|
|
|
|
// ▶ 썸네일 이미지
|
|
const img = document.createElement("img");
|
|
img.src = URL.createObjectURL(file);
|
|
img.style.width = "80px";
|
|
img.style.height = "80px";
|
|
img.style.objectFit = "cover";
|
|
img.style.borderRadius = "6px";
|
|
img.style.display = "block";
|
|
|
|
// ▶ 파일명 (길면 ... 처리)
|
|
const name = document.createElement("div");
|
|
name.textContent = file.name;
|
|
name.style.marginTop = "4px";
|
|
name.style.whiteSpace = "nowrap";
|
|
name.style.overflow = "hidden";
|
|
name.style.textOverflow = "ellipsis";
|
|
|
|
// ▶ 박스에 넣기
|
|
box.appendChild(img);
|
|
box.appendChild(name);
|
|
|
|
// ▶ preview 영역에 넣기
|
|
preview.appendChild(box);
|
|
});
|
|
}
|
|
});
|
|
</script>
|