Project

General

Profile

Feature #147 » 模具歷程查詢_0716.html

鎮源 游, 07/16/2026 03:50 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: #2563eb;
--primary-hover: #1d4ed8;
--success-green: #10b981;
--success-hover: #059669;
--orange-warning: #f59e0b;
--bg-gray: #f8fafc;
--border-color: #e2e8f0;
--text-dark: #1e293b;
--text-muted: #64748b;
--accent-bg: #eff6ff;
--danger-red: #ef4444;
}

* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

body {
background-color: var(--bg-gray);
color: var(--text-dark);
padding: 40px 20px;
}

.container {
max-width: 1300px;
margin: 0 auto;
}

.header {
margin-bottom: 24px;
border-bottom: 4px solid #dbeafe;
padding-bottom: 16px;
}

.header h1 {
font-size: 28px;
color: var(--text-dark);
display: flex;
align-items: center;
gap: 10px;
}

/* 篩選與搜尋面板 */
.filter-card {
background: white;
border-radius: 12px;
padding: 20px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
border: 1px solid var(--border-color);
margin-bottom: 24px;
}

.filter-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
margin-bottom: 16px;
}

.form-group {
display: flex;
flex-direction: column;
gap: 6px;
}

.form-group label {
font-size: 14px;
font-weight: 600;
color: var(--text-dark);
}

.form-control {
padding: 8px 12px;
border: 1px solid var(--border-color);
border-radius: 6px;
font-size: 14px;
outline: none;
transition: border-color 0.2s;
}

.form-control:focus {
border-color: var(--primary-blue);
}

.btn-group {
display: flex;
justify-content: flex-end;
gap: 12px;
}

.btn {
padding: 8px 16px;
border: none;
border-radius: 6px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 6px;
transition: background-color 0.2s;
}

.btn-primary {
background-color: var(--primary-blue);
color: white;
}

.btn-primary:hover {
background-color: var(--primary-hover);
}

.btn-success {
background-color: var(--success-green);
color: white;
}

.btn-success:hover {
background-color: var(--success-hover);
}

.btn-action {
padding: 4px 10px;
background-color: #f1f5f9;
border: 1px solid var(--border-color);
color: var(--primary-blue);
font-size: 12px;
font-weight: 600;
border-radius: 4px;
cursor: pointer;
transition: all 0.15s;
}

.btn-action:hover {
background-color: var(--primary-blue);
color: white;
border-color: var(--primary-blue);
}

/* 資料表格 */
.table-card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
border: 1px solid var(--border-color);
overflow: hidden;
}

table {
width: 100%;
border-collapse: collapse;
text-align: left;
font-size: 14px;
}

th {
background-color: #f1f5f9;
color: var(--text-dark);
font-weight: 600;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
}

td {
padding: 14px 16px;
border-bottom: 1px solid var(--border-color);
color: var(--text-dark);
}

tr:hover {
background-color: #f8fafc;
}

.badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: 700;
display: inline-block;
}

.badge-green { background-color: #dcfce7; color: #16a34a; border: 1px solid #bbf7d0; } /* 上機 */
.badge-blue { background-color: #dbeafe; color: #2563eb; border: 1px solid #bfdbfe; } /* 待機庫存 */
.badge-orange { background-color: #fef3c7; color: #d97706; border: 1px solid #fde68a; } /* 保養/維修中 */

.text-null {
color: #94a3b8;
font-style: italic;
}

/* 彈出視窗 Modal */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: none;
justify-content: center;
align-items: center;
z-index: 1000;
}

.modal-content {
background: white;
border-radius: 12px;
width: 90%;
max-width: 850px;
padding: 24px;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
max-height: 90vh;
overflow-y: auto;
}

.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
border-bottom: 2px solid var(--primary-blue);
padding-bottom: 12px;
}

.modal-title {
font-size: 20px;
font-weight: 700;
color: var(--text-dark);
}

.close-modal {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: var(--text-muted);
}

.modal-section-title {
font-size: 15px;
font-weight: 700;
color: #1e293b;
margin: 20px 0 10px 0;
padding-left: 8px;
border-left: 4px solid var(--primary-blue);
background-color: #f8fafc;
padding-top: 4px;
padding-bottom: 4px;
}

/* 上半部資訊網格排版 (2欄) */
.info-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
background: #fff;
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 16px;
}

.info-grid-full {
grid-column: span 2;
}

.info-item {
display: flex;
align-items: center;
font-size: 14px;
}

.info-label {
width: 110px;
font-weight: 600;
color: var(--text-muted);
}

.info-value {
flex: 1;
color: var(--text-dark);
}

