From 8682c7e7c60b035f2def9ae328821d0670b2f8e0 Mon Sep 17 00:00:00 2001 From: NAS-Admin Date: Wed, 4 Mar 2026 21:17:52 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MIGRATE_V2_FIN.php | 92 ++++++++++++++++++++++++++++++++++++++++++++ assets.db | Bin 196608 -> 196608 bytes migrate_data_v2.php | 38 ++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 MIGRATE_V2_FIN.php create mode 100644 migrate_data_v2.php diff --git a/MIGRATE_V2_FIN.php b/MIGRATE_V2_FIN.php new file mode 100644 index 0000000..336512b --- /dev/null +++ b/MIGRATE_V2_FIN.php @@ -0,0 +1,92 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + echo "--- [마이그레이션 시작] 노트북 자산 관리 시스템 v2 ---\n\n"; + + // 2. 백업 생성 (안전을 위한 rsync 성격의 파일 복사) + $backupPath = $dbPath . '.bak_' . date('Ymd_His'); + if (!copy($dbPath, $backupPath)) { + throw new Exception("데이터베이스 백업 생성 실패"); + } + echo "🛡️ 데이터 안전: 원본 백업이 생성되었습니다. ($backupPath)\n"; + + // 3. 스키마 확장 (컬럼 추가) + $newColumns = [ + 'real_user' => 'TEXT', + 'disposal_user_id' => 'INTEGER' + ]; + + foreach ($newColumns as $col => $type) { + try { + $db->exec("ALTER TABLE laptop_assets ADD COLUMN $col $type"); + echo "✅ 컬럼 추가 성공: $col\n"; + } catch (PDOException $e) { + if (strpos($e->getMessage(), 'duplicate column name') !== false) { + echo "ℹ️ 이미 존재함: $col (스키마 유지)\n"; + } else { + throw $e; + } + } + } + + // 4. 데이터 정합성 마이그레이션 - STOCK 상태 자산 명칭 동기화 + // 기존에 STOCK 상태인 모든 자산의 배정사용자를 '업무용(TEMP_44666b)'으로 통합 + $stmtStock = $db->prepare(" + UPDATE laptop_assets + SET assigned_user_name = '업무용(TEMP_44666b)', + current_user_id = NULL + WHERE status = 'stock' + AND (assigned_user_name != '업무용(TEMP_44666b)' OR assigned_user_name IS NULL) + "); + $stmtStock->execute(); + $affectedStock = $stmtStock->rowCount(); + echo "✅ 데이터 동기화: STOCK 자산 $affectedStock 건의 입력을 '업무용(TEMP_44666b)'으로 통일했습니다.\n"; + + // 5. 데이터 정합성 마이그레이션 - 매각 대상자 ID 복구 + // 기존 매각 대상자 이름(disposal_recipient)이 직원 리스트에 있다면 ID를 찾아 매핑 + $allDisposed = $db->query(" + SELECT id, disposal_recipient + FROM laptop_assets + WHERE status = 'disposed' + AND disposal_recipient IS NOT NULL + AND disposal_user_id IS NULL + ")->fetchAll(PDO::FETCH_ASSOC); + + $idRestored = 0; + $userFinder = $db->prepare("SELECT id FROM users WHERE name = ? LIMIT 1"); + $idUpdater = $db->prepare("UPDATE laptop_assets SET disposal_user_id = ? WHERE id = ?"); + + foreach ($allDisposed as $row) { + $userFinder->execute([$row['disposal_recipient']]); + $uid = $userFinder->fetchColumn(); + if ($uid) { + $idUpdater->execute([$uid, $row['id']]); + $idRestored++; + } + } + echo "✅ 데이터 정합성: DISPOSED 자산 $idRestored 건의 사번 ID를 자동 매핑했습니다.\n\n"; + + echo "--- [마이그레이션 완료] 시스템이 정상적으로 업데이트되었습니다. ---\n"; + +} catch (Exception $e) { + echo "\n❌ [마이그레이션 실패] 오류 내용: " . $e->getMessage() . "\n"; + if (isset($backupPath) && file_exists($backupPath)) { + echo "⚠️ 주의: 원본 데이터가 손상되었을 수 있으므로 백업 파일($backupPath)을 확인하십시오.\n"; + } +} diff --git a/assets.db b/assets.db index ed6a68c6a5dbd7a18d29c2591edd35ec2fe38614..7d42aafd2cecaa502953e8c2e2b60ffbd372f9a0 100644 GIT binary patch delta 3663 zcmbVPZA?>V6n@X`y}kXqt*8vO2%?lCopLGtbb>Hp>ZIUA=caRtU#R$j6cDEiwCLP| zniS?<#fc^^aXK-Ix|>Y5Y{sdHAKCn2OkA>vW)p{~`_hbT?!CRm(Mz?mrs=P~=Q;0l zp7WgZ*463i$Txw5caaWRk-mfbQMX+?UX!A_&i=*H^p}cwYRZWOmWqBP zw0Sn0!{JzfeN|vS7Qe8YqRFAV*rLzWVX=h6DkwG&r*9xFWF!3|Zm4#jW{Y~D zYP>RynWZSD21B-xz{3b&eAE4}rQ&I|5F1YjvBX&V5@K^_GWbs(mWN^BTn|`;SSwtl zX!b0s#zzl=32W@&5jijHC+C?i3LETl2$63g%>f^SNO(1VfFT)oIiXNYyC6#1_6!$; ze|O4b2GbtohAw3y-HddU3-l+rGNPl0>NeF$t(hIGe2aNcQAD`{fkvS%2W~59RX*yJ zz)$DF84)}$Dmc&J^LY`#(;U7+|3rzNr012S%}L?GufVeK3J`iyh4e}A0?=A5p@--( z1+ShA1)?Z(!gTZ;qIA;OJ2`?Vg`-nocCY~P*f14_jPn)vb5oI-v{Vw;tEGa9mn(?p ztvsJW+KRW@91Kp*h56xkAmvE2`-b_mNxEtjH(FwZ;}9485KT^qBzvdRiCt5{EDQD# zIK=8?MX8R>Wn-|XKvo@r}=etGiTV*xAeu`m`b$_5}j1 zBE)nFVqo8A~--q#k^;zdh)n@YO0gL{MbER>P~I9?YqMigCWz{j)+6=q=%>60kFPRgD}W zNX*uC1VMOvJ=|3ggI_~RFbC=HaLu|i+6U@ZRRIf13p10t4?hbDbx;g6y^P$q$_Et= zKjU92T{WbhBx0HqCDSxbFy{AlG-swuiTC)RDoj2?iytnKR$_XZJ+M(~_9an@W9Nyq z@x}=EN)v0lILdLG+sWXYn<5;y2-Id!(4zTuivF5{(;MKl=&vRHtgS7R!kGQdM$n%>WMw zWdT?OH2Gu5N*^{#?0Tbs+j%m6{%(u_o+esR#s9G)Lb&I{2v%ef7Ho$Giq;=Tm7?L7 zGrr~i%AN$X}P3BYmZ%a?U(HGohXntH-Y?ZeyJMpGp4ju1oJ`ncU$ZZ3g@XdGNVudT$Ae}X;&LIuyKZ0!39-wHAQ=P@mWZLO+ z>L22;D*=CS1J~$8-$K-Dvtga+b0#b delta 1738 zcmZ{leQZ-z7{@W3KcvIVA)-x$!7_hYa`JvfWB?F5IC?}dH9;UEr? zy99E`9Uqj9Yi9Ao9l@?maSKc*|&-k9^b7TD}e!4?NgfU zbG8)DX*_Hxp07T#klQ^l$uiT&phN2$)~%@adkek3qGGR)IGVu!D8g*TwE)s7VHGY> z70M;+f)GlySKd>OJ`1nX7b$oSF)xJ4WLpQASRXn>o(Mr6i6mf2Vq=vraiYe{2Jvi_ zA(xxU)AxNLSWVtNmDHg^S+fW_vgaFqq)tVUd7*s7_>}azzD+kvxXXXSEn`z)07ay9 z!{>%&`eFS?`hadg7t<{%bx)N}9nM59ySiIygWr2;y?}Rwrp} zpcafd^j;$@q~HPkO41>@>Cp~lD+L?jIS_FOzhpysAZ2BRXy)(!hbRqf5%739wTaS;qFsRy*R58#a|V^yL%JZ;Rpaq0$e zQ=+B9l3|@9V~;H7jYi7j@vCD^K1`X_RU20m#2b=h`Tgoxf2c>sg4*^eyakq0>2Jd! z{Q~h%v50?}{hg^t!|`~(GJFI+=G7Fxlcc`%8Qt~n%Euio{-~IP?0_;H4us4|wmXsR zahdaIZj-^Ct-yLUxcSPE0y-L)V3bvxdgJkK4%bApNbNarDrc_3B+=2bG-}P%u%;)moP}umT$kCd zV!5nzpDtd3w~6CC6e{0cg96b?XEQK%^$M$WfUz5Vy7S^v{yJC7{7Zwl7Rb(i*s}L5 zSRF0p(VS`j+Z&Da&c6=r$=<`);R4U$HPKwsHvsjt-b?nx;5Bs(iSQM@y?78V@@DNr p-kuzAP_ij0Ltv7)mSD7iWIv$#UAX}n^xtPr>)-=W1|Kl#+setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + echo "--- 🛠 데이터 일관성 점검 및 마이그레이션 중... ---\n"; + + // 1. 재고(STOCK) 상태인 자산의 배정사용자를 '업무용(TEMP_44666b)'으로 통합 + // 기존에 비어있거나 다른 이름이었던 경우 업데이트 + $stmt1 = $db->prepare("UPDATE laptop_assets + SET assigned_user_name = '업무용(TEMP_44666b)', current_user_id = NULL + WHERE status = 'stock' AND (assigned_user_name != '업무용(TEMP_44666b)' OR assigned_user_name IS NULL)"); + $stmt1->execute(); + echo "✅ 재고(STOCK) 자산의 배정사용자명을 '업무용(TEMP_44666b)'으로 동기화함. (수정건수: " . $stmt1->rowCount() . "건)\n"; + + // 2. 매각 대상자 ID 복구 시도 (문자열 이름 -> 정수 ID) + // 기존 disposal_recipient에 이름이 있는 경우 users 테이블과 대조하여 disposal_user_id 채우기 + $allDisposed = $db->query("SELECT id, disposal_recipient FROM laptop_assets WHERE status = 'disposed' AND disposal_recipient IS NOT NULL AND disposal_user_id IS NULL")->fetchAll(PDO::FETCH_ASSOC); + + $restoredCount = 0; + $userFinder = $db->prepare("SELECT id FROM users WHERE name = ? LIMIT 1"); + $idUpdater = $db->prepare("UPDATE laptop_assets SET disposal_user_id = ? WHERE id = ?"); + + foreach ($allDisposed as $row) { + $userFinder->execute([$row['disposal_recipient']]); + $uid = $userFinder->fetchColumn(); + if ($uid) { + $idUpdater->execute([$uid, $row['id']]); + $restoredCount++; + } + } + echo "✅ 매각 자산의 대상자 ID(disposal_user_id)를 사내 직원 데이터와 대조하여 복구함. (복구건수: $restoredCount 건)\n"; + + echo "--- 🎉 완료되었습니다. ---"; + +} catch (Exception $e) { + echo "❌ 오류: " . $e->getMessage() . "\n"; +}