Compare commits
3 Commits
41406f56e8
...
db_setting
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f165faf13 | ||
|
|
237ac9ee25 | ||
| f41f2378d7 |
@@ -1,30 +0,0 @@
|
|||||||
# 📝 작업 보고서 (2026-06-15)
|
|
||||||
|
|
||||||
## 1. 서버 및 개발 환경 설정
|
|
||||||
- **백엔드 서버 구동**: 3000번 포트(DB 서버) 정상 구동 완료.
|
|
||||||
- **프론트엔드 서버 구동**: 8080번 포트 정상 구동 완료.
|
|
||||||
- **브랜치 전환**: \`db_setting\` 브랜치로 전환 및 최신 코드 Pull 완료.
|
|
||||||
|
|
||||||
## 2. 데이터베이스 정제 및 보강 (Surgical Update)
|
|
||||||
- **사용자 정보(system_users) 업데이트**:
|
|
||||||
- 엑셀(\`system_User (20260615).xlsx\`) 기반 987건 신규 입력.
|
|
||||||
- 기존 백업 데이터(212건)와 병합하여 총 1,199건의 사용자 DB 구축.
|
|
||||||
- **PC 자산(asset_pc) 데이터 입력**:
|
|
||||||
- 엑셀(\`asset_pc (2026.06.15).xlsx\`) 기반 1,030건 입력 완료.
|
|
||||||
- **용량 정제**: 괄호 제거 및 4자리 GB 단위를 TB로 자동 변환 (예: 1863GB -> 1.86TB).
|
|
||||||
- **구매일 보강**: 연도 데이터에 월/일 추가 (\`YYYY-12-01\` 형식으로 통일).
|
|
||||||
- **자산번호 재매핑**: \`PC-YYYY12-NNNN\` 형식으로 전수 재부여 및 기존 번호와의 연속성 유지.
|
|
||||||
|
|
||||||
## 3. 부서 및 자산 유형 정상화
|
|
||||||
- **부서명 통합**: '총괄기획실', '기술개발센터', '한맥', '장헌', 'PTC', '현타' 등을 제외한 1,045건의 부서명을 **'삼안'**으로 일괄 통합.
|
|
||||||
- **자산 유형 교정 (핵심)**:
|
|
||||||
- 엑셀의 오기입과 상관없이 **사번(emp_no) 존재 여부**를 기준으로 자산 유형을 재분류.
|
|
||||||
- 사번이 있는 991건 -> **개인PC**로 정상화.
|
|
||||||
- 사번이 없는 39건 -> **공용PC**로 지정 및 사용자명 '공용'으로 정리.
|
|
||||||
|
|
||||||
## 4. 운영 규칙 업데이트
|
|
||||||
- **README.md 수정**: 'DB 삭제 및 초기화 절대 엄금 (Rule 5)' 항목 추가.
|
|
||||||
|
|
||||||
---
|
|
||||||
**보고자**: Gemini CLI
|
|
||||||
**상태**: 소스 코드 수정 없음, 데이터베이스 정제 완료.
|
|
||||||
Binary file not shown.
BIN
label/DevExpress.Data.v14.1.dll
Normal file
BIN
label/DevExpress.Data.v14.1.dll
Normal file
Binary file not shown.
BIN
label/DevExpress.Printing.v14.1.Core.dll
Normal file
BIN
label/DevExpress.Printing.v14.1.Core.dll
Normal file
Binary file not shown.
BIN
label/DevExpress.Utils.v14.1.dll
Normal file
BIN
label/DevExpress.Utils.v14.1.dll
Normal file
Binary file not shown.
BIN
label/DevExpress.XtraEditors.v14.1.dll
Normal file
BIN
label/DevExpress.XtraEditors.v14.1.dll
Normal file
Binary file not shown.
BIN
label/DevExpress.XtraGrid.v14.1.dll
Normal file
BIN
label/DevExpress.XtraGrid.v14.1.dll
Normal file
Binary file not shown.
BIN
label/DevExpress.XtraLayout.v14.1.dll
Normal file
BIN
label/DevExpress.XtraLayout.v14.1.dll
Normal file
Binary file not shown.
BIN
label/DevExpress.XtraPrinting.v14.1.dll
Normal file
BIN
label/DevExpress.XtraPrinting.v14.1.dll
Normal file
Binary file not shown.
BIN
label/LabelPrinter.exe
Normal file
BIN
label/LabelPrinter.exe
Normal file
Binary file not shown.
BIN
label/Newtonsoft.Json.dll
Normal file
BIN
label/Newtonsoft.Json.dll
Normal file
Binary file not shown.
BIN
label/WebQuery.dll
Normal file
BIN
label/WebQuery.dll
Normal file
Binary file not shown.
4
label/config.ini
Normal file
4
label/config.ini
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[PRINT]
|
||||||
|
FONT=8
|
||||||
|
LEFT=143
|
||||||
|
TOP=40
|
||||||
BIN
label/de/DevExpress.Data.v14.1.resources.dll
Normal file
BIN
label/de/DevExpress.Data.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/de/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
BIN
label/de/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
Binary file not shown.
BIN
label/de/DevExpress.Utils.v14.1.resources.dll
Normal file
BIN
label/de/DevExpress.Utils.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/de/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
BIN
label/de/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/de/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
BIN
label/de/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/de/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
BIN
label/de/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/de/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
BIN
label/de/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.Data.v14.1.resources.dll
Normal file
BIN
label/es/DevExpress.Data.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
BIN
label/es/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.Utils.v14.1.resources.dll
Normal file
BIN
label/es/DevExpress.Utils.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
BIN
label/es/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
BIN
label/es/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
BIN
label/es/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/es/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
BIN
label/es/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.Data.v14.1.resources.dll
Normal file
BIN
label/ja/DevExpress.Data.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
BIN
label/ja/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.Utils.v14.1.resources.dll
Normal file
BIN
label/ja/DevExpress.Utils.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
BIN
label/ja/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
BIN
label/ja/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
BIN
label/ja/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ja/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
BIN
label/ja/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.Data.v14.1.resources.dll
Normal file
BIN
label/ru/DevExpress.Data.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
BIN
label/ru/DevExpress.Printing.v14.1.Core.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.Utils.v14.1.resources.dll
Normal file
BIN
label/ru/DevExpress.Utils.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
BIN
label/ru/DevExpress.XtraEditors.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
BIN
label/ru/DevExpress.XtraGrid.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
BIN
label/ru/DevExpress.XtraLayout.v14.1.resources.dll
Normal file
Binary file not shown.
BIN
label/ru/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
BIN
label/ru/DevExpress.XtraPrinting.v14.1.resources.dll
Normal file
Binary file not shown.
7
label/tmp/file_1.txt
Normal file
7
label/tmp/file_1.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
자산번호 : 210312
|
||||||
|
자산명 : 가을-PC(i5-12400F)
|
||||||
|
공급사 : (주)가을디에스
|
||||||
|
자산위치 : 지반부
|
||||||
|
관리부서 : 전산
|
||||||
|
사용자 : 박노석
|
||||||
|
취득일자 : 2024-08-05
|
||||||
BIN
label/tmp/file_1.txt - 바로 가기.lnk
Normal file
BIN
label/tmp/file_1.txt - 바로 가기.lnk
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
import { state, saveAsset, deleteAsset } from '../../core/state';
|
import { state, saveAsset, deleteAsset } from '../../core/state';
|
||||||
import { ASSET_SCHEMA, UI_TEXT } from '../../core/schema';
|
import { ASSET_SCHEMA, UI_TEXT } from '../../core/schema';
|
||||||
import { calculatePcScoreDeductive, getPcGrade } from '../../core/utils';
|
import { calculatePcScoreDeductive, getPcGrade, API_BASE_URL } from '../../core/utils';
|
||||||
import {
|
import {
|
||||||
generateOptionsHTML,
|
generateOptionsHTML,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
@@ -377,6 +377,30 @@ class HwAssetModal extends BaseModal {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 자산코드가 비어있는 경우 자동 생성 처리
|
||||||
|
let assetCode = getFieldValue('hw-asset_code').trim();
|
||||||
|
if (!assetCode) {
|
||||||
|
const cat = categorySelect.value;
|
||||||
|
if (!cat) { alert('구분을 먼저 선택해주세요.'); return; }
|
||||||
|
const prefix = TYPE_PREFIX_MAP[cat] || 'ETC';
|
||||||
|
const purchaseDate = (document.getElementById('hw-purchase_date') as HTMLInputElement)?.value || '';
|
||||||
|
try {
|
||||||
|
const res = await fetch(`http://${location.hostname}:3000/api/generate-asset-code?prefix=${prefix}&purchaseDate=${purchaseDate}`);
|
||||||
|
const data = await res.json();
|
||||||
|
if (data.nextCode) {
|
||||||
|
setFieldValue('hw-asset_code', data.nextCode);
|
||||||
|
assetCode = data.nextCode;
|
||||||
|
} else {
|
||||||
|
alert('자산코드 자동 생성에 실패했습니다. 수동으로 생성 버튼을 눌러주세요.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('코드 자동 생성 실패:', err);
|
||||||
|
alert('자산코드 자동 생성 중 오류가 발생했습니다.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 동적 볼륨 데이터 수집
|
// 동적 볼륨 데이터 수집
|
||||||
const vols: any[] = [];
|
const vols: any[] = [];
|
||||||
document.querySelectorAll('#hw-volume-container .volume-row').forEach((row, idx) => {
|
document.querySelectorAll('#hw-volume-container .volume-row').forEach((row, idx) => {
|
||||||
@@ -704,7 +728,7 @@ class HwAssetModal extends BaseModal {
|
|||||||
|
|
||||||
private async fetchMapConfig() {
|
private async fetchMapConfig() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`http://${location.hostname}:3000/api/maps`);
|
const res = await fetch(`${API_BASE_URL}/api/maps`);
|
||||||
this.dynamicMapConfig = await res.json();
|
this.dynamicMapConfig = await res.json();
|
||||||
} catch (err) { console.error('Failed to fetch map config:', err); }
|
} catch (err) { console.error('Failed to fetch map config:', err); }
|
||||||
}
|
}
|
||||||
@@ -901,7 +925,7 @@ class HwAssetModal extends BaseModal {
|
|||||||
|
|
||||||
private async fetchMasterComponents(): Promise<void> {
|
private async fetchMasterComponents(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`http://${location.hostname}:3000/api/hardware-components`);
|
const res = await fetch(`${API_BASE_URL}/api/hardware-components`);
|
||||||
this.masterComponents = await res.json();
|
this.masterComponents = await res.json();
|
||||||
} catch (err) { console.error('Failed to fetch master components:', err); }
|
} catch (err) { console.error('Failed to fetch master components:', err); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,10 +125,13 @@ export function setEditLock(
|
|||||||
const inputs = form.querySelectorAll('input, select, textarea');
|
const inputs = form.querySelectorAll('input, select, textarea');
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
const el = input as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
const el = input as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
||||||
// 자산번호 및 ID 필드는 편집 모드에서도 잠금 유지
|
// 자산번호 및 ID 필드는 편집 모드에서도 잠금 유지 (disabled는 해제하되 readOnly를 적용하여 폼 데이터 수집 가능하게 함)
|
||||||
if (el.name !== 'asset_code' && !el.id.includes('asset-id') && !el.id.includes('id-hidden')) {
|
if (el.name !== 'asset_code' && !el.id.includes('asset-id') && !el.id.includes('id-hidden')) {
|
||||||
el.disabled = false;
|
el.disabled = false;
|
||||||
if ('readOnly' in el) (el as HTMLInputElement).readOnly = false;
|
if ('readOnly' in el) (el as HTMLInputElement).readOnly = false;
|
||||||
|
} else {
|
||||||
|
el.disabled = false;
|
||||||
|
if ('readOnly' in el) (el as HTMLInputElement).readOnly = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -537,6 +537,8 @@
|
|||||||
background-color: var(--canvas-soft-2);
|
background-color: var(--canvas-soft-2);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-map-container.readonly {
|
.layout-map-container.readonly {
|
||||||
@@ -546,12 +548,15 @@
|
|||||||
.image-marker-wrapper {
|
.image-marker-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-map-img {
|
.layout-map-img {
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 75vh;
|
max-height: 70vh;
|
||||||
|
object-fit: contain;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-drag: none;
|
-webkit-user-drag: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ export async function renderLocationView(container: HTMLElement) {
|
|||||||
: [];
|
: [];
|
||||||
const mapPath = locImages[currentPage] || '';
|
const mapPath = locImages[currentPage] || '';
|
||||||
|
|
||||||
// 조회 모드: 설정 파일에 정의된 asset_id를 기준으로 자산 데이터 매핑
|
|
||||||
const allBoxes = mapConfig[mapPath] || [];
|
|
||||||
const boxes = allBoxes.filter((box: any) => box.asset_id != null);
|
|
||||||
|
|
||||||
// 모든 하드웨어 카테고리에서 자산 검색
|
// 모든 하드웨어 카테고리에서 자산 검색
|
||||||
const allHwAssets = [
|
const allHwAssets = [
|
||||||
...state.masterData.pc,
|
...state.masterData.pc,
|
||||||
@@ -41,6 +37,50 @@ export async function renderLocationView(container: HTMLElement) {
|
|||||||
...state.masterData.pcParts
|
...state.masterData.pcParts
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// map_config.json에 설정된 모든 박스를 복사해서 작업용으로 사용
|
||||||
|
const tempBoxes = (mapConfig[mapPath] || []).map((b: any) => ({ ...b }));
|
||||||
|
|
||||||
|
// DB 데이터에서 현재 지도(mapPath) 및 위치와 좌표 정보(loc_x, loc_y)가 일치하는 자산 추출
|
||||||
|
allHwAssets.forEach((asset: any) => {
|
||||||
|
const photoPath = asset.location_photo || asset.loc_img || '';
|
||||||
|
const hasCoords = asset.loc_x != null && asset.loc_y != null && asset.loc_x !== '' && asset.loc_y !== '' && asset.loc_x !== 'null' && asset.loc_y !== 'null';
|
||||||
|
|
||||||
|
if (hasCoords && photoPath.trim() === mapPath.trim()) {
|
||||||
|
const ax = parseFloat(asset.loc_x);
|
||||||
|
const ay = parseFloat(asset.loc_y);
|
||||||
|
|
||||||
|
// map_config.json에서 읽어온 박스들 중 x, y 좌표가 일치하는 빈 박스가 있는지 찾음 (오차범위 0.1 고려)
|
||||||
|
const matchedBox = tempBoxes.find((b: any) => {
|
||||||
|
const bx = parseFloat(b.x);
|
||||||
|
const by = parseFloat(b.y);
|
||||||
|
return Math.abs(bx - ax) < 0.1 && Math.abs(by - ay) < 0.1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchedBox) {
|
||||||
|
// 이미 매칭된 박스가 존재하고 asset_id가 비어있다면 해당 박스에 asset_id를 주입
|
||||||
|
if (matchedBox.asset_id == null) {
|
||||||
|
matchedBox.asset_id = asset.id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 일치하는 기존 박스가 없을 때만 4x4 크기의 임시 박스로 동적 생성
|
||||||
|
const alreadyMatched = tempBoxes.some((b: any) => b.asset_id === asset.id);
|
||||||
|
if (!alreadyMatched) {
|
||||||
|
tempBoxes.push({
|
||||||
|
asset_id: asset.id,
|
||||||
|
x: asset.loc_x,
|
||||||
|
y: asset.loc_y,
|
||||||
|
w: '4',
|
||||||
|
h: '4',
|
||||||
|
name: asset.asset_purpose || asset.asset_code || '미지정 자산'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 최종적으로 asset_id가 null이 아닌(자산이 정상 매핑되거나 갱신된) 박스들만 남겨서 렌더링
|
||||||
|
const boxes = tempBoxes.filter((b: any) => b.asset_id != null);
|
||||||
|
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
<div class="location-view-wrapper">
|
<div class="location-view-wrapper">
|
||||||
<!-- 상단 통합 바 (Unified Search Bar) -->
|
<!-- 상단 통합 바 (Unified Search Bar) -->
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
|
||||||
|
const proxyTarget = process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:3000';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
server: {
|
server: {
|
||||||
port: 8080,
|
port: 8080,
|
||||||
host: true, // Listen on all local IPs
|
host: true, // Listen on all local IPs
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://localhost:3000',
|
target: proxyTarget,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
'/uploads': {
|
'/uploads': {
|
||||||
target: 'http://localhost:3000',
|
target: proxyTarget,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user