/* 下半部表單項目的表格 */
.detail-table {
width: 100%;
border-collapse: collapse;
margin-top: 8px;
font-size: 13px;
}

.detail-table th {
background-color: #f1f5f9;
font-weight: 600;
padding: 10px 12px;
border: 1px solid var(--border-color);
}

.detail-table td {
padding: 10px 12px;
border: 1px solid var(--border-color);
}

.text-pass {
color: var(--success-green);
font-weight: bold;
}
.text-ng {
color: var(--danger-red);
font-weight: bold;
}

.form-meta-block {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 13px;
background: #f0f7ff;
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 8px;
border: 1px solid #d0e7ff;
}
</style>
</head>
<body>

<div class="container">
<div class="header">
<h1><i class="fas fa-history text-blue-600"></i> 模具歷程與狀態變更查詢</h1>
</div>

<div class="filter-card">
<div class="filter-grid">
<div class="form-group">
<label for="moldNo">模具編號/名稱</label>
<input type="text" id="moldNo" class="form-control" placeholder="輸入關鍵字搜尋...">
</div>
<div class="form-group">
<label for="moldType">模具類型</label>
<select id="moldType" class="form-control">
<option value="ALL">全部類型</option>
<option value="光學模具">光學模具</option>
<option value="射出模具">射出模具</option>
<option value="沖壓模具">沖壓模具</option>
</select>
</div>
<div class="form-group">
<label for="operator">操作人員</label>
<input type="text" id="operator" class="form-control" placeholder="輸入人員姓名...">
</div>
</div>
<div class="btn-group">
<button class="btn btn-primary" onclick="filterHistory()"><i class="fas fa-search"></i> 查詢</button>
<button class="btn btn-success" onclick="exportToCSV()"><i class="fas fa-file-excel"></i> 匯出 CSV</button>
</div>
</div>

<div class="table-card">
<table>
<thead>
<tr>
<th>異動時間</th>
<th>模具編號</th>
<th>模具名稱</th>
<th>模具類型</th>
<th>變更前狀態</th>
<th>變更後狀態</th>
<th>機台</th>
<th>操作人員</th>
<th style="text-align: center; width: 80px;">操作</th>
</tr>
</thead>
<tbody id="history-table-body">
</tbody>
</table>
</div>
</div>

<div class="modal-overlay" id="formModal">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title"><i class="far fa-list-alt text-blue-600"></i> 模具狀態變更詳細資訊</div>
<button class="close-modal" onclick="closeModal()">&times;</button>
</div>
<div class="modal-body">
<div class="modal-section-title">基本與狀態變更資訊</div>
<div class="info-grid">
<div class="info-item">
<div class="info-label">模具編號</div>
<div class="info-value" id="m-mold-no" style="font-weight: bold; color: var(--primary-blue);">-</div>
</div>
<div class="info-item">
<div class="info-label">模具名稱</div>
<div class="info-value" id="m-mold-name">-</div>
</div>
<div class="info-item">
<div class="info-label">線別</div>
<div class="info-value" id="m-line" style="font-weight: 500; color: #0f172a;">-</div>
</div>
<div class="info-item">
<div class="info-label">區域</div>
<div class="info-value" id="m-area" style="font-weight: 500; color: #0f172a;">-</div>
</div>
<div class="info-item">
<div class="info-label">變更前狀態</div>
<div class="info-value" id="m-status-before">-</div>
</div>
<div class="info-item">
<div class="info-label">變更後狀態</div>
<div class="info-value" id="m-status-after">-</div>
</div>
<div class="info-item">
<div class="info-label">操作人員</div>
<div class="info-value" id="m-user">-</div>
</div>
<div class="info-item">
</div>
<div class="info-item info-grid-full" style="align-items: flex-start;">
<div class="info-label">異動原因說明</div>
<div class="info-value" id="m-desc" style="background: #fffbeb; padding: 6px 10px; border-radius: 4px; border: 1px solid #fde68a; color: #b45309;">-</div>
</div>
</div>

<div class="modal-section-title">模具檢驗表單</div>
<div id="no-form-block" style="display: none; text-align: center; color: var(--text-muted); padding: 20px; border: 1px dashed var(--border-color); border-radius: 8px;">
<i class="fas fa-info-circle"></i> 此狀態切換點未設定/未觸發 any 模具檢驗表單。
</div>

