한글뷰어 기능수정 Ver.01
This commit is contained in:
@@ -407,6 +407,46 @@
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
/* Pagination styling */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.pagination-btn {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border);
|
||||
background-color: var(--card-bg);
|
||||
color: var(--text-main);
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.pagination-btn:hover:not(:disabled) {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
background-color: var(--primary-soft);
|
||||
}
|
||||
|
||||
.pagination-btn.active {
|
||||
background-color: var(--primary);
|
||||
color: #ffffff;
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.pagination-btn:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
table.admin-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
@@ -814,7 +854,7 @@
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">📢 실시간 배너 공지사항 등록</h3>
|
||||
</div>
|
||||
<form class="config-form" style="gap: 20px;" onsubmit="handleBannerSubmit(event)">
|
||||
<form class="config-form" style="gap: 20px;" onsubmit="submitBannerForm(event)">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="banner-project-select">공지 대상 프로젝트</label>
|
||||
@@ -1030,6 +1070,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Pagination Controls -->
|
||||
<div id="audit-log-pagination" class="pagination-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1428,6 +1470,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 날짜 문자열을 클라이언트 로컬 타임존 기반의 YYYY-MM-DD HH:mm:ss 형식으로 변환하는 함수
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return '-';
|
||||
const date = new Date(dateStr);
|
||||
if (isNaN(date.getTime())) return dateStr;
|
||||
const YYYY = date.getFullYear();
|
||||
const MM = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const DD = String(date.getDate()).padStart(2, '0');
|
||||
const HH = String(date.getHours()).padStart(2, '0');
|
||||
const mm = String(date.getMinutes()).padStart(2, '0');
|
||||
const ss = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}`;
|
||||
}
|
||||
|
||||
// 로그인 사용자 프로필 로드 함수
|
||||
async function loadUserProfile() {
|
||||
try {
|
||||
@@ -2275,7 +2331,7 @@
|
||||
}
|
||||
|
||||
// --- 7. 활동 로그 조회 탭 (Activity Logs) ---
|
||||
async function renderAuditLogs() {
|
||||
async function renderAuditLogs(page = 1) {
|
||||
const userId = document.getElementById('search-log-user').value.trim();
|
||||
const projectNm = document.getElementById('search-log-project').value.trim();
|
||||
const action = document.getElementById('filter-log-action').value.trim();
|
||||
@@ -2284,16 +2340,22 @@
|
||||
if (userId) params.append('user_id', userId);
|
||||
if (projectNm) params.append('project_nm', projectNm);
|
||||
if (action) params.append('activity', action);
|
||||
params.append('page', page);
|
||||
params.append('limit', 20);
|
||||
|
||||
let queryUrl = `/api/admin/audit-logs?${params.toString()}`;
|
||||
|
||||
try {
|
||||
const logs = await fetchAPI(queryUrl);
|
||||
const resData = await fetchAPI(queryUrl);
|
||||
const logs = resData.data;
|
||||
const pagination = resData.pagination;
|
||||
|
||||
const body = document.getElementById('audit-log-body');
|
||||
body.innerHTML = '';
|
||||
|
||||
if (logs.length === 0) {
|
||||
if (!logs || logs.length === 0) {
|
||||
body.innerHTML = `<tr><td colspan="7" style="text-align: center; color: var(--text-light); padding: 24px 0;">조회된 활동 로그 내역이 없습니다.</td></tr>`;
|
||||
document.getElementById('audit-log-pagination').innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2305,9 +2367,11 @@
|
||||
cleanPath = '/' + log.criteria_info.filter(p => p).join('/');
|
||||
}
|
||||
|
||||
const rowNumber = pagination.total - ((pagination.page - 1) * pagination.limit) - idx;
|
||||
|
||||
tr.innerHTML = `
|
||||
<td>${idx + 1}</td>
|
||||
<td>${log.clean_date ? log.clean_date.replace('T', ' ').substring(0, 19) : '-'}</td>
|
||||
<td>${rowNumber}</td>
|
||||
<td>${formatDate(log.clean_date)}</td>
|
||||
<td><strong>${log.project_nm || log.project_id || '-'}</strong></td>
|
||||
<td>${log.user_id || '-'}</td>
|
||||
<td>${log.user_ip || '-'}</td>
|
||||
@@ -2316,11 +2380,53 @@
|
||||
`;
|
||||
body.appendChild(tr);
|
||||
});
|
||||
|
||||
renderPaginationControls(pagination);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
function renderPaginationControls(pagination) {
|
||||
const container = document.getElementById('audit-log-pagination');
|
||||
container.innerHTML = '';
|
||||
|
||||
const { page, totalPages } = pagination;
|
||||
if (totalPages <= 1) return;
|
||||
|
||||
const prevBtn = document.createElement('button');
|
||||
prevBtn.className = 'pagination-btn';
|
||||
prevBtn.innerText = '이전';
|
||||
prevBtn.disabled = page === 1;
|
||||
prevBtn.onclick = () => renderAuditLogs(page - 1);
|
||||
container.appendChild(prevBtn);
|
||||
|
||||
const maxPageButtons = 5;
|
||||
let startPage = Math.max(1, page - Math.floor(maxPageButtons / 2));
|
||||
let endPage = startPage + maxPageButtons - 1;
|
||||
|
||||
if (endPage > totalPages) {
|
||||
endPage = totalPages;
|
||||
startPage = Math.max(1, endPage - maxPageButtons + 1);
|
||||
}
|
||||
|
||||
for (let i = startPage; i <= endPage; i++) {
|
||||
const pageBtn = document.createElement('button');
|
||||
pageBtn.className = `pagination-btn ${i === page ? 'active' : ''}`;
|
||||
pageBtn.innerText = i;
|
||||
pageBtn.onclick = () => renderAuditLogs(i);
|
||||
container.appendChild(pageBtn);
|
||||
}
|
||||
|
||||
const nextBtn = document.createElement('button');
|
||||
nextBtn.className = 'pagination-btn';
|
||||
nextBtn.innerText = '다음';
|
||||
nextBtn.disabled = page === totalPages;
|
||||
nextBtn.onclick = () => renderAuditLogs(page + 1);
|
||||
container.appendChild(nextBtn);
|
||||
}
|
||||
|
||||
// --- 8. 글로벌 삭제 정책 설정 탭 (Policies) ---
|
||||
async function renderDeletePolicy() {
|
||||
try {
|
||||
@@ -2345,7 +2451,7 @@
|
||||
const tr = document.createElement('tr');
|
||||
tr.innerHTML = `
|
||||
<td>${idx + 1}</td>
|
||||
<td>${l.clean_date ? l.clean_date.replace('T', ' ').substring(0, 19) : '-'}</td>
|
||||
<td>${formatDate(l.clean_date)}</td>
|
||||
<td><strong>${l.project_id}</strong></td>
|
||||
<td style="max-width: 250px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;">${l.clean_path}</td>
|
||||
<td>${l.criteria_info}</td>
|
||||
|
||||
@@ -14,4 +14,49 @@
|
||||
} */
|
||||
|
||||
/* 폰트적용 */
|
||||
/* * { font-family: 'Noto Sans KR', 'Protest Riot', 'Gowun Dodum', sans-serif; } */
|
||||
/* * { font-family: 'Noto Sans KR', 'Protest Riot', 'Gowun Dodum', sans-serif; } */
|
||||
|
||||
/* Noto Sans KR & Noto Serif KR 임포트 */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;700&family=Noto+Serif+KR:wght@300;400;700&display=swap');
|
||||
|
||||
/* 한양굴림, 한컴바탕 등 한글 기본 폰트의 웹 폰트 대체 매핑 */
|
||||
@font-face {
|
||||
font-family: '바탕';
|
||||
src: local('바탕'), local('Batang'), url('https://fonts.gstatic.com/s/notoserifkr/v18/jvra712_5C0LaY5Bp242iPfYE5m3Kg.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '바탕체';
|
||||
src: local('바탕체'), local('BatangChe'), url('https://fonts.gstatic.com/s/notoserifkr/v18/jvra712_5C0LaY5Bp242iPfYE5m3Kg.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '함초롬바탕';
|
||||
src: local('함초롬바탕'), url('https://fonts.gstatic.com/s/notoserifkr/v18/jvra712_5C0LaY5Bp242iPfYE5m3Kg.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '돋움';
|
||||
src: local('돋움'), local('Dotum'), url('https://fonts.gstatic.com/s/notosanskr/v27/PbykF3t50S0B5K_7Jea-vUDz1g.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '돋움체';
|
||||
src: local('돋움체'), local('DotumChe'), url('https://fonts.gstatic.com/s/notosanskr/v27/PbykF3t50S0B5K_7Jea-vUDz1g.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '함초롬돋움';
|
||||
src: local('함초롬돋움'), url('https://fonts.gstatic.com/s/notosanskr/v27/PbykF3t50S0B5K_7Jea-vUDz1g.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '굴림';
|
||||
src: local('굴림'), local('Gulim'), url('https://fonts.gstatic.com/s/notosanskr/v27/PbykF3t50S0B5K_7Jea-vUDz1g.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '굴림체';
|
||||
src: local('굴림체'), local('GulimChe'), url('https://fonts.gstatic.com/s/notosanskr/v27/PbykF3t50S0B5K_7Jea-vUDz1g.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '궁서';
|
||||
src: local('궁서'), local('Gungsuh'), url('https://fonts.gstatic.com/s/notoserifkr/v18/jvra712_5C0LaY5Bp242iPfYE5m3Kg.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: '궁서체';
|
||||
src: local('궁서체'), local('GungsuhChe'), url('https://fonts.gstatic.com/s/notoserifkr/v18/jvra712_5C0LaY5Bp242iPfYE5m3Kg.woff2') format('woff2');
|
||||
}
|
||||
@@ -425,7 +425,7 @@ body > .control-box .contents-wrap .btn-wrap .btn.selected.map .icon { backgroun
|
||||
|
||||
|
||||
/* 아카이브 우측 영역 (미리보기, 메모(AI요약), 메타데이터) */
|
||||
.archive-main-right { min-width: 41rem; max-width: 41rem; height: 100%; background: #fff; position: relative; }
|
||||
.archive-main-right { min-width: 55rem; max-width: 55rem; height: 100%; background: #fff; position: relative; }
|
||||
|
||||
.archive-main-right .viewer-container { display: none; flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 100%; position: relative; }
|
||||
|
||||
@@ -1184,12 +1184,12 @@ body > .control-box .contents-wrap .btn-wrap .btn.selected.map .icon { backgroun
|
||||
.archive-main-center .list-notice .list-notice-box .list-notice-bottom .list-notice-bottom-footer .list-notice-negative h3 { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; letter-spacing: -0.0175rem; color: #111; }
|
||||
.archive-main-center .list-notice .list-notice-box .list-notice-bottom .list-notice-bottom-footer .list-notice-positive h3 { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; letter-spacing: -0.0175rem; }
|
||||
.archive-main-center .list-notice .list-notice-box .list-notice-bottom .list-notice-bottom-body h4 { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; letter-spacing: -0.0175rem; }
|
||||
/* .archive-main-center .list-notice .list-notice-box-toggle { background-color: #fff; border: 0.063rem solid #ddd; padding: 0.375rem; border-radius: 0.25rem; display: flex; cursor: pointer; position: absolute; z-index: 11; top: 2.5rem; right: 41.5rem; } */
|
||||
/* .archive-main-center .list-notice .list-notice-box-toggle { background-color: #fff; border: 0.063rem solid #ddd; padding: 0.375rem; border-radius: 0.25rem; display: flex; cursor: pointer; position: absolute; z-index: 11; top: 2.5rem; right: 55.5rem; } */
|
||||
.list-notice-box-toggle { background-color: #fff; border: 0.0625rem solid #ddd; border-radius: 0.25rem; padding: 0.25rem; cursor: pointer; position: absolute; z-index: 40; top: 0.625rem; right: 0.625rem; }
|
||||
|
||||
|
||||
.archive-main-center .list-notice .list-notice-box-toggle:hover { background-color: #eee;}
|
||||
.archive-main-center .list-notice .list-notice-box-toggle-menu { display: flex; flex-direction: column; gap: 0.25rem; background-color: #fff; border: 0.063rem solid #ddd; border-radius: 0.25rem; padding: 0.5rem 1rem; min-width: 12rem; max-width:12rem; position: absolute; z-index: 11; top: 4.82rem; right: 41.5rem; box-shadow: 0rem 0.5rem 1.5rem 0rem rgba(0, 0, 0, 0.16); }
|
||||
.archive-main-center .list-notice .list-notice-box-toggle-menu { display: flex; flex-direction: column; gap: 0.25rem; background-color: #fff; border: 0.063rem solid #ddd; border-radius: 0.25rem; padding: 0.5rem 1rem; min-width: 12rem; max-width:12rem; position: absolute; z-index: 11; top: 4.82rem; right: 55.5rem; box-shadow: 0rem 0.5rem 1.5rem 0rem rgba(0, 0, 0, 0.16); }
|
||||
.archive-main-center .list-notice .list-notice-box-toggle-menu-list { display: flex; align-items: center; gap: 0.5rem; }
|
||||
.archive-main-center .list-notice .list-notice-box-toggle-menu-list:hover { cursor: pointer; background: #ccc; }
|
||||
.archive-main-center .list-notice .list-notice-box-toggle-menu-list h3 { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; letter-spacing: -0.0175rem; color: #111; }
|
||||
|
||||
@@ -5487,6 +5487,7 @@ export async function renderViewer(resourcePath, dataId, shouldAddClickLog = tru
|
||||
|
||||
function viewerExcel(presignedUrl) {
|
||||
vars.viewer.innerHTML = '<div style="display:flex;justify-content:center;align-items:center;height:100%;font-size:1.2rem;color:#666;background:#fff;">엑셀 데이터를 불러오는 중...</div>';
|
||||
initMainFallbackPdfButton(dataId, resourcePath, objectKey, previewKey);
|
||||
|
||||
fetch(presignedUrl)
|
||||
.then(res => {
|
||||
@@ -5616,18 +5617,33 @@ export async function renderViewer(resourcePath, dataId, shouldAddClickLog = tru
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '100%';
|
||||
container.style.height = '100%';
|
||||
container.style.overflow = 'auto';
|
||||
container.style.overflowX = 'auto';
|
||||
container.style.overflowY = 'auto';
|
||||
container.style.padding = '20px';
|
||||
container.style.boxSizing = 'border-box';
|
||||
container.style.background = '#f5f5f5';
|
||||
|
||||
const styleEl = document.createElement('style');
|
||||
styleEl.textContent = `
|
||||
.hwp-inner-container {
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
width: max-content;
|
||||
min-width: 800px;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
|
||||
padding: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
min-height: 100%;
|
||||
}
|
||||
.hwp-inner-container img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
`;
|
||||
container.appendChild(styleEl);
|
||||
|
||||
const hwpInner = document.createElement('div');
|
||||
hwpInner.style.background = '#ffffff';
|
||||
hwpInner.style.margin = '0 auto';
|
||||
hwpInner.style.maxWidth = '800px';
|
||||
hwpInner.style.boxShadow = '0 4px 10px rgba(0,0,0,0.1)';
|
||||
hwpInner.style.padding = '40px';
|
||||
hwpInner.style.minHeight = '100%';
|
||||
hwpInner.classList.add('hwp-inner-container');
|
||||
|
||||
container.appendChild(hwpInner);
|
||||
vars.viewer.appendChild(container);
|
||||
|
||||
@@ -733,6 +733,7 @@ export async function renderDocViewer(resourcePath, docId) {
|
||||
|
||||
function viewerExcel(presignedUrl) {
|
||||
docVars.viewer.innerHTML = '<div style="display:flex;justify-content:center;align-items:center;height:100%;font-size:1.2rem;color:#666;background:#fff;">엑셀 데이터를 불러오는 중...</div>';
|
||||
initDocFallbackPdfButton(docId, resourcePath, objectKey, previewKey);
|
||||
|
||||
fetch(presignedUrl)
|
||||
.then(res => {
|
||||
@@ -862,7 +863,7 @@ export async function renderDocViewer(resourcePath, docId) {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '100%';
|
||||
container.style.height = '100%';
|
||||
container.style.overflowX = 'hidden';
|
||||
container.style.overflowX = 'auto';
|
||||
container.style.overflowY = 'auto';
|
||||
container.style.padding = '20px';
|
||||
container.style.boxSizing = 'border-box';
|
||||
@@ -873,38 +874,17 @@ export async function renderDocViewer(resourcePath, docId) {
|
||||
.hwp-inner-container {
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
width: max-content;
|
||||
min-width: 800px;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
|
||||
padding: 30px !important;
|
||||
padding: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
min-height: 100%;
|
||||
}
|
||||
.hwp-inner-container > div > div {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
box-sizing: border-box !important;
|
||||
padding-left: 20px !important;
|
||||
padding-right: 20px !important;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
.hwp-inner-container table {
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
table-layout: fixed !important;
|
||||
}
|
||||
.hwp-inner-container img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.hwp-inner-container {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.hwp-inner-container > div > div {
|
||||
padding-left: 10px !important;
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
container.appendChild(styleEl);
|
||||
|
||||
|
||||
@@ -674,6 +674,10 @@ function _openExcel(path, data) {
|
||||
const viewer = document.getElementById('popup_viewer');
|
||||
viewer.innerHTML = '<div style="display:flex;justify-content:center;align-items:center;height:100%;font-size:1.2rem;color:#666;background:#fff;">엑셀 데이터를 불러오는 중...</div>';
|
||||
|
||||
if (dataId && path_name) {
|
||||
initFallbackPdfButton(dataId, path_name, resourcePath);
|
||||
}
|
||||
|
||||
fetch(path)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText}`);
|
||||
@@ -815,7 +819,7 @@ function _openHwp(path, data) {
|
||||
const container = document.createElement('div');
|
||||
container.style.width = '100%';
|
||||
container.style.height = '100%';
|
||||
container.style.overflowX = 'hidden';
|
||||
container.style.overflowX = 'auto';
|
||||
container.style.overflowY = 'auto';
|
||||
container.style.padding = '20px';
|
||||
container.style.boxSizing = 'border-box';
|
||||
@@ -826,38 +830,17 @@ function _openHwp(path, data) {
|
||||
.hwp-inner-container {
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
width: max-content;
|
||||
min-width: 800px;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
|
||||
padding: 30px !important;
|
||||
padding: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
min-height: 100%;
|
||||
}
|
||||
.hwp-inner-container > div > div {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
box-sizing: border-box !important;
|
||||
padding-left: 20px !important;
|
||||
padding-right: 20px !important;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
.hwp-inner-container table {
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
table-layout: fixed !important;
|
||||
}
|
||||
.hwp-inner-container img {
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.hwp-inner-container {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.hwp-inner-container > div > div {
|
||||
padding-left: 10px !important;
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
container.appendChild(styleEl);
|
||||
|
||||
|
||||
@@ -3483,6 +3483,9 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docx-preview@0.1.18/dist/docx-preview.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/docx-preview@0.1.18/dist/docx-preview.min.js"></script>
|
||||
|
||||
<!-- wmf.js (WMF 이미지 렌더러) -->
|
||||
<script src="/libs/wmf.js"></script>
|
||||
|
||||
<!-- hwp.js (한글 뷰어) 스크립트 -->
|
||||
<script src="/libs/hwp.js"></script>
|
||||
|
||||
|
||||
@@ -133,6 +133,11 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docx-preview@0.1.18/dist/docx-preview.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/docx-preview@0.1.18/dist/docx-preview.min.js"></script>
|
||||
|
||||
<!-- font.css (한글 기본 폰트 매핑) -->
|
||||
<link rel="stylesheet" href="/main/css/font.css">
|
||||
<!-- wmf.js (WMF 이미지 렌더링) -->
|
||||
<script src="/libs/wmf.js"></script>
|
||||
|
||||
<!-- hwp.js (한글 뷰어) 스크립트 -->
|
||||
<script src="/libs/hwp.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.8.1/github-markdown.min.css">
|
||||
|
||||
Reference in New Issue
Block a user