{"id":712,"date":"2026-09-05T18:39:22","date_gmt":"2026-09-05T10:39:22","guid":{"rendered":"https:\/\/udreamart.com\/?page_id=712"},"modified":"2026-09-15T16:14:15","modified_gmt":"2026-09-15T08:14:15","slug":"work","status":"publish","type":"page","link":"https:\/\/udreamart.com\/index.php\/work\/","title":{"rendered":"work"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"712\" class=\"elementor elementor-712\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-72c3f02 e-flex e-con-boxed e-con e-parent\" data-id=\"72c3f02\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-740b915 elementor-widget elementor-widget-html\" data-id=\"740b915\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"zh-TW\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>\u8018\u5922\u6f14\u85dd\u5b78\u82d1 - \u6253\u5361\u7cfb\u7d71<\/title>\n<style>\n  body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; background: #eef2f5; margin: 0; padding: 20px; display: flex; justify-content: center; }\n  .card { background: #fff; width: 100%; max-width: 400px; border-radius: 16px; padding: 25px; box-shadow: 0 8px 20px rgba(0,0,0,0.08); }\n  h2 { text-align: center; color: #1c1c1e; margin: 0 0 10px 0; font-size: 20px; }\n  .status-bar { text-align: center; font-size: 12px; color: #ff9500; font-weight: bold; margin-bottom: 15px; }\n  .form-group { margin-bottom: 15px; }\n  label { display: block; font-size: 13px; font-weight: 600; color: #48484a; margin-bottom: 6px; }\n  select, input { width: 100%; padding: 12px; border: 1px solid #d1d1d6; border-radius: 10px; font-size: 15px; box-sizing: border-box; outline: none; }\n  .time-flex { display: flex; gap: 10px; }\n  .btn { width: 100%; padding: 14px; background: #007aff; color: white; border: none; border-radius: 10px; font-size: 16px; font-weight: bold; cursor: pointer; margin-top: 10px; }\n  .btn:disabled { background: #a2a2a7; cursor: not-allowed; }\n  .hidden { display: none; }\n  .user-bar { display: flex; justify-content: space-between; align-items: center; background: #e5f1ff; padding: 10px 15px; border-radius: 8px; margin-bottom: 15px; }\n  .log-msg { margin-top: 15px; padding: 12px; border-radius: 8px; font-size: 13px; text-align: center; background: #f2f2f7; }\n<\/style>\n<\/head>\n<body>\n\n<div class=\"card\">\n  <h2>\ud83c\udfad \u8018\u5922\u6f14\u85dd\u5b78\u82d1 \u6253\u5361<\/h2>\n  <div id=\"sync-status\" class=\"status-bar\">\u23f3 \u6b63\u5728\u9023\u7dda\u5f8c\u53f0\u540c\u6b65\u8a2d\u5b9a...<\/div>\n\n  <!-- 1. \u767b\u5165\u5340\u584a -->\n  <div id=\"sec-login\">\n    <div class=\"form-group\">\n      <label>\u9078\u64c7\u54e1\u5de5\u59d3\u540d<\/label>\n      <select id=\"user-select\">\n        <option value=\"\">-- \u8acb\u9078\u64c7\u540d\u5b57 --<\/option>\n        <option value=\"\u7530\u5bb6\u6a3a\">\u7530\u5bb6\u6a3a<\/option>\n        <option value=\"\u9673\u5c1a\u7b60\">\u9673\u5c1a\u7b60<\/option>\n        <option value=\"\u5433\u8c9e\u7487\">\u5433\u8c9e\u7487<\/option>\n        <option value=\"\u6881\u744b\u5a77\">\u6881\u744b\u5a77<\/option>\n        <option value=\"\u59da\u76c8\u7af9\">\u59da\u76c8\u7af9<\/option>\n        <option value=\"\u4f55\u4fe1\u826f\">\u4f55\u4fe1\u826f<\/option>\n        <option value=\"\u502a\u610f\u5a77\">\u502a\u610f\u5a77<\/option>\n      <\/select>\n    <\/div>\n    <div class=\"form-group\">\n      <label>\u500b\u4eba\u9a57\u8b49 PIN \u78bc<\/label>\n      <input type=\"password\" id=\"pin-input\" maxlength=\"8\" placeholder=\"\u8acb\u8f38\u5165\u9a57\u8b49\u78bc\">\n    <\/div>\n    <button class=\"btn\" id=\"login-btn\" onclick=\"verifyLogin()\">\u9a57\u8b49\u767b\u5165<\/button>\n  <\/div>\n\n  <!-- 2. \u6253\u5361\u586b\u5beb\u5340\u584a -->\n  <div id=\"sec-clock\" class=\"hidden\">\n    <div class=\"user-bar\">\n      <span id=\"display-user\" style=\"font-weight: bold; color: #007aff;\"><\/span>\n      <a href=\"#\" onclick=\"logout()\" style=\"font-size: 12px; color: #8e8e93; text-decoration: none;\">[\u5207\u63db\u5e33\u865f]<\/a>\n    <\/div>\n\n    <div class=\"form-group\">\n      <label>\u6253\u5361\u65e5\u671f<\/label>\n      <input type=\"date\" id=\"clock-date\">\n    <\/div>\n\n    <div class=\"form-group\">\n      <label>\u4e0a\u8ab2\u6642\u6bb5 (\u8d77\u8a16\u6642\u9593)<\/label>\n      <div class=\"time-flex\">\n        <input type=\"time\" id=\"start-time\" value=\"14:00\" onchange=\"calcHours()\">\n        <input type=\"time\" id=\"end-time\" value=\"16:00\" onchange=\"calcHours()\">\n      <\/div>\n    <\/div>\n\n    <div class=\"form-group\">\n      <label>\u8a08\u7b97\u7e3d\u6642\u6578 (\u5c0f\u6642)<\/label>\n      <input type=\"number\" id=\"calc-hours\" value=\"2\" readonly style=\"background:#f2f2f7;\">\n    <\/div>\n\n    <!-- \u52d5\u614b\u8f09\u5165\u5f8c\u53f0\u300c\u85aa\u8cc7\u8a08\u7b97\u57fa\u6e96\u300d\u8ab2\u7a0b\u6e05\u55ae -->\n    <div class=\"form-group\">\n      <label>\u9078\u64c7\u8ab2\u7a0b\/\u5de5\u4f5c\u9805\u76ee<\/label>\n      <select id=\"task-select\" onchange=\"onTaskChange()\">\n        <option value=\"\">\u23f3 \u8f09\u5165\u8ab2\u7a0b\u4e2d...<\/option>\n      <\/select>\n    <\/div>\n\n    <!-- \u52d5\u614b\u5207\u63db\uff1a\u5b78\u54e1\u540d\u518a\u9078\u55ae \/ \u624b\u52d5\u586b\u5beb\u6b04\u4f4d -->\n    <div class=\"form-group\">\n      <label id=\"note-label\">\u5b78\u54e1\u59d3\u540d \/ \u5099\u8a3b<\/label>\n      <select id=\"student-select\" class=\"hidden\" onchange=\"onStudentSelectChange()\">\n        <option value=\"\">-- \u8acb\u9078\u64c7\u5b78\u54e1 --<\/option>\n      <\/select>\n      <input type=\"text\" id=\"clock-note\" placeholder=\"\u4f8b\uff1a5 \u4eba \u6216 \u5b78\u54e1\u59d3\u540d\">\n    <\/div>\n\n    <button class=\"btn\" id=\"sub-btn\" onclick=\"submitClock()\">\u9001\u51fa\u6253\u5361\u7d00\u9304<\/button>\n  <\/div>\n\n  <div id=\"log-msg\" class=\"log-msg\">\u8acb\u9078\u64c7\u59d3\u540d\u8207\u8f38\u5165\u9a57\u8b49\u78bc<\/div>\n<\/div>\n\n<script>\n  const API_URL = \"https:\/\/script.google.com\/macros\/s\/AKfycbz75VLwsoSLANHm1ON7GUsqfqR1f3e7pJSpggDczFWJ9unycMM10LLImQA41VNxUDiJ\/exec\";\n\n  let remotePins = {};\n  let remoteStudents = [];\n  let remoteCounts = {};\n  let remoteTasks = [];\n  let isDataLoaded = false;\n\n  \/\/ \u63a5\u6536\u5f8c\u53f0 JSONP \u56de\u50b3\u8cc7\u6599\n  function handleSyncData(data) {\n    if (data) {\n      remotePins = data.pins || {};\n      remoteStudents = data.students || [];\n      remoteCounts = data.counts || {};\n      remoteTasks = data.tasks || [];\n      isDataLoaded = true;\n\n      const statusEl = document.getElementById('sync-status');\n      if (statusEl) {\n        statusEl.innerText = \"\ud83d\udfe2 \u5f8c\u53f0\u8a2d\u5b9a\u3001\u5b78\u54e1\u540d\u518a\u8207\u8ab2\u7a0b\u52d5\u614b\u9023\u7dda\u5b8c\u6210\";\n        statusEl.style.color = \"#34c759\";\n      }\n      \n      \/\/ \u6e32\u67d3\u52d5\u614b\u8ab2\u7a0b\u9078\u55ae\u8207\u5b78\u54e1\u9078\u55ae\n      renderTaskDropdown();\n      renderStudentDropdown();\n    }\n  }\n\n  window.onload = function() {\n    document.getElementById('clock-date').valueAsDate = new Date();\n    \n    \/\/ \u900f\u904e JSONP \u6293\u53d6\u5f8c\u53f0\u8cc7\u6599\n    const script = document.createElement('script');\n    script.src = API_URL + \"?callback=handleSyncData\";\n    document.body.appendChild(script);\n  };\n\n  \/\/ \u6e32\u67d3\u8ab2\u7a0b\u4e0b\u62c9\u9078\u55ae\uff08\u81ea\u52d5\u5c0d\u7167\u300c\u85aa\u8cc7\u8a08\u7b97\u57fa\u6e96\u300d\u8a66\u7b97\u8868\uff09\n  function renderTaskDropdown() {\n    const taskSelect = document.getElementById('task-select');\n    taskSelect.innerHTML = '';\n\n    if (remoteTasks.length === 0) {\n      taskSelect.innerHTML = '<option value=\"\u4e00\u5c0d\u4e00\u9418\u9ede\">\u4e00\u5c0d\u4e00\u9418\u9ede<\/option><option value=\"\u884c\u653f\u4e8b\u9805\">\u884c\u653f\u4e8b\u9805<\/option>';\n      return;\n    }\n\n    remoteTasks.forEach(task => {\n      const opt = document.createElement('option');\n      opt.value = task;\n      opt.innerText = task;\n      taskSelect.appendChild(opt);\n    });\n\n    onTaskChange(); \/\/ \u521d\u59cb\u5316\u9023\u52d5\u89f8\u767c\n  }\n\n  \/\/ \u6e32\u67d3\u5b78\u54e1\u4e0b\u62c9\u9078\u55ae\u9078\u9805\n  function renderStudentDropdown() {\n    const studentSelect = document.getElementById('student-select');\n    studentSelect.innerHTML = '<option value=\"\">-- \u8acb\u9078\u64c7\u5b78\u54e1 --<\/option>';\n    \n    remoteStudents.forEach(student => {\n      const opt = document.createElement('option');\n      opt.value = student;\n      opt.innerText = student;\n      studentSelect.appendChild(opt);\n    });\n    \n    const customOpt = document.createElement('option');\n    customOpt.value = \"CUSTOM\";\n    customOpt.innerText = \"\u2795 \u5176\u4ed6\/\u624b\u52d5\u8f38\u5165\";\n    studentSelect.appendChild(customOpt);\n  }\n\n  function verifyLogin() {\n    if (!isDataLoaded) {\n      return alert(\"\u7cfb\u7d71\u6b63\u5728\u9023\u7dda\u5f8c\u53f0\uff0c\u8acb\u7a0d\u5019 2 \u79d2\u518d\u8a66\uff01\");\n    }\n\n    const user = document.getElementById('user-select').value;\n    const inputPin = document.getElementById('pin-input').value.trim();\n\n    if (!user) return alert(\"\u8acb\u9078\u64c7\u54e1\u5de5\u59d3\u540d\uff01\");\n    if (!inputPin) return alert(\"\u8acb\u8f38\u5165\u9a57\u8b49\u78bc\uff01\");\n\n    const correctPin = String(remotePins[user] || \"\").trim();\n    const finalPin = correctPin === \"\" ? \"0000\" : correctPin;\n\n    if (String(inputPin) !== finalPin) {\n      return alert(\"\u9a57\u8b49\u78bc\u932f\u8aa4\uff0c\u8acb\u91cd\u65b0\u8f38\u5165\uff01\");\n    }\n\n    document.getElementById('display-user').innerText = \"\ud83d\udc64 \" + user + \" \u8001\u5e2b\";\n    document.getElementById('sec-login').classList.add('hidden');\n    document.getElementById('sec-clock').classList.remove('hidden');\n    document.getElementById('log-msg').innerText = \"\u8acb\u78ba\u8a8d\u6642\u9593\u8207\u8ab2\u7a0b\u5f8c\u9ede\u64ca\u9001\u51fa\";\n    onTaskChange();\n  }\n\n  function logout() {\n    document.getElementById('sec-login').classList.remove('hidden');\n    document.getElementById('sec-clock').classList.add('hidden');\n    document.getElementById('pin-input').value = \"\";\n    document.getElementById('log-msg').innerText = \"\u8acb\u9078\u64c7\u59d3\u540d\u8207\u8f38\u5165\u9a57\u8b49\u78bc\";\n  }\n\n  function calcHours() {\n    const start = document.getElementById('start-time').value;\n    const end = document.getElementById('end-time').value;\n    if (start && end) {\n      const s = parseInt(start.split(':')[0]) + parseInt(start.split(':')[1])\/60;\n      const e = parseInt(end.split(':')[0]) + parseInt(end.split(':')[1])\/60;\n      const diff = e - s;\n      document.getElementById('calc-hours').value = diff > 0 ? diff : 0;\n    }\n  }\n\n  function onTaskChange() {\n    const task = document.getElementById('task-select').value;\n    const studentSelect = document.getElementById('student-select');\n    const noteInput = document.getElementById('clock-note');\n    const noteLabel = document.getElementById('note-label');\n\n    const singleStudentTasks = [\"\u4e00\u5c0d\u4e00\u9418\u9ede\", \"\u5957\u88dd\u8a3a\u65b7\u8ab2\"];\n\n    if (singleStudentTasks.includes(task)) {\n      noteLabel.innerText = \"\u9078\u64c7\u4e00\u5c0d\u4e00\u5b78\u54e1\";\n      studentSelect.classList.remove('hidden');\n      noteInput.classList.add('hidden');\n      noteInput.value = studentSelect.value !== \"CUSTOM\" ? studentSelect.value : \"\";\n    } else {\n      noteLabel.innerText = \"\u4e0a\u8ab2\u4eba\u6578 \/ \u5099\u8a3b\";\n      studentSelect.classList.add('hidden');\n      noteInput.classList.remove('hidden');\n      \n      if (remoteCounts[task] !== undefined) {\n        noteInput.value = remoteCounts[task] + \" \u4eba\";\n      } else {\n        noteInput.value = \"\";\n      }\n    }\n  }\n\n  function onStudentSelectChange() {\n    const studentSelect = document.getElementById('student-select');\n    const noteInput = document.getElementById('clock-note');\n\n    if (studentSelect.value === \"CUSTOM\") {\n      noteInput.classList.remove('hidden');\n      noteInput.value = \"\";\n      noteInput.placeholder = \"\u8acb\u624b\u52d5\u8f38\u5165\u5b78\u54e1\u59d3\u540d\";\n      noteInput.focus();\n    } else {\n      noteInput.classList.add('hidden');\n      noteInput.value = studentSelect.value;\n    }\n  }\n\n  function submitClock(isConfirmed = false) {\n    const task = document.getElementById('task-select').value;\n    const studentSelect = document.getElementById('student-select');\n    let finalNote = document.getElementById('clock-note').value;\n\n    const singleStudentTasks = [\"\u4e00\u5c0d\u4e00\u9418\u9ede\", \"\u5957\u88dd\u8a3a\u65b7\u8ab2\"];\n    if (singleStudentTasks.includes(task) && studentSelect.value !== \"CUSTOM\") {\n      finalNote = studentSelect.value;\n    }\n\n    if (!finalNote) {\n      return alert(\"\u8acb\u9078\u64c7\u6216\u8f38\u5165\u5b78\u54e1\u59d3\u540d\/\u4eba\u6578\uff01\");\n    }\n\n    const payload = {\n      user: document.getElementById('user-select').value,\n      date: document.getElementById('clock-date').value,\n      startTime: document.getElementById('start-time').value,\n      endTime: document.getElementById('end-time').value,\n      hours: document.getElementById('calc-hours').value,\n      task: task,\n      note: finalNote,\n      confirmedConflict: isConfirmed\n    };\n\n    const btn = document.getElementById('sub-btn');\n    const msg = document.getElementById('log-msg');\n    btn.disabled = true;\n    msg.innerHTML = \"<span style='color:#007aff;'>\u23f3 \u6253\u5361\u50b3\u9001\u4e2d\uff0c\u8acb\u7a0d\u5019...<\/span>\";\n\n    fetch(API_URL, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"text\/plain;charset=utf-8\" },\n      body: JSON.stringify(payload)\n    })\n    .then(res => res.json())\n    .then(data => {\n      btn.disabled = false;\n      \n      if (data.status === \"warning\" && data.hasConflict) {\n        if (confirm(data.message)) {\n          submitClock(true);\n        } else {\n          msg.innerHTML = \"<span style='color:#ff3b30;'>\u5df2\u53d6\u6d88\u672c\u6b21\u6253\u5361\u3002<\/span>\";\n        }\n      } else if (data.status === \"success\") {\n        msg.innerHTML = \"<b style='color:#34c759;'>\ud83c\udf89 \u6253\u5361\u6210\u529f\uff01\u8cc7\u6599\u5df2\u5beb\u5165\u8a66\u7b97\u8868\u3002<\/b>\";\n      } else {\n        alert(\"\u6253\u5361\u56de\u61c9\u7570\u5e38\uff1a\" + (data.message || \"\u672a\u77e5\u932f\u8aa4\"));\n        msg.innerHTML = \"<span style='color:#ff3b30;'>\u6253\u5361\u5931\u6557\uff0c\u8acb\u91cd\u8a66\u3002<\/span>\";\n      }\n    })\n    .catch(err => {\n      btn.disabled = false;\n      msg.innerHTML = \"<b style='color:#34c759;'>\ud83c\udf89 \u6253\u5361\u8acb\u6c42\u5df2\u9001\u51fa\uff0c\u8acb\u81f3\u8a66\u7b97\u8868\u78ba\u8a8d\uff01<\/b>\";\n    });\n  }\n<\/script>\n<\/body>\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u8018\u5922\u6f14\u85dd\u5b78\u82d1 &#8211; \u6253\u5361\u7cfb\u7d71 \ud83c\udfad \u8018\u5922\u6f14\u85dd\u5b78\u82d1 \u6253\u5361 \u23f3 \u6b63\u5728\u9023\u7dda\u5f8c\u53f0\u540c\u6b65\u8a2d\u5b9a&#8230; \u9078\u64c7\u54e1 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/udreamart.com\/index.php\/work\/\" class=\"more-link\">\u95b1\u8b80\u5168\u6587<span class=\"screen-reader-text\">\u3008work\u3009<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-712","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/pages\/712","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/comments?post=712"}],"version-history":[{"count":38,"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/pages\/712\/revisions"}],"predecessor-version":[{"id":752,"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/pages\/712\/revisions\/752"}],"wp:attachment":[{"href":"https:\/\/udreamart.com\/index.php\/wp-json\/wp\/v2\/media?parent=712"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}