Project

General

Profile

Feature #146 » 模具管理_0716.html

鎮源 游, 07/16/2026 03:49 AM

 
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模具主檔 - 狀態變更維護控制系統</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
:root {
--primary-blue: #1e88e5;
--btn-blue: #2563eb;
--btn-green: #10b981;
--border-color: #e2e8f0;
--text-main: #1e293b;
--text-sub: #64748b;
/* 狀態色彩 (與設備管理一致) */
--status-running: #10b981; /* 生產中 - 綠 */
--status-standby: #2563eb; /* 待機庫存 - 藍 */
--status-repair: #f59e0b; /* 保養/維修 - 橘 */
}

* { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; }
body { background-color: #f1f5f9; margin: 0; padding: 20px; color: var(--text-main); }

.container { max-width: 1450px; margin: 0 auto; background: #ffffff; border-radius: 8px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); padding: 24px; }
/* 標題與頂部工具列 */
.header-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 2px solid var(--border-color); padding-bottom: 12px; }
.main-title { font-size: 1.5rem; font-weight: bold; color: #0f172a; margin: 0; }

/* 快速篩選區 */
.filter-section { margin-bottom: 20px; background: #f8fafc; padding: 16px; border-radius: 8px; border: 1px solid var(--border-color); }
.filter-label { font-size: 0.85rem; font-weight: bold; color: var(--text-sub); margin-bottom: 8px; }
.filter-group { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.filter-tag {
background-color: #ffffff; border: 1px solid #cbd5e1; border-radius: 6px;
padding: 6px 16px; font-size: 0.85rem; cursor: pointer; font-weight: 500; transition: all 0.2s;
}
.filter-tag.active { background-color: #3b82f6; color: white; border-color: #2563eb; }

/* 搜尋列 */
.search-row { display: flex; gap: 10px; margin-bottom: 20px; }
.search-input { flex: 1; padding: 10px 14px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.9rem; }
.btn-search { background-color: #2563eb; color: white; padding: 0 20px; border-radius: 6px; font-weight: bold; border: none; cursor: pointer; }
.btn-clear { background-color: #64748b; color: white; padding: 0 20px; border-radius: 6px; font-weight: bold; border: none; cursor: pointer; }

/* 表格樣式 */
.table-responsive { width: 100%; overflow-x: auto; border: 1px solid var(--border-color); border-radius: 8px; background: white; }
table { width: 100%; border-collapse: collapse; text-align: left; font-size: 0.9rem; }
th { background-color: #f8fafc; color: var(--text-sub); padding: 14px 16px; font-weight: 600; border-bottom: 2px solid var(--border-color); }
td { padding: 14px 16px; border-bottom: 1px solid var(--border-color); vertical-align: middle; }
tr:hover { background-color: #f8fafc; }

/* 狀態 Badge */
.status-badge { display: inline-block; padding: 4px 12px; border-radius: 4px; color: white; font-size: 0.8rem; font-weight: bold; text-align: center; }
.status-running { background-color: var(--status-running); }
.status-standby { background-color: var(--status-standby); }
.status-repair { background-color: var(--status-repair); }

/* 設備標籤樣式 */
.device-badge { background-color: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; padding: 4px 8px; border-radius: 6px; font-size: 0.8rem; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; }
.mold-na { color: #94a3b8; font-style: italic; }

/* 操作按鈕 */
.btn-action {
border: none; border-radius: 4px; padding: 6px 12px; font-size: 0.85rem; font-weight: 500;
cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: background 0.2s;
}
.btn-change { background-color: var(--btn-blue); color: white; }
.btn-change:hover { background-color: #1d4ed8; }
/* 規則排列 */
.rule-container { display: flex; flex-direction: column; gap: 4px; }
.rule-item { font-size: 0.85rem; color: #334155; font-weight: 500; background: #f1f5f9; padding: 2px 8px; border-radius: 4px; display: inline-block; width: max-content; }
.rule-na { color: #94a3b8; font-style: italic; }

/* 彈出視窗 (Modal) */
.modal-overlay {
display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(15, 23, 42, 0.6); z-index: 1000; justify-content: center; align-items: center; padding: 20px;
}
.modal-overlay.open { display: flex; }
.modal-card { background: white; width: 100%; max-width: 850px; border-radius: 8px; overflow: hidden; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); animation: slideUp 0.2s ease-out; }
@keyframes slideUp { from { transform: translateY(15px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

.modal-header { padding: 18px 24px; border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: center; }
.modal-title { font-size: 1.25rem; font-weight: bold; color: var(--text-main); }
.modal-body { padding: 24px; max-height: 75vh; overflow-y: auto; }
.form-row { margin-bottom: 18px; }
.form-label { display: block; font-size: 0.9rem; font-weight: bold; margin-bottom: 8px; }
.form-label span { color: #ef4444; margin-right: 4px; }
.form-select, .form-textarea { width: 100%; border: 1px solid #cbd5e1; border-radius: 6px; padding: 10px 12px; font-size: 0.9rem; outline: none; background-color: #fff; }
/* 歷史紀錄表格 */
.modal-table-title { font-size: 0.95rem; font-weight: bold; margin: 24px 0 10px 0; }
.modal-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.modal-table th { padding: 10px; background-color: #f8fafc; border-bottom: 1px solid var(--border-color); }
.modal-table td { padding: 10px; border-bottom: 1px solid var(--border-color); }

.modal-footer { padding: 16px 24px; border-top: 1px solid var(--border-color); display: flex; justify-content: flex-end; gap: 12px; background: #f8fafc; }
.footer-btn-confirm { background-color: var(--btn-green); color: white; padding: 8px 18px; font-weight: bold; border: none; border-radius: 4px; cursor: pointer; }
.footer-btn-cancel { background-color: white; border: 1px solid #cbd5e1; color: var(--text-sub); padding: 8px 18px; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>

<div class="container">
<div class="header-row">
<div class="main-title">模具管理</div>
</div>

<div class="filter-section">
<div class="filter-label">按模具類別快速篩選:</div>
<div class="filter-group" id="type-filters">
<div class="filter-tag active" onclick="filterType('ALL', this)">全部</div>
<div class="filter-tag" onclick="filterType('光學模具', this)">光學模具</div>
<div class="filter-tag" onclick="filterType('射出模具', this)">射出模具</div>
<div class="filter-tag" onclick="filterType('沖壓模具', this)">沖壓模具</div>
</div>

<div class="search-row">
<input type="text" class="search-input" id="moldSearchInput" placeholder="搜尋模具編號...">
<button class="btn-search" onclick="searchMolds()">搜尋</button>
<button class="btn-clear" onclick="clearSearch()">清空</button>
</div>
</div>

<div class="table-responsive">
<table>
<thead>
<tr>
<th>模具編號</th>
<th>模具名稱</th>
<th>模具類型</th>
<th>綁定設備</th>
<th>線別</th>
<th>所屬廠區</th>
<th>狀態</th>
<th>狀態變更維護 (可轉移規則)</th>
<th>操作</th>
</tr>
</thead>
<tbody id="mold-table-body">
<tr id="row-MOLD-2026-A1" data-type="光學模具">
<td><b>MOLD-2026-A1</b></td>
<td>隱形眼鏡前弧成型模 A型</td>
<td>光學模具</td>
<td><span class="device-badge"><i class="fas fa-desktop"></i> HL-M-17</span></td>
<td>手動線</td>
<td>第二廠區</td>
<td><span class="status-badge status-running">生產中</span></td>
<td>
<div class="rule-container">
<div class="rule-item">生產中 ➔ 保養中</div>
</div>
</td>
<td>
<button class="btn-action btn-change" onclick="openStatusModal('MOLD-2026-A1', '隱形眼鏡前弧成型模 A型', '生產中')">
<i class="fas fa-exchange-alt"></i> 變更狀態
</button>
</td>
</tr>
<tr id="row-MOLD-2026-B3" data-type="光學模具">
<td><b>MOLD-2026-B3</b></td>
<td>隱形眼鏡後弧成型模 B型</td>
<td>光學模具</td>
<td><span class="device-badge"><i class="fas fa-desktop"></i> HL-M-18</span></td>
<td>自動線</td>
<td>第二廠區</td>
<td><span class="status-badge status-running">生產中</span></td>
<td><span class="rule-na">N/A</span></td>
<td>
<button class="btn-action btn-change" onclick="openStatusModal('MOLD-2026-B3', '隱形眼鏡後弧成型模 B型', '生產中')">
<i class="fas fa-exchange-alt"></i> 變更狀態
</button>
</td>
</tr>
<tr id="row-MOLD-PL-V2" data-type="射出模具">
<td><b>MOLD-PL-V2</b></td>
<td>PIM 載台特製模組</td>
<td>射出模具</td>
<td><span class="device-badge"><i class="fas fa-desktop"></i> HL-M-27</span></td>
<td>自動線</td>
<td>第三廠區</td>
<td><span class="status-badge status-running">生產中</span></td>
<td>
<div class="rule-container">
<div class="rule-item">生產中 ➔ 保養中</div>
<div class="rule-item">生產中 ➔ 維修中</div>
</div>
</td>
<td>
<button class="btn-action btn-change" onclick="openStatusModal('MOLD-PL-V2', 'PIM 載台特製模組', '生產中')">
<i class="fas fa-exchange-alt"></i> 變更狀態
</button>
</td>
</tr>
<tr id="row-MOLD-ST-99" data-type="沖壓模具">
<td><b>MOLD-ST-99</b></td>
<td>外殼固定鋼片沖壓模</td>
<td>沖壓模具</td>
<td><span class="mold-na">N/A (在庫房)</span></td>
<td>手動線</td>
<td>第一廠區庫房</td>
<td><span class="status-badge status-standby">待機庫存</span></td>
<td>
<div class="rule-container">
<div class="rule-item">待機庫存 ➔ 保養中</div>
</div>
</td>
<td>
<button class="btn-action btn-change" onclick="openStatusModal('MOLD-ST-99', '外殼固定鋼片沖壓模', '待機庫存')">
<i class="fas fa-exchange-alt"></i> 變更狀態
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>

<div id="statusModal" class="modal-overlay">
<div class="modal-card">
<div class="modal-header">
<div class="modal-title" id="modalTitle">模具狀態變更:</div>
<i class="fas fa-times" style="cursor: pointer; color: var(--text-sub);" onclick="closeModal()"></i>
</div>
<div class="modal-body">
<div class="form-row">
<label class="form-label">當前狀態:</label>
<span id="currentStatusBadge" class="status-badge">生產中</span>
</div>
<div class="form-row">
<label class="form-label"><span>*</span>目標狀態:</label>
<select class="form-select" id="targetStatusSelect">
<option value="" disabled selected>請選擇切換目標狀態</option>
</select>
</div>

<div class="form-row">
<label class="form-label"><span>*</span>保養維護原因 / 下線紀錄:</label>
<textarea class="form-textarea" id="changeReasonInput" rows="3" placeholder="請說明狀態變更的原因(例:定期洗模保養、生產結束下線、模面刮傷修模等)"></textarea>
</div>

<div class="modal-table-title">最近變更與維護紀錄:</div>
<table class="modal-table">
<thead>
<tr>
<th>狀態</th>
<th>原因/備註</th>
<th>變更時間</th>
<th>變更人員</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="status-badge status-running">生產中</span></td>
<td>上線生產分配 (設備: HL-M-17)</td>
<td>2026-07-16 08:00:00</td>
<td>張阿明</td>
</tr>
<tr>
<td><span class="status-badge status-repair">保養中</span></td>
<td>定期超音波清洗與化學藥水浸泡保養完成</td>
<td>2026-07-15 17:30:00</td>
<td>陳小華</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button class="footer-btn-confirm" onclick="submitStatusChange()">確認</button>
<button class="footer-btn-cancel" onclick="closeModal()">取消</button>
</div>
</div>
</div>

<script>
let activeMoldId = '';

function openStatusModal(moldId, moldName, currentStatus) {
activeMoldId = moldId;
document.getElementById('modalTitle').innerText = `模具狀態變更:${moldName}`;
const badge = document.getElementById('currentStatusBadge');
badge.innerText = currentStatus;
badge.className = 'status-badge ' + (currentStatus === '生產中' ? 'status-running' : 'status-standby');

const targetRow = document.getElementById(`row-${moldId}`);
const ruleItems = targetRow.querySelectorAll('.rule-item');
const selectEl = document.getElementById('targetStatusSelect');
selectEl.innerHTML = '<option value="" disabled selected>請選擇切換目標狀態</option>';

if (ruleItems.length > 0) {
ruleItems.forEach(item => {
const text = item.innerText;
const parts = text.split('');
if (parts.length === 2) {
const fromStatus = parts[0].trim();
const toStatus = parts[1].trim();
const opt = document.createElement('option');
opt.value = toStatus;
opt.innerText = `${toStatus} (依規則:${fromStatus}${toStatus})`;
selectEl.appendChild(opt);
}
});
} else {
const defaultStatuses = ['生產中', '待機庫存', '保養中', '維修中'];
defaultStatuses.forEach(s => {
if (s !== currentStatus) {
const opt = document.createElement('option');
opt.value = s;
opt.innerText = s;
selectEl.appendChild(opt);
}
});
}

document.getElementById('changeReasonInput').value = '';
document.getElementById('statusModal').classList.add('open');
}

function closeModal() { document.getElementById('statusModal').classList.remove('open'); }

function submitStatusChange() {
const targetStatus = document.getElementById('targetStatusSelect').value;
const reason = document.getElementById('changeReasonInput').value.trim();

if (!targetStatus || !reason) { alert('請填寫所有必要欄位!'); return; }

const targetRow = document.getElementById(`row-${activeMoldId}`);
if (targetRow) {
// 狀態目前位於第 7 欄
const statusCell = targetRow.querySelector('td:nth-child(7)');
let badgeClass = 'status-running';
if (targetStatus === '待機庫存') badgeClass = 'status-standby';
if (targetStatus === '保養中' || targetStatus === '維修中') badgeClass = 'status-repair';
statusCell.innerHTML = `<span class="status-badge ${badgeClass}">${targetStatus}</span>`;
const actionBtn = targetRow.querySelector('.btn-change');
actionBtn.setAttribute('onclick', `openStatusModal('${activeMoldId}', '${targetRow.querySelector('td:nth-child(2)').innerText}', '${targetStatus}')`);
}

alert('模具變更確認成功!');
closeModal();
}

function filterType(type, el) {
el.parentElement.querySelectorAll('.filter-tag').forEach(t => t.classList.remove('active'));
el.classList.add('active');
document.querySelectorAll('#mold-table-body tr').forEach(row => {
row.style.display = (type === 'ALL' || row.getAttribute('data-type') === type) ? 'table-row' : 'none';
});
}

function searchMolds() {
const query = document.getElementById('moldSearchInput').value.trim().toLowerCase();
document.querySelectorAll('#mold-table-body tr').forEach(row => {
const id = row.querySelector('td:first-child').innerText.toLowerCase();
row.style.display = id.includes(query) ? 'table-row' : 'none';
});
}

function clearSearch() {
document.getElementById('moldSearchInput').value = '';
document.querySelectorAll('#mold-table-body tr').forEach(row => {
row.style.display = 'table-row';
});
}
</script>

</body>
</html>
    (1-1/1)