<div id="has-form-block" style="display: block;">
<div class="form-meta-block">
<div><strong>表單名稱:</strong><span id="m-form-name" style="color:var(--primary-blue); font-weight: 600;">-</span></div>
<div><strong>檢驗人:</strong><span id="m-form-inspector">-</span></div>
</div>
<table class="detail-table">
<thead>
<tr>
<th style="width: 15%; text-align: center;">項目標號</th>
<th style="width: 35%;">項目名稱</th>
<th style="width: 15%; text-align: center;">單位</th>
<th style="width: 15%; text-align: center;">檢驗結果</th>
<th style="width: 20%; text-align: right;">檢驗值</th>
</tr>
</thead>
<tbody id="modal-detail-table-body">
</tbody>
</table>
</div>

</div>
</div>
</div>

<script>
// 模擬模具歷程數據池 (補齊對應的線別與區域數據以供彈窗讀取)
const mockHistoryData = [
{
time: '2026-07-16 11:15:00', no: 'MOLD-2026-B3', name: '隱形眼鏡後弧成型模 B型', type: '光學模具',
line: '自動線A', area: '光學射出區', fromStatus: '待機庫存', toStatus: '上機', machine: 'EQ-射出機-01', user: '張志明', desc: '工單開工,正常生產排程上機。',
form: '', inspector: '', details: []
},
{
time: '2026-07-16 10:15:22', no: 'MOLD-2026-A1', name: '隱形眼鏡前弧成型模 A型', type: '光學模具',
line: '手動精修線', area: '精密加工區', fromStatus: '上機', toStatus: '保養中', machine: '', user: '張志明', desc: '計畫性下線清洗與精密磨損量測。',
form: '日點檢-下線洗模檢驗紀錄表', inspector: '張志明',
details: [
{ code: 'ITM-001', name: '型腔/入子磨損厚度變形量', unit: 'mm', res: 'PASS', val: '0.002' },
{ code: 'ITM-002', name: '核心光學區表面粗糙度(Ra)', unit: 'µm', res: 'PASS', val: '0.015' },
{ code: 'ITM-003', name: '模具冷卻水路管道水壓阻力', unit: 'kg/cm²', res: 'PASS', val: '4.2' },
{ code: 'ITM-004', name: '射出嘴套焦黑積碳殘留數', unit: 'pcs', res: 'PASS', val: '0' }
]
},
{
time: '2026-07-16 09:45:10', no: 'MOLD-PL-V2', name: 'PIM 載台特製模組', type: '射出模具',
line: '自動線B', area: '標準射出區', fromStatus: '上機', toStatus: '維修中', machine: '', user: '陳大同', desc: '射出嘴套異常焦黑,緊急抽換新噴嘴套件。',
form: '模具維修段檢驗報告表', inspector: '王大維',
details: [
{ code: 'REP-01', name: '更換後嘴套鏡面平行度', unit: 'mm', res: 'PASS', val: '0.001' },
{ code: 'REP-02', name: '加熱圈電阻中心值阻抗', unit: 'Ω', res: 'PASS', val: '24.5' }
]
},
{
time: '2026-07-15 16:30:00', no: 'MOLD-ST-99', name: '外殼固定鋼片沖壓模', type: '沖壓模具',
line: '手動沖壓線', area: '重型沖壓區', fromStatus: '待機庫存', toStatus: '保養中', machine: '', user: '林小華', desc: '季度預防性超音波清洗與全面防鏽油噴塗。',
form: '定期維護保養點檢清單', inspector: '林小華',
details: [
{ code: 'PM-001', name: '超音波清洗槽槽液溫度', unit: '°C', res: 'PASS', val: '65.0' },
{ code: 'PM-002', name: '防鏽油層均勻塗佈厚度', unit: 'µm', res: 'PASS', val: '12.8' }
]
}
];

const tableBody = document.getElementById('history-table-body');
const modal = document.getElementById('formModal');

window.onload = function() {
renderTable(mockHistoryData);
};

function renderTable(data) {
tableBody.innerHTML = '';
if(data.length === 0) {
tableBody.innerHTML = `<tr><td colspan="9" style="text-align:center; color:var(--text-muted); font-style: italic;">查無對應的模具異動歷程資料。</td></tr>`;
return;
}

data.forEach((item, index) => {
const row = document.createElement('tr');
const fromBadgeClass = getBadgeColor(item.fromStatus);
const toBadgeClass = getBadgeColor(item.toStatus);

const machineDisplay = (item.toStatus === '上機' && item.machine)
? `<strong style="color:#2563eb;">${item.machine}</strong>`
: `<span class="text-null">NULL</span>`;

row.innerHTML = `
<td>${item.time}</td>
<td style="font-weight:bold;">${item.no}</td>
<td>${item.name}</td>
<td>${item.type}</td>
<td><span class="badge ${fromBadgeClass}">${item.fromStatus}</span></td>
<td><span class="badge ${toBadgeClass}">${item.toStatus}</span></td>
<td>${machineDisplay}</td>
<td>${item.user}</td>
<td style="text-align: center;">
<button class="btn-action" onclick="showDetail(${index})">詳細</button>
</td>
`;
tableBody.appendChild(row);
});
}

