21909-2004 ไมโครคอนโทรลเลอร์

ตรวจสอบการส่งงาน LAB ไมโครคอนโทรลเลอร์

iOS Glassmorphism Interface • วิเคราะห์ข้อมูลแบบส่วนบุคคล

เลือกชิ้นงาน LAB -- กำลังโหลดข้อมูล LAB --
เลือกระดับชั้น / ห้องเรียน -- กำลังโหลดข้อมูลห้องเรียน --
Export คะแนนเป็น Excel (.csv)

กรุณาเลือกงาน LAB และห้องเรียนเพื่อเปิดใช้งาน Dashboard และตารางข้อมูล

กำลังวิเคราะห์โครงสร้างชิ้นงานค้างส่ง...

เปอร์เซ็นต์การส่งงาน
0%
0/0 คน
ส่งเร็ว (30% แรก)
ปานกลาง (20% ถัดมา)
ส่งช้า (กลุ่มที่เหลือ)
ยังไม่ได้ส่ง
รหัส ชื่อ สกุล (คลิกดู Dashboard) สถานะ ไฟล์งาน ลิงค์ไฟล์ รายละเอียด เวลาการส่งงาน ลำดับ คะแนน
'; if(!counts.medium) medEl.innerHTML = '
ไม่มีรายชื่อ
'; if(!counts.slow) slowEl.innerHTML = '
ไม่มีรายชื่อ
'; if(!counts.none) noneEl.innerHTML = '
ส่งครบเรียบร้อย 🎉
'; } function renderTableRows(list) { tableBody.innerHTML = ''; list.forEach(s => { const tr = document.createElement('tr'); // ชื่อ (แบบคลิกได้เป็น iOS Link Dashboard Popup) const tdName = document.createElement('td'); const cleanStrName = encodeURIComponent(s.name); tdName.innerHTML = ` ${s.name}`; tr.appendChild(tdName); // สถานะ const tdStatus = document.createElement('td'); tdStatus.style.textAlign = 'center'; tdStatus.innerHTML = s.hasSubmitted ? '' : ''; tr.appendChild(tdStatus); // ไฟล์อัพโหลด const tdFile = document.createElement('td'); tdFile.style.textAlign = 'center'; tdFile.innerHTML = (s.hasSubmitted && s.fileUpload.startsWith('http')) ? `` : ``; tr.appendChild(tdFile); // ลิงก์ const tdLink = document.createElement('td'); tdLink.style.textAlign = 'center'; tdLink.innerHTML = (s.hasSubmitted && s.fileLink.startsWith('http')) ? `` : ``; tr.appendChild(tdLink); // บันทึก const tdDetails = document.createElement('td'); tdDetails.style.textAlign = 'center'; if (s.hasSubmitted && s.details) { const encodedTxt = encodeURIComponent(s.details); tdDetails.innerHTML = ` ดู`; } else { tdDetails.innerHTML = ``; } tr.appendChild(tdDetails); // เวลา const tdTime = document.createElement('td'); tdTime.textContent = s.hasSubmitted ? s.timestamp : '-'; tr.appendChild(tdTime); // ลำดับส่ง const tdRank = document.createElement('td'); tdRank.style.textAlign = 'center'; tdRank.style.fontWeight = '600'; tdRank.textContent = s.classRank; if(s.hasSubmitted) { if(s.group === 'fast') tdRank.style.color = 'var(--ios-green)'; if(s.group === 'medium') tdRank.style.color = 'var(--ios-orange)'; if(s.group === 'slow') tdRank.style.color = 'var(--ios-red)'; } tr.appendChild(tdRank); // คะแนน const tdScore = document.createElement('td'); tdScore.style.textAlign = 'center'; let cls = 'p0'; if(s.score===10) cls='p10'; else if(s.score===8) cls='p8'; else if(s.score===6) cls='p6'; tdScore.innerHTML = `${s.score} คะแนน`; tr.appendChild(tdScore); tableBody.appendChild(tr); }); } // ฟังชันเด้งดึ๋ง Dashboard Popup ของแต่ละรายชื่อบุคคล function openStudentDashboard(encodedName) { const name = decodeURIComponent(encodedName); const cleanName = name.replace(/\s+/g, ''); // 1. ตรวจสอบชิ้นงานแล็บทั้งหมดในระบบที่มีการส่งงานเกิดขึ้น const totalLabsAvailable = allUniqueLabs.length; // 2. คำนวณชิ้นงานที่ส่งแล้ว ค้างส่ง และงานส่งซ้ำ let submittedLabs = new Set(); let duplicateMap = {}; rawSubmissions.forEach(sub => { if (sub.name.replace(/\s+/g, '') === cleanName) { submittedLabs.add(sub.lab); duplicateMap[sub.lab] = (duplicateMap[sub.lab] || 0) + 1; } }); const sendCount = submittedLabs.size; const pendingCount = Math.max(0, totalLabsAvailable - sendCount); // คัดกรองงานส่งซ้ำ (ส่งมากกว่า 1 ครั้งขึ้นไป) let duplicateItems = []; for (let labItem in duplicateMap) { if (duplicateMap[labItem] > 1) { duplicateItems.push({ labName: labItem, count: duplicateMap[labItem] }); } } // ประกอบ HTML โครงสร้าง iOS Component document.getElementById('modal-title').textContent = "Personal Summary Dashboard"; let html = `
${name}
รายงานผลรวมความคืบหน้าทุกวิชา LAB
${sendCount}
ส่งแล้ว (ชิ้น)
${pendingCount}
ค้างส่ง (ชิ้น)
${duplicateItems.length}
ส่งซ้ำ (รายการ)
  • `; if (duplicateItems.length === 0) { html += `
