<!doctype html>
<html>
<head>
<meta name="chromevox" content-script="no">
<title>上傳數字表</title>
<meta name="viewport"content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" nonce="-aJ84cE0i2s2Myu8iWo1Ag"><link rel="stylesheet" href="/static/macros/client/css/2208734863-mae_html_css_ltr.css">
<script type="text/javascript" src="/static/macros/client/js/1504762570-warden_bin_i18n_warden__zh_tw.js"></script>
</head>
<body>
<table id="warning-bar-table" class="full_size" cellspacing="0" cellpadding="0"><tr><td><div id="warning" class="warning-bar"></div></td></tr><tr><td style="height: 100%"><iframe id="sandboxFrame" title="上傳數字表" allow="accelerometer *; autoplay *; clipboard-read *; clipboard-write *; encrypted-media *; fullscreen *; geolocation *; gyroscope *; local-network-access *; magnetometer *; midi *; payment *; picture-in-picture *; screen-wake-lock *; sync-xhr *; web-share *" sandbox="allow-downloads allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-top-navigation-by-user-activation allow-storage-access-by-user-activation">
</iframe>
</td></tr></table><script nonce="O0twzP2ymdks6nF2VFRYFA">
(function() {
var el = document.getElementById('sandboxFrame');
el.onload = function() {
goog.script.init("\x7b\x22functionNames\x22:\x5b\x22verifySheetStructure\x22,\x22resetRitualSheet\x22,\x22fixRitualHeader\x22,\x22fixAll\x22,\x22addMember\x22,\x22checkMemberStatus\x22,\x22isMemberNoDuplicate\x22,\x22generateUploadId\x22,\x22fixAllUploadIds\x22,\x22autoFillMemberNameForUpload\x22,\x22autoFillDate\x22,\x22autoFillMonth\x22,\x22recalcMemberStats\x22,\x22updateAllStats\x22,\x22refreshSummaryStats\x22,\x22debugSummarySheet\x22,\x22updateMemberStats\x22,\x22checkDeleteRow\x22,\x22setRitualTypeDropdown\x22,\x22updateRitualRemark\x22,\x22updateRitualRecord\x22,\x22generateRitualId\x22,\x22autoFillSendTime\x22,\x22autoFillMemberNameForRitual\x22,\x22getMemberListByGroup\x22,\x22getFullMemberListByGroup\x22,\x22getMemberUploadRecordsForLeader\x22,\x22updateMemberUploadRecord\x22,\x22getMemberInfoForLeaderUpload\x22,\x22getRemarksByGroup\x22,\x22markRemarkAsRead\x22,\x22getAllRemarks\x22,\x22isMemberRitualExists\x22,\x22getMemberRitualRecords\x22,\x22getRitualRecordById\x22,\x22onEdit\x22,\x22quickAddMember\x22,\x22saveQuickMember\x22,\x22chooseGroupStats\x22,\x22chooseGroupMonthStats\x22,\x22quickBackup\x22,\x22safeFixAll\x22,\x22safeRebuildAll\x22,\x22showAllGroupsReport\x22,\x22generateAllGroupsMainHTML\x22,\x22getAllGroupsReportData\x22,\x22getGroupStatsReport\x22,\x22maskNameForGS\x22,\x22generateAllGroupsTableHTML\x22,\x22debugMemberStructure\x22,\x22debugUploadSheet\x22,\x22showLeaderSummary\x22,\x22showGroupDetailReport\x22,\x22generateGroupDetailUploadHTML\x22,\x22getGroupDetailUploadData\x22,\x22generateGroupDetailTableHTML\x22,\x22showGroupDetailReportWithGroup\x22,\x22getGroupDetailReportWithStats\x22,\x22getAllGroupsSummary\x22,\x22generateReportTableHTML\x22,\x22generateGroupDetailHTMLV3\x22,\x22getGroupDetailReportData\x22,\x22rebuildAll\x22,\x22submitMemberForm\x22,\x22showUploadForm\x22,\x22getMemberInfo\x22,\x22clearTestUploadData\x22,\x22showAllUploadData\x22,\x22clearUploadRow2\x22,\x22clearUploadRow28\x22,\x22clearUploadCellA302\x22,\x22viewRow28\x22,\x22deleteRowByNumber\x22,\x22setCellValue\x22,\x22doGet\x22,\x22doPost\x22,\x22onOpen\x22,\x22quickFix10\x22,\x22quickFix20\x22,\x22quickFix30\x22,\x22quickFix50\x22,\x22quickFix100\x22,\x22quickFixByRange\x22,\x22deleteSelectedRowsAndUpdate\x22,\x22quickFixWithRange\x22,\x22addMemberByMode\x22,\x22checkMemberNoExists\x22,\x22getMemberDetail\x22,\x22updateMember\x22,\x22getGroupsList\x22,\x22getMemberInfoByNo\x22,\x22getUploadCount\x22,\x22saveMemberUploadsData\x22,\x22getMemberIdByNo\x22,\x22submitUploadData\x22,\x22getUploadRecordsByMember\x22,\x22cnGetMemberInfo\x22,\x22getCnUploadLocation\x22,\x22cnSubmitUpload\x22,\x22updateCnMemberTotal\x22,\x22getCnCurrentYearMonth\x22,\x22getMemberInfoForForm\x22,\x22addUserMember\x22,\x22addLeaderMember\x22,\x22getNewMembersByGroup\x22,\x22getAllNewMembers\x22,\x22sendUploadRemarkNotification\x22,\x22submitUserUpload\x22,\x22afterUploadUpdateStats\x22,\x22updateMemberUploadRecordWithRemark\x22,\x22registerMember\x22,\x22submitLeaderUpload\x22,\x22submitUploadFormData\x22,\x22batchImportFullYearData\x22,\x22showYearlySummary\x22,\x22batchImportCustomMembers\x22,\x22batchImport300Members\x22,\x22calculateAndWriteMonthlyTotal\x22,\x22calculateAndWriteGrandTotal\x22,\x22recalculateAllTotals\x22,\x22flushDataToSheet\x22,\x22createUploadSheet\x22,\x22getCurrentBatch\x22,\x22isBatchOpen\x22,\x22addRitualRecord\x22,\x22testBatch\x22,\x22testAdd\x22,\x22generateMassUploadRecords\x22,\x22quickGenerate500\x22,\x22quickGenerate\x22,\x22clearMemberRowsFrom45\x22,\x22testSendEmail\x22,\x22authorizeMailApp\x22,\x22copyJ43ToJ41J42\x22,\x22emergencyStop\x22,\x22setupBalancedSync\x22,\x22incrementalSync\x22,\x22autoFullSync\x22,\x22updateSingleMemberFast\x22,\x22checkSyncStatus\x22,\x22checkEmailQuota\x22\x5d,\x22sandboxMode\x22:\x22IFRAME_SANDBOX\x22,\x22callbackTimeout\x22:390000,\x22deploymentId\x22:\x22AKfycbzmx-NnHFINpcFQu9LHTFNutBJwQZ9zqBbcRBaaTlxoHNh0QwSY_VNigg3wMgkXApL7\x22,\x22eei\x22:\x22\x22,\x22sandboxHost\x22:\x22https:\/\/n-3mhxk4g3yb4uvegvguwx5yplyuuwxchjnykofga-0lu-script.googleusercontent.com\x22,\x22clientSideProperties\x22:\x7b\x22google.script.sandbox.mode\x22:\x22IFRAME_SANDBOX\x22,\x22google.script.host.origin\x22:\x22https:\/\/docs.google.com\x22\x7d,\x22actionPrefix\x22:\x22\/macros\/s\/AKfycbzmx-NnHFINpcFQu9LHTFNutBJwQZ9zqBbcRBaaTlxoHNh0QwSY_VNigg3wMgkXApL7\x22,\x22userHtml\x22:\x22\x3c!DOCTYPE html\x3e\\n\x3chtml lang\x3d\\\x22zh-Hant\\\x22\x3e\\n\x3chead\x3e\\n    \x3cmeta charset\x3d\\\x22UTF-8\\\x22\x3e\\n    \x3cmeta name\x3d\\\x22viewport\\\x22 content\x3d\\\x22width\x3ddevice-width, initial-scale\x3d1.0, user-scalable\x3dyes\\\x22\x3e\\n    \x3ctitle\x3e上傳數字表\x3c\\\/title\x3e\\n    \x3cstyle\x3e\\n        * \x7b box-sizing: border-box; font-family: system-ui, -apple-system, BlinkMacSystemFont, \x27Segoe UI\x27, Roboto, \x27Helvetica Neue\x27, Arial, \x27Noto Sans\x27, \x27PingFang SC\x27, \x27Microsoft YaHei\x27, sans-serif; \x7d\\n        \\n        body \x7b \\n            background: linear-gradient(145deg, #e0e7ff 0%, #c7d2fe 100%); \\n            margin: 0; \\n            padding: 20px 16px 40px 16px;\\n             \\n        \x7d\\n        .app-container \x7b \\n            max-width: 900px; \\n            width: 100%; \\n            margin: 0 auto; \\n            background: white; \\n            border-radius: 40px; \\n            box-shadow: 0 25px 45px -12px rgba(0,0,0,0.35); \\n            overflow: hidden; \\n            \\n        \x7d\\n        .hero-header \x7b background: #1e293b; color: white; padding: 24px 20px; position: relative; \x7d\\n        .hero-header h1 \x7b margin: 0; font-size: 28px; font-weight: 700; \x7d\\n        .hero-header p \x7b margin: 8px 0 0; opacity: 0.8; font-size: 16px; \x7d\\n        .tab-pane \x7b padding: 20px 16px; background: white; \x7d\\n        .form-row \x7b margin-bottom: 20px; \x7d\\n        label \x7b display: block; font-weight: 600; margin-bottom: 10px; color: #0f172a; font-size: 16px; \x7d\\n        input, select, textarea \x7b width: 100%; padding: 14px 18px; border: 1.5px solid #e2e8f0; border-radius: 28px; font-size: 16px; background: #fefefe; line-height: 1.4; \x7d\\n        input:disabled \x7b background: #f1f5f9; color: #94a3b8; cursor: not-allowed; \x7d\\n        button \x7b width: 100%; padding: 16px; background: #f97316; border: none; border-radius: 40px; font-weight: bold; font-size: 16px; color: white; cursor: pointer; margin-top: 20px; \x7d\\n        button.primary \x7b background: #f97316; \x7d\\n        button.primary:hover \x7b background: #ea580c; \x7d\\n        button.query-btn \x7b background: #0369a1; margin-top: 0; \x7d\\n        button.query-btn:hover \x7b background: #258BC9; \x7d\\n        button:disabled \x7b background: #cbd5e1; cursor: not-allowed; \x7d\\n        .message \x7b margin-top: 16px; padding: 14px; border-radius: 40px; text-align: center; font-size: 16px; display: none; line-height: 1.5; \x7d\\n        .message.success \x7b background: #dcfce7; color: #15803d; display: block; \x7d\\n        .message.error \x7b background: #fee2e2; color: #b91c1c; display: block; \x7d\\n        .message.warning \x7b background: #fff3e0; color: #e65100; display: block; \x7d\\n        .message.info \x7b background: #e0f2fe; color: #0369a1; display: block; \x7d\\n        .info-card \x7b background: #fef9e8; border-left: 5px solid #f97316; padding: 16px; border-radius: 24px; margin-bottom: 20px; font-size: 14px; line-height: 1.3; \x7d\\n        .warning-badge \x7b background: #ffedd5; color: #9a3412; padding: 14px; border-radius: 30px; text-align: center; font-weight: bold; margin-bottom: 20px; display: none; font-size: 16px; \x7d\\n        .history-item \x7b font-size: 16px; background: #fff7ed; margin: 5px 0; padding: 12px 16px; border-radius: 40px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; line-height: 1.5; \x7d\\n        .history-time \x7b font-size: 14px; color: #8d6e63; background: #f0e4c6; padding: 5px 10px; border-radius: 20px; font-family: monospace; \x7d\\n        footer \x7b text-align: center; font-size: 16px; padding: 14px; color: #94a3b8; background: #f8fafc; \x7d\\n        \\n        .reminder-box \x7b\\n            background: #e3f2fd;\\n            border-left: 4px solid #2196f3;\\n            padding: 16px 20px;\\n            border-radius: 16px;\\n            margin-bottom: 20px;\\n            font-size: 15px;\\n            color: #1565c0;\\n            line-height: 1.6;\\n        \x7d\\n        .reminder-box .emoji \x7b font-size: 22px; display: inline-block; margin-right: 10px; \x7d\\n        .reminder-box .text \x7b flex: 1; \x7d\\n        .reminder-box .text strong \x7b color: #0d47a1; \x7d\\n        \\n        .rule-box \x7b\\n            background: #fef9e8;\\n            border-left: 4px solid #f97316;\\n            padding: 16px 20px;\\n            border-radius: 16px;\\n            margin-bottom: 20px;\\n            font-size: 15px;\\n            color: #5d4037;\\n            line-height: 1.6;\\n        \x7d\\n        .rule-box .title \x7b\\n            font-weight: bold;\\n            font-size: 16px;\\n            margin-bottom: 8px;\\n            color: #e65100;\\n        \x7d\\n        .rule-box ul \x7b\\n            margin: 5px 0;\\n            padding-left: 20px;\\n        \x7d\\n        .rule-box li \x7b\\n            margin: 5px 0;\\n        \x7d\\n        \\n        .loading-spinner \x7b\\n            display: inline-block;\\n            width: 20px;\\n            height: 20px;\\n            border: 3px solid #f3f3f3;\\n            border-top: 3px solid #f97316;\\n            border-radius: 50%;\\n            animation: spin 0.8s linear infinite;\\n            vertical-align: middle;\\n            margin-right: 10px;\\n        \x7d\\n        @keyframes spin \x7b\\n            0% \x7b transform: rotate(0deg); \x7d\\n            100% \x7b transform: rotate(360deg); \x7d\\n        \x7d\\n        \\n        .query-status-area \x7b\\n            margin-bottom: 20px;\\n            display: none;\\n        \x7d\\n        .query-status-card \x7b\\n            background: #f1f5f9;\\n            border-radius: 32px;\\n            padding: 14px 18px;\\n            text-align: center;\\n            font-size: 16px;\\n            font-weight: 500;\\n            color: #1e293b;\\n            border-left: 6px solid #f97316;\\n        \x7d\\n        .query-status-card.loading \x7b\\n            background: #e0f2fe;\\n            color: #0369a1;\\n            border-left-color: #0284c7;\\n        \x7d\\n        .query-status-card.success \x7b\\n            background: #dcfce7;\\n            color: #15803d;\\n            border-left-color: #22c55e;\\n        \x7d\\n        .query-status-card.error \x7b\\n            background: #fee2e2;\\n            color: #b91c1c;\\n            border-left-color: #ef4444;\\n        \x7d\\n        .query-status-card.warning \x7b\\n            background: #ffedd5;\\n            color: #9a3412;\\n            border-left-color: #f97316;\\n        \x7d\\n        \\n        .query-btn-wrapper \x7b\\n            margin: 10px 0 20px 0;\\n        \x7d\\n        \\n        @keyframes fadeInUp \x7b\\n            from \x7b opacity: 0; transform: translateY(-30px); \x7d\\n            to \x7b opacity: 1; transform: translateY(0); \x7d\\n        \x7d\\n    \x3c\\\/style\x3e\\n\x3c\\\/head\x3e\\n\x3cbody\x3e\\n\x3cdiv class\x3d\\\x22app-container\\\x22\x3e\\n    \x3cdiv class\x3d\\\x22hero-header\\\x22\x3e\\n        \x3ch1\x3e一心皈命 📤 上傳數字表\x3c\\\/h1\x3e\\n        \x3cp\x3e請先查詢會員，確認資料後再上傳\x3c\\\/p\x3e\\n    \x3c\\\/div\x3e\\n    \x3cdiv class\x3d\\\x22tab-pane\\\x22\x3e\\n        \\n        \x3cdiv class\x3d\\\x22rule-box\\\x22\x3e\\n            \x3cdiv class\x3d\\\x22title\\\x22\x3e📌 上傳注意事項\x3c\\\/div\x3e\\n            \x3cul\x3e\\n                \x3cli\x3e📊 \x3cstrong\x3e只統計當月份上傳數字\x3c\\\/strong\x3e，每月1日重新計算，次月不累計\x3c\\\/li\x3e\\n                \x3cli\x3e✏️ \x3cstrong\x3e系統無法扣除上傳數字\x3c\\\/strong\x3e，請在5次上傳內仔細確認數字\x3c\\\/li\x3e\\n                \x3cli\x3e💬 若填寫錯誤，請直接向\x3cstrong\x3e組長反映\x3c\\\/strong\x3e，由組長協助修改\x3c\\\/li\x3e\\n                \x3cli\x3e📈 每月最多可上傳 \x3cstrong\x3e5 次\x3c\\\/strong\x3e，超過次數無法再上傳\x3c\\\/li\x3e\\n            \x3c\\\/ul\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv class\x3d\\\x22reminder-box\\\x22\x3e\\n            \x3cspan class\x3d\\\x22emoji\\\x22\x3e💡\x3c\\\/span\x3e\\n            \x3cspan class\x3d\\\x22text\\\x22\x3e\x3cstrong\x3e操作步驟：\x3c\\\/strong\x3e\x3cbr\x3e\\n            ① 輸入會員編號後按「🔍 查詢會員」\x3cbr\x3e\\n            ② 確認會員資料（查詢成功後數字欄位才會啟用）\x3cbr\x3e\\n            ③ 輸入數字\x3cbr\x3e\\n            ④ 點擊「📤 確認上傳」\x3c\\\/span\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv class\x3d\\\x22form-row\\\x22\x3e\\n            \x3clabel\x3e🔢 會員編號\x3c\\\/label\x3e\\n            \x3cinput type\x3d\\\x22text\\\x22 id\x3d\\\x22userMemberNo\\\x22 placeholder\x3d\\\x22請輸入會員編號\\\x22\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv class\x3d\\\x22query-btn-wrapper\\\x22\x3e\\n            \x3cbutton id\x3d\\\x22userCheckBtn\\\x22 class\x3d\\\x22query-btn\\\x22\x3e🔍 查詢會員\x3c\\\/button\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv id\x3d\\\x22queryStatusArea\\\x22 class\x3d\\\x22query-status-area\\\x22\x3e\\n            \x3cdiv id\x3d\\\x22queryStatusCard\\\x22 class\x3d\\\x22query-status-card\\\x22\x3e\x3c\\\/div\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv id\x3d\\\x22userMemberInfo\\\x22 style\x3d\\\x22display:none;\\\x22 class\x3d\\\x22info-card\\\x22\x3e\\n            \x3cdiv\x3e\x3cstrong\x3e📌 會員姓名：\x3c\\\/strong\x3e \x3cspan id\x3d\\\x22showMemberName\\\x22\x3e-\x3c\\\/span\x3e\x3c\\\/div\x3e\\n            \x3cdiv\x3e\x3cstrong\x3e📊 已上傳次數：\x3c\\\/strong\x3e \x3cspan id\x3d\\\x22uploadCountSpan\\\x22\x3e0\x3c\\\/span\x3e \/ 5\x3c\\\/div\x3e\\n            \x3cdiv id\x3d\\\x22historyArea\\\x22\x3e\x3c\\\/div\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv id\x3d\\\x22userLimitWarning\\\x22 class\x3d\\\x22warning-badge\\\x22\x3e⚠️ 本月已達5次上傳上限！\x3c\\\/div\x3e\\n        \\n        \x3cdiv class\x3d\\\x22form-row\\\x22\x3e\\n            \x3clabel\x3e💰 上傳數字\x3c\\\/label\x3e\\n            \x3cinput type\x3d\\\x22number\\\x22 id\x3d\\\x22userAmount\\\x22 placeholder\x3d\\\x22請先查詢會員\\\x22 disabled\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cdiv class\x3d\\\x22form-row\\\x22\x3e\\n            \x3clabel\x3e📝 備註\x3c\\\/label\x3e\\n            \x3cinput type\x3d\\\x22text\\\x22 id\x3d\\\x22userRemark\\\x22 placeholder\x3d\\\x22備註說明\\\x22 disabled\x3e\\n        \x3c\\\/div\x3e\\n        \\n        \x3cbutton id\x3d\\\x22userUploadBtn\\\x22 class\x3d\\\x22primary\\\x22 disabled\x3e📤 確認上傳\x3c\\\/button\x3e\\n        \x3cdiv id\x3d\\\x22userUploadMsg\\\x22 class\x3d\\\x22message\\\x22\x3e\x3c\\\/div\x3e\\n    \x3c\\\/div\x3e\\n    \x3cfooter\x3e© 會員上傳系統\x3c\\\/footer\x3e\\n\x3c\\\/div\x3e\\n\\n\x3cscript\x3e\\n    var currentUser \x3d null;\\n    var isQuerying \x3d false;\\n\\n    function maskName(name) \x7b\\n        if (!name) return \x27\x27;\\n        var n \x3d name.trim();\\n        if (n.length \x3c\x3d 2) return n;\\n        return n.charAt(0) + \x27O\x27 + n.charAt(n.length - 1);\\n    \x7d\\n\\n    \\n    function showSuccessModal(message) \x7b\\n        var existing \x3d document.getElementById(\x27customSuccessModal\x27);\\n        if (existing) existing.remove();\\n        var modal \x3d document.createElement(\x27div\x27);\\n        modal.id \x3d \x27customSuccessModal\x27;\\n        modal.style.cssText \x3d \x27position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); display:flex; align-items:flex-start; justify-content:center; z-index:10000; padding-top:120px;\x27;\\n        modal.innerHTML \x3d \x27\x3cdiv style\x3d\\\x22background:white; border-radius:48px; padding:35px 30px; width:360px; text-align:center; animation:fadeInUp 0.3s ease;\\\x22\x3e\x3cdiv style\x3d\\\x22font-size:60px; margin-bottom:15px;\\\x22\x3e🎉\x3c\\\/div\x3e\x3ch3 style\x3d\\\x22color:#1e293b; margin-bottom:18px; font-size:28px;\\\x22\x3e通知！\x3c\\\/h3\x3e\x3cdiv style\x3d\\\x22color:#475569; line-height:1.6; margin-bottom:22px; text-align:left; white-space:pre-line; font-size:16px;\\\x22\x3e\x27 + message.replace(\/\\\\n\/g, \x27\x3cbr\x3e\x27) + \x27\x3c\\\/div\x3e\x3cbutton id\x3d\\\x22closeSuccessModalBtn\\\x22 style\x3d\\\x22background:#f97316; color:white; border:none; padding:16px 24px; border-radius:40px; font-size:17px; font-weight:600; cursor:pointer; width:100%;\\\x22\x3e我知道了\x3c\\\/button\x3e\x3c\\\/div\x3e\x27;\\n        document.body.appendChild(modal);\\n        document.getElementById(\x27closeSuccessModalBtn\x27).onclick \x3d function() \x7b modal.remove(); \x7d;\\n        modal.onclick \x3d function(e) \x7b if (e.target \x3d\x3d\x3d modal) modal.remove(); \x7d;\\n    \x7d\\n\\n    function showMsg(msg, type) \x7b\\n        var el \x3d document.getElementById(\x27userUploadMsg\x27);\\n        if (el) \x7b\\n            el.className \x3d \x27message \x27 + type;\\n            el.innerText \x3d msg;\\n            el.style.display \x3d \x27block\x27;\\n            setTimeout(function() \x7b if (el) el.style.display \x3d \x27none\x27; \x7d, 4000);\\n        \x7d\\n    \x7d\\n\\n    function showQueryStatus(status, message) \x7b\\n        var area \x3d document.getElementById(\x27queryStatusArea\x27);\\n        var card \x3d document.getElementById(\x27queryStatusCard\x27);\\n        \\n        area.style.display \x3d \x27block\x27;\\n        card.innerHTML \x3d \x27\x27;\\n        \\n        switch(status) \x7b\\n            case \x27loading\x27:\\n                card.className \x3d \x27query-status-card loading\x27;\\n                card.innerHTML \x3d \x27\x3cspan class\x3d\\\x22loading-spinner\\\x22\x3e\x3c\\\/span\x3e 🔍 \x27 + message;\\n                break;\\n            case \x27success\x27:\\n                card.className \x3d \x27query-status-card success\x27;\\n                card.innerHTML \x3d \x27✅ \x27 + message;\\n                setTimeout(function() \x7b\\n                    var areaEl \x3d document.getElementById(\x27queryStatusArea\x27);\\n                    if (areaEl) areaEl.style.display \x3d \x27none\x27;\\n                \x7d, 3000);\\n                break;\\n            case \x27error\x27:\\n                card.className \x3d \x27query-status-card error\x27;\\n                card.innerHTML \x3d \x27❌ \x27 + message;\\n                break;\\n            case \x27warning\x27:\\n                card.className \x3d \x27query-status-card warning\x27;\\n                card.innerHTML \x3d \x27⚠️ \x27 + message;\\n                break;\\n            default:\\n                card.className \x3d \x27query-status-card\x27;\\n                card.innerHTML \x3d message;\\n        \x7d\\n    \x7d\\n    \\n    function hideQueryStatus() \x7b\\n        var area \x3d document.getElementById(\x27queryStatusArea\x27);\\n        if (area) area.style.display \x3d \x27none\x27;\\n    \x7d\\n    \\n    function setInputsEnabled(enabled) \x7b\\n        var amountInput \x3d document.getElementById(\x27userAmount\x27);\\n        var remarkInput \x3d document.getElementById(\x27userRemark\x27);\\n        if (enabled) \x7b\\n            amountInput.disabled \x3d false;\\n            remarkInput.disabled \x3d false;\\n        \x7d else \x7b\\n            amountInput.disabled \x3d true;\\n            remarkInput.disabled \x3d true;\\n            amountInput.value \x3d \x27\x27;\\n        \x7d\\n    \x7d\\n\\n    function queryMember() \x7b\\n        var no \x3d document.getElementById(\x27userMemberNo\x27).value.trim();\\n        if (!no) \x7b\\n            showSuccessModal(\x27⚠️ 請輸入會員編號\x27);\\n            return;\\n        \x7d\\n        if (isQuerying) return;\\n        isQuerying \x3d true;\\n        \\n        setInputsEnabled(false);\\n        document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n        document.getElementById(\x27userMemberInfo\x27).style.display \x3d \x27none\x27;\\n        document.getElementById(\x27userLimitWarning\x27).style.display \x3d \x27none\x27;\\n        \\n        showQueryStatus(\x27loading\x27, \x27查詢會員編號：\x27 + no + \x27，請稍候...\x27);\\n        \\n        google.script.run.withSuccessHandler(function(r) \x7b\\n            isQuerying \x3d false;\\n            if (r.success) \x7b\\n                currentUser \x3d r;\\n                document.getElementById(\x27userMemberInfo\x27).style.display \x3d \x27block\x27;\\n                document.getElementById(\x27showMemberName\x27).innerText \x3d (r.name);\\n                var cnt \x3d r.uploadInfo.uploadedCount;\\n                document.getElementById(\x27uploadCountSpan\x27).innerText \x3d cnt;\\n                \\n                var monthlyTotal \x3d 0;\\n                if (r.uploadInfo.history \x26\x26 r.uploadInfo.history.length) \x7b\\n                    for (var i \x3d 0; i \x3c r.uploadInfo.history.length; i++) \x7b\\n                        monthlyTotal +\x3d r.uploadInfo.history\x5bi\x5d.amount;\\n                    \x7d\\n                \x7d\\n                r.uploadInfo.monthlyTotal \x3d monthlyTotal;\\n                currentUser \x3d r;\\n\\n                var html \x3d \x27\x3cdiv\x3e\x3cstrong\x3e📋 歷史上傳：\x3c\\\/strong\x3e\x3c\\\/div\x3e\x27;\\n                if (r.uploadInfo.history \x26\x26 r.uploadInfo.history.length) \x7b\\n                    for (var i \x3d 0; i \x3c r.uploadInfo.history.length; i++) \x7b\\n                        var h \x3d r.uploadInfo.history\x5bi\x5d;\\n                        var timeStr \x3d h.date ? h.date : \x27時間未記錄\x27;\\n                        html +\x3d \x27\x3cdiv class\x3d\\\x22history-item\\\x22\x3e\x27 +\\n                                    \x27\x3cspan\x3e📌 第 \x27 + h.number + \x27 次：數字 \x27 + h.amount.toLocaleString() + \x27\x3c\\\/span\x3e\x27 +\\n                                    \x27\x3cspan class\x3d\\\x22history-time\\\x22\x3e🕘 \x27 + timeStr + \x27\x3c\\\/span\x3e\x27 +\\n                                \x27\x3c\\\/div\x3e\x27;\\n                    \x7d\\n                \x7d else \x7b \\n                    html +\x3d \x27\x3cdiv\x3e無紀錄\x3c\\\/div\x3e\x27; \\n                \x7d\\n                \\n                var totalHtml \x3d \x27\x3cdiv style\x3d\\\x22background:#f97316; color:white; padding:14px 18px; border-radius:35px; margin-top:15px; margin-bottom:15px; text-align:center; font-weight:700; font-size:16px;\\\x22\x3e📊 當月累計總額：\x27 + monthlyTotal.toLocaleString() + \x27\x3c\\\/div\x3e\x27;\\n                document.getElementById(\x27historyArea\x27).innerHTML \x3d totalHtml + html;\\n                \\n                var full \x3d cnt \x3e\x3d 5;\\n                var isDisabled \x3d r.status \x26\x26 r.status.includes(\x27停用\x27);\\n                \\n                if (isDisabled) \x7b\\n                    document.getElementById(\x27userLimitWarning\x27).style.display \x3d \x27block\x27;\\n                    document.getElementById(\x27userLimitWarning\x27).innerHTML \x3d \x27⚠️ 該會員已停用，無法上傳！\x27;\\n                    document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n                    setInputsEnabled(false);\\n                    showQueryStatus(\x27error\x27, \x27會員已停用，無法上傳數字\x27);\\n                    showSuccessModal(\x27⚠️ 會員已停用，無法上傳數字\x27);\\n                \x7d else if (full) \x7b\\n                    document.getElementById(\x27userLimitWarning\x27).style.display \x3d \x27block\x27;\\n                    document.getElementById(\x27userLimitWarning\x27).innerHTML \x3d \x27⚠️ 本月已達5次上傳上限！\x27;\\n                    document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n                    setInputsEnabled(false);\\n                    showQueryStatus(\x27warning\x27, \x27本月已達5次上傳上限，無法繼續上傳\x27);\\n                    showSuccessModal(\x27⚠️ 本月已達5次上傳上限，無法繼續上傳\x27);\\n                \x7d else \x7b\\n                    document.getElementById(\x27userLimitWarning\x27).style.display \x3d \x27none\x27;\\n                    document.getElementById(\x27userUploadBtn\x27).disabled \x3d false;\\n                    setInputsEnabled(true);\\n                    showQueryStatus(\x27success\x27, \x27會員驗證成功！姓名：\x27 + (r.name) + \x27，剩餘上傳次數：\x27 + (5 - cnt));\\n                    showSuccessModal(\x27✅ 會員驗證成功！\\\\n\\\\n姓名：\x27 + (r.name) + \x27\\\\n剩餘上傳次數：\x27 + (5 - cnt) + \x27\\\\n請輸入數字後點擊「確認上傳」\x27);\\n                \x7d\\n            \x7d else \x7b\\n                currentUser \x3d null;\\n                document.getElementById(\x27userMemberInfo\x27).style.display \x3d \x27none\x27;\\n                document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n                setInputsEnabled(false);\\n                showQueryStatus(\x27error\x27, r.message);\\n                showSuccessModal(\x27❌ \x27 + r.message);\\n            \x7d\\n        \x7d).withFailureHandler(function(err) \x7b\\n            isQuerying \x3d false;\\n            currentUser \x3d null;\\n            document.getElementById(\x27userMemberInfo\x27).style.display \x3d \x27none\x27;\\n            document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n            setInputsEnabled(false);\\n            showQueryStatus(\x27error\x27, \x27查詢失敗：\x27 + err.message);\\n            showSuccessModal(\x27❌ 查詢失敗：\x27 + err.message);\\n        \x7d).getMemberInfoByNo(no);\\n    \x7d\\n\\n    function uploadAmount() \x7b\\n        if (!currentUser) \x7b\\n            showSuccessModal(\x27❌ 尚未驗證會員！請先點擊「🔍 查詢會員」\x27);\\n            return;\\n        \x7d\\n        \\n        var amountInput \x3d document.getElementById(\x27userAmount\x27);\\n        var remarkInput \x3d document.getElementById(\x27userRemark\x27);\\n        var amount \x3d parseFloat(amountInput.value);\\n        var remark \x3d remarkInput.value;\\n        var no \x3d document.getElementById(\x27userMemberNo\x27).value.trim();\\n        \\n        if (isNaN(amount) || amount \x3c\x3d 0) \x7b \\n            showSuccessModal(\x27⚠️ 請輸入有效的數字（大於0）\x27);\\n            return; \\n        \x7d\\n        \\n        if (currentUser.uploadInfo.uploadedCount \x3e\x3d 5) \x7b\\n            showSuccessModal(\x27⚠️ 本月已達5次上傳上限，無法再上傳\x27);\\n            return;\\n        \x7d\\n        \\n        if (currentUser.status \x26\x26 currentUser.status.includes(\x27停用\x27)) \x7b\\n            showSuccessModal(\x27⚠️ 會員已停用，無法上傳\x27);\\n            return;\\n        \x7d\\n        \\n        var currentTotal \x3d currentUser.uploadInfo.monthlyTotal || 0;\\n        var newTotal \x3d currentTotal + amount;\\n        var newCount \x3d currentUser.uploadInfo.uploadedCount + 1;\\n        \\n        currentUser.uploadInfo.history.push(\x7b\\n            number: newCount,\\n            amount: amount,\\n            date: new Date().toLocaleString()\\n        \x7d);\\n        currentUser.uploadInfo.uploadedCount \x3d newCount;\\n        currentUser.uploadInfo.monthlyTotal \x3d newTotal;\\n        \\n        var totalHtml \x3d \x27\x3cdiv style\x3d\\\x22background:#f97316; color:white; padding:14px 18px; border-radius:35px;margin-top:15px;margin-bottom:15px; text-align:center; font-weight:700; font-size:16px;\\\x22\x3e📊 當月累計總額：\x27 + newTotal.toLocaleString() + \x27\x3c\\\/div\x3e\x27;\\n        var historyHtml \x3d \x27\x3cdiv\x3e\x3cstrong\x3e📋 歷史上傳：\x3c\\\/strong\x3e\x3c\\\/div\x3e\x27;\\n        for (var i \x3d 0; i \x3c currentUser.uploadInfo.history.length; i++) \x7b\\n            var h \x3d currentUser.uploadInfo.history\x5bi\x5d;\\n            historyHtml +\x3d \x27\x3cdiv class\x3d\\\x22history-item\\\x22\x3e\x27 +\\n                                \x27\x3cspan\x3e📌 第 \x27 + h.number + \x27 次：數字 \x27 + h.amount.toLocaleString() + \x27\x3c\\\/span\x3e\x27 +\\n                                \x27\x3cspan class\x3d\\\x22history-time\\\x22\x3e🕘 \x27 + h.date + \x27\x3c\\\/span\x3e\x27 +\\n                            \x27\x3c\\\/div\x3e\x27;\\n        \x7d\\n        document.getElementById(\x27historyArea\x27).innerHTML \x3d totalHtml + historyHtml;\\n        document.getElementById(\x27uploadCountSpan\x27).innerText \x3d newCount;\\n        \\n        var full \x3d newCount \x3e\x3d 5;\\n        if (full) \x7b\\n            document.getElementById(\x27userLimitWarning\x27).style.display \x3d \x27block\x27;\\n            document.getElementById(\x27userLimitWarning\x27).innerHTML \x3d \x27⚠️ 本月已達5次上傳上限！\x27;\\n            document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n            setInputsEnabled(false);\\n        \x7d\\n        \\n        \\n        showSuccessModal(\x27✅ 上傳成功！\\\\n👤 姓名：\x27 + currentUser.name + \x27\\\\n💰 本次：\x27 + amount.toLocaleString() + \x27\\\\n📊 當月累計：\x27 + newTotal.toLocaleString());\\n        \\n        amountInput.value \x3d \x27\x27;\\n\\n        \\n        var rInput \x3d document.getElementById(\x27userRemark\x27); if (rInput) rInput.value \x3d \x27\x27;\\n        \\n        \\n        google.script.run.withFailureHandler(function(err) \x7b\\n            showSuccessModal(\x27⚠️ 畫面已更新，但後端錯誤：\x27 + err.message + \x27，請聯絡管理員\x27);\\n        \x7d).submitUserUpload(no, currentUser.name, amount, remark);\\n\\n    \x7d\\n    \\n    \\n    var amountField \x3d document.getElementById(\x27userAmount\x27);\\n    if (amountField) \x7b\\n        amountField.addEventListener(\x27focus\x27, function() \x7b\\n            if (!currentUser) \x7b\\n                var no \x3d document.getElementById(\x27userMemberNo\x27).value.trim();\\n                if (no) \x7b\\n                    showSuccessModal(\x27🔍 尚未查詢，自動為您查詢會員...\x27);\\n                    queryMember();\\n                    this.blur();\\n                \x7d else \x7b\\n                    showSuccessModal(\x27⚠️ 請先輸入會員編號並點擊「查詢」\x27);\\n                    this.blur();\\n                \x7d\\n            \x7d\\n        \x7d);\\n    \x7d\\n    \\n    document.getElementById(\x27userCheckBtn\x27).onclick \x3d queryMember;\\n    document.getElementById(\x27userUploadBtn\x27).onclick \x3d uploadAmount;\\n    \\n    var memberNoInput \x3d document.getElementById(\x27userMemberNo\x27);\\n    memberNoInput.addEventListener(\x27keypress\x27, function(e) \x7b\\n        if (e.key \x3d\x3d\x3d \x27Enter\x27) \x7b\\n            e.preventDefault();\\n            queryMember();\\n        \x7d\\n    \x7d);\\n    \\n    memberNoInput.addEventListener(\x27input\x27, function() \x7b\\n        if (currentUser) \x7b\\n            currentUser \x3d null;\\n            document.getElementById(\x27userMemberInfo\x27).style.display \x3d \x27none\x27;\\n            document.getElementById(\x27userUploadBtn\x27).disabled \x3d true;\\n            document.getElementById(\x27userLimitWarning\x27).style.display \x3d \x27none\x27;\\n            setInputsEnabled(false);\\n            hideQueryStatus();\\n        \x7d\\n    \x7d);\\n\x3c\\\/script\x3e\\n\x3c\\\/body\x3e\\n\x3c\\\/html\x3e\x22,\x22ncc\x22:\x22\x7b\\\x22awhs\\\x22:true\x7d\x22\x7d", "", undefined, true , false  , "false", "https:\/\/n-3mhxk4g3yb4uvegvguwx5yplyuuwxchjnykofga-0lu-script.googleusercontent.com", "https:\/\/drive.google.com\/abuse?id\x3dAKkXjoy_XgPxJh_L5gyw2zj2QRt68QngO5kknZRSNUR2quZmpsCVy-LDto3zV4sD9LGHxtU0Moxcsm4c3Kr40oPW48qNiSUS5cjJcCOn%3A0\x26docurl\x3dhttps%3A%2F%2Fscript.google.com%2Fmacros%2Fs%2FAKfycbzmx-NnHFINpcFQu9LHTFNutBJwQZ9zqBbcRBaaTlxoHNh0QwSY_VNigg3wMgkXApL7%2Fexec");}
el.src = 'https:\/\/n-3mhxk4g3yb4uvegvguwx5yplyuuwxchjnykofga-0lu-script.googleusercontent.com\/userCodeAppPanel';
}());
</script>
</body>
</html>