function getBadgeColor(status) {
if (status === '上機') return 'badge-green';
if (status === '待機庫存') return 'badge-blue';
return 'badge-orange';
}

function filterHistory() {
const keyword = document.getElementById('moldNo').value.trim().toLowerCase();
const selectedType = document.getElementById('moldType').value;
const operator = document.getElementById('operator').value.trim().toLowerCase();

const filtered = mockHistoryData.filter(item => {
const matchesKeyword = !keyword || item.no.toLowerCase().includes(keyword) || item.name.toLowerCase().includes(keyword);
const matchesType = selectedType === 'ALL' || item.type === selectedType;
const matchesOperator = !operator || item.user.toLowerCase().includes(operator);
return matchesKeyword && matchesType && matchesOperator;
});

renderTable(filtered);
}

function showDetail(index) {
const item = mockHistoryData[index];
// 1. 上半部資訊填充 (加入線別與區域)
document.getElementById('m-mold-no').innerText = item.no;
document.getElementById('m-mold-name').innerText = item.name;
document.getElementById('m-line').innerText = item.line || '未設定';
document.getElementById('m-area').innerText = item.area || '未設定';
document.getElementById('m-status-before').innerText = item.fromStatus;
document.getElementById('m-status-after').innerText = item.toStatus;
document.getElementById('m-user').innerText = item.user;
document.getElementById('m-desc').innerText = item.desc || '無特定異動原因說明。';
// 2. 下半部模具檢驗表單新型欄位處理
const noFormBlock = document.getElementById('no-form-block');
const hasFormBlock = document.getElementById('has-form-block');
const detailTbody = document.getElementById('modal-detail-table-body');
detailTbody.innerHTML = '';

if (item.form) {
noFormBlock.style.display = 'none';
hasFormBlock.style.display = 'block';
document.getElementById('m-form-name').innerText = item.form;
document.getElementById('m-form-inspector').innerText = item.inspector || item.user;
item.details.forEach(det => {
const tr = document.createElement('tr');
const resClass = (det.res === 'PASS') ? 'text-pass' : 'text-ng';
tr.innerHTML = `
<td style="text-align: center; font-family: monospace; color: #475569;">${det.code}</td>
<td style="font-weight: 500;">${det.name}</td>
<td style="text-align: center; color: #64748b;">${det.unit}</td>
<td class="text-center ${resClass}" style="text-align: center;">${det.res}</td>
<td style="text-align: right; font-weight: 600; color: #0f172a;">${det.val}</td>
`;
detailTbody.appendChild(tr);
});
} else {
noFormBlock.style.display = 'block';
hasFormBlock.style.display = 'none';
}
modal.style.display = 'flex';
}

function closeModal() {
modal.style.display = 'none';
}

window.onclick = function(event) {
if (event.target === modal) {
closeModal();
}
}

function exportToCSV() {
let csvContent = "\uFEFF";
csvContent += "異動時間,模具編號,模具名稱,模具類型,變更前狀態,變更後狀態,機台,操作人員,異動原因\n";
const keyword = document.getElementById('moldNo').value.trim().toLowerCase();
const selectedType = document.getElementById('moldType').value;
const operator = document.getElementById('operator').value.trim().toLowerCase();
let exportCount = 0;

mockHistoryData.forEach(item => {
const matchesKeyword = !keyword || item.no.toLowerCase().includes(keyword) || item.name.toLowerCase().includes(keyword);
const matchesType = selectedType === 'ALL' || item.type === selectedType;
const matchesOperator = !operator || item.user.toLowerCase().includes(operator);
if (matchesKeyword && matchesType && matchesOperator) {
const machineStr = (item.toStatus === '上機') ? item.machine : 'NULL';
csvContent += `"${item.time}","${item.no}","${item.name}","${item.type}","${item.fromStatus}","${item.toStatus}","${machineStr}","${item.user}","${item.desc}"\n`;
exportCount++;
}
});

if (exportCount === 0) {
alert("目前無符合條件的數據可供匯出。");
return;
}

const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement("a");
const url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", `模具歷程與檢驗表_${new Date().toISOString().slice(0,10)}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
</script>
</body>
</html>
    (1-1/1)