- ไม่พบประวัติการส่งงานซ้ำ -
`; } else { duplicateItems.forEach(item => { html += ` ${item.labName} (ส่งซ้ำเข้ามาทั้งหมด ${item.count} ครั้ง)`; }); } html += `

* ข้อมูลถูกดึงจากการจับคู่กับฐานข้อมูลส่งงานหลักล่าสุด

`; document.getElementById('modal-body-container').innerHTML = html; iosModal.style.display = 'flex'; } // ฟังก์ชันเปิดดูบันทึกรายละเอียดธรรมดา function openNotesPopup(encodedName, encodedTxt) { const name = decodeURIComponent(encodedName); const notes = decodeURIComponent(encodedTxt); document.getElementById('modal-title').textContent = "รายละเอียดข้อความแนบ"; document.getElementById('modal-body-container').innerHTML = `
บันทึกจาก: ${name}
${notes}
`; iosModal.style.display = 'flex'; } function closeModal() { iosModal.style.display = 'none'; } window.onclick = e => { if (e.target == iosModal) closeModal(); } // --- EXPORT TO EXCEL (.CSV) FUNCTION --- // --- EXPORT TO EXCEL (.CSV) FUNCTION (เวอร์ชันสรุปคะแนนทุก LAB รวมเป็นตารางเดียว) --- btnExport.addEventListener('click', () => { if (rawStudents.length === 0) return; const classTitle = selectClass.value || "ทุกห้องเรียน"; // 1. คัดกรองรายชื่อนักเรียนตามห้องที่เลือก (ถ้าไม่ได้เลือก ให้ดึงทุกห้อง) const targetStudents = selectClass.value ? rawStudents.filter(s => s.className === selectClass.value) : rawStudents; // 2. หาชื่อ LAB ทั้งหมดที่มีอยู่ในระบบเพื่อนำมาทำเป็นหัวคอลัมน์ (เหมือนในรูปตัวอย่าง) // allUniqueLabs ถูกเก็บค่าไว้ตอนโหลดหน้าเว็บแล้ว if (allUniqueLabs.length === 0) { alert("ไม่พบข้อมูลชิ้นงาน LAB ในระบบ"); return; } // 3. เริ่มต้นสร้างส่วนหัวตาราง (Header) let csvContent = "รหัส ชื่อ สกุล"; allUniqueLabs.forEach(lab => { csvContent += `,${lab}`; // เพิ่มคอลัมน์ LAB 1.1, LAB 1.2, ... ไปเรื่อยๆ }); csvContent += ",รวม\n"; // เพิ่มคอลัมน์สรุปคะแนนรวมท้ายตาราง // 4. ขั้นตอนการคำนวณคะแนนสัมพัทธ์ (Relative Scoring 10, 8, 6) ของทุกๆ LAB // สร้างแผนผังเก็บคะแนนแยกตามชิ้นงาน LAB เพื่อความรวดเร็วในการ lookup let labScoresLookup = {}; allUniqueLabs.forEach(targetLab => { const currentLabSubs = rawSubmissions.filter(sub => sub.lab === targetLab); let sortedSubmissions = [...currentLabSubs].sort((a,b) => new Date(a.timestamp) - new Date(b.timestamp)); // คัดกรองเฉพาะคนที่ส่งและจัดลำดับเพื่อคำนวณคะแนนกลุ่ม let submittedGroup = targetStudents.map(student => { const cleanName = student.name.replace(/\s+/g, ''); const matchRecords = currentLabSubs.filter(sub => sub.name.replace(/\s+/g, '') === cleanName); let globalRank = sortedSubmissions.findIndex(sub => sub.name.replace(/\s+/g, '') === cleanName) + 1; return { name: student.name, hasSubmitted: matchRecords.length > 0, globalRank: globalRank > 0 ? globalRank : null }; }).filter(s => s.hasSubmitted); // เรียงตามเวลาส่งจริงส่วนกลาง submittedGroup.sort((a, b) => a.globalRank - b.globalRank); const totalSub = submittedGroup.length; const limitFast = Math.ceil(totalSub * 0.3); const limitMedium = Math.ceil(totalSub * 0.5); submittedGroup.forEach((st, idx) => { const runningNo = idx + 1; if (runningNo <= limitFast) st.score = 10; else if (runningNo <= limitMedium) st.score = 8; else st.score = 6; }); // บันทึกลงตาราง Lookup Table [ชื่อนักเรียน][ชื่อLAB] = คะแนน targetStudents.forEach(student => { if (!labScoresLookup[student.name]) { labScoresLookup[student.name] = {}; } const match = submittedGroup.find(m => m.name === student.name); labScoresLookup[student.name][targetLab] = match ? match.score : 0; // ถ้าไม่ส่งงานให้เป็น 0 คะแนน }); }); // 5. นำข้อมูลจาก Lookup มาเขียนลงบรรทัดของนักเรียนแต่ละคน (Row Generation) targetStudents.forEach(student => { csvContent += `"${student.name}"`; // ใส่ฟันหนูครอบเพื่อป้องกันเครื่องหมายจุลภาคพังตาราง let totalStudentScore = 0; // วนลูปหยอดคะแนนเรียงตามคอลัมน์ LAB allUniqueLabs.forEach(lab => { const score = labScoresLookup[student.name][lab] || 0; csvContent += `,${score}`; totalStudentScore += score; // สะสมคะแนนรวม }); csvContent += `,${totalStudentScore}\n`; // หยอดคะแนนรวมปิดท้ายบรรทัด }); // 6. ใช้ Uint8Array บังคับให้ Microsoft Excel อ่านภาษาไทยออกโดยตรง const bom = new Uint8Array([0xEF, 0xBB, 0xBF]); const blob = new Blob([bom, csvContent], { type: 'text/csv;charset=utf-8;' }); // 7. สั่งดาวน์โหลดไฟล์สรุปผลรวม const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", `สรุปคะแนนทุกLAB_ห้อง_${classTitle}.csv`); document.body.appendChild(link); link.click(); document.body.removeChild(link); });
แชร์ LINE