HEX
Server: Apache/2.4.37 (CentOS Stream) OpenSSL/1.1.1k
System: Linux ysnet.com.tw 4.18.0-553.5.1.el8.x86_64 #1 SMP Tue May 21 05:46:01 UTC 2024 x86_64
User: test (521)
PHP: 7.4.33
Disabled: NONE
Upload Files
File: /var/www/test/Installationlist/oldphp/confirmold.php
<!DOCTYPE html>
<html lang="zh-Hant">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>確認與簽名</title>
        <style>
            body { font-family: "Microsoft JhengHei", sans-serif; padding: 20px; font-size: 18px; }
            .section { margin-bottom: 30px; }
            .signature-box, .photo-box { border: 1px solid #ccc; padding: 16px; border-radius: 8px;}
            table { border-collapse: collapse; width: 100%; margin-bottom: 20px;}
            td, th { border: 1px solid #000; padding: 10px; vertical-align: top; }
            .section-title { background: #f6f6f6; font-weight: bold; font-size: 22px; text-align: center;}
            .label { font-weight: bold; width: 20%; background: #f7f7fa;}
            .val { width: 30%; box-sizing: border-box;}
            .btn { padding: 10px 20px; font-size: 16px; margin: 10px 5px; cursor: pointer; }
            .highlight { background: #f9f9a9; padding: 10px; border-left: 4px solid #f1c40f; }
            .btn-group { margin: 28px 0; text-align: center; }
            .btn:hover { background: #e0e7ef; }
            .file-btn { display: inline-block; font-size: 20px; padding: 12px 20px; background-color: #f0f0f0; border: 1px solid #ccc; border-radius: 6px; cursor: pointer; margin-bottom: 10px; text-align: center; }
            .file-btn input[type="file"] { display: none; }
            .terms-wrapper { max-height: 300px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; background: #fffdf5; margin-bottom: 12px; }
            #signature-modal { display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.6); justify-content:center; align-items:center; z-index:9999; }
            #signature-box { background:#fff; width:80vw; height:80vh; padding:20px; display:flex; flex-direction:column; align-items:center; justify-content:center; box-shadow:0 0 10px rgba(0,0,0,0.5); border-radius: 10px; }
            #signature-canvas { width:100%; height:100%; border:1px solid #000; box-sizing: border-box; touch-action: none; }
        </style>
    </head>
    <body>
        <h2>請確認以下條款</h2>
        <iframe id="previewFrame" src="preview.php" style="display:none;"></iframe>

        <div class="section">
            <div class="terms-wrapper" id="terms-box">
                <div class="highlight">
                    第一條、<br>Internet係開放性網路,各種資源之正確性與完整性,本公司無法保證,倘客戶因截取使用網路資料而導致損失時,本公司亦不負損害賠償責任。<br><br>
                        第二條、<br>用戶租用本業務應繳各項費用及收費標準如價目表;資費如有調整時,按新費率計收,用戶如不同意繳付新費率,可隨時終止契約,並辦理退費。申請加值服務者,以網頁上公告費用計收各項費用。<br><br>
                        第三條、<br>本公司因技術上需要,得將用戶號碼、用戶識別碼、IP ADDRESS、連接方式、用戶解面、傳輸型態等予以變更,用戶不得異議或提出其他要求。<br><br>
                        第四條、<br>本公司使用網路位址轉換技術共享真實IP,少數需要真實IP的連線服務會受此限制,用戶應確認有無此需求。<br><br>
                        第五條、<br>本公司基於保障消費者權益,給予您一個月滿意鑑賞期,期間若不滿意,本公司保證全額退費。<br><br>
                        第六條、<br>本公司配發每一個用戶一組帳號密碼,每組帳號密碼可供一台電腦使用,若家中為兩台以上電腦上網,則需請用戶使用IP分享器。<br><br>
                        第七條、<br>本公司以戶為單位,用戶不得私自接線提供他戶使用。<br><br>
                        第八條、<br>用戶端如有無線網路路由設備,應設加密,以防止第三人竊取頻寬或是進行違法情形。<br><br>
                        第九條、<br>本公司應維持本業務系統設備之正常運作,遇有障礙應盡速修復。但用户自備設備者,應自行檢修,用户使用本業務,如因本公司系統設備障礙、阻斷,以致發生錯誤、遲滞、中斷或不能傳遞而造成損害時,其所發生之損害,除按本契約條款第十條之規定給予補償外,本公司不負損害賠責任。<br><br>
                        第十條、<br>用戶租用本業務,因不可歸責於用户之原因,致系統障礙不能通信時 :本公司應扣減網路租费。通信連續阻斷二十四小時以上者,每二十四小時扣減全月租費三十分一,但不滿二十四小时部分,不予減扣。由於天然災害之不可抗力致不能通信者,自連續阻日起至修復日止,不收租費。前項阻斷開始之時間,以本公司查覺或接到用户通知之時間為準。但有事實足以證明實際開始阻斷之時間者,依實際開始阻斷之時間為準。<br><br>
                        第十一條、<br>辦理退租時,須請申請人或其代理人攜帶各自的有效身份證明文件正本、 雙證件正本(指身份證及健保卡...等等)。至本公司桃園營運處:桃園市桃園區大興西路二段61號16樓,辦理退費,相關注意事項如下:<br>
                                1.使用登記人為退費的權益人,退費需攜帶雙證件正本辦理,倘委託代理人辦理,則代理人需攜帶使用登記人之雙證件正本及代理人的雙證件正本,方可辦理。<br>
                                2.用户至門市填妥退租申請書,完成折讓程序並經身份確認後,方可退費。<br>
                                3.使用月份不足一個月者,依使用天數等比例結算,贈送月份不計入退費月份。<br>
                                4.倘有加購之優惠,於計算已使用月份之費用時,先依標准資費計算,之後的月份再依加購資費計算。<br>
                                5.特定資費方案有聲明不得退費者,不享有以上退費措施。<br>
                                6.申裝優惠方案,倘使用未滿優惠期限內退費,則喪失優惠資格,必需補繳優惠之裝機費用,新台幣500元,若有贈品則需補繳裝機時提供贈品之費用。<br>
                                7.光纖安裝用戶,若不續用網路需自行歸還光纖設備,包含光纖盒變、變壓器及光纖線,則無息退還押金。<br>
                                8.影音方案須綁約乙年,期間無法退租退費。(方案中電視盒、Litv收視壹年及分享器為贈品)<br><br>
                        第十二條、<br>用戶租用本業務應繳之費用應在本公司通知繳費之期限內繳清,逾期未繳費者,本公司得註銷其申請並暫停其使用。經限期催繳仍未繳納者,得終止其使用,用户積欠之費用仍需缴納。用戶對各項應繳費用有異議並申訴者,在未查明責任歸屬前,本公司暫緩催費。<br><br>
                        第十三條、<br>1.有竊取、更改、破壞他人資訊情事者。<br>
                                2.有擅自複製他人資訊轉售,轉載情事者。<br>
                                3.未經對方同意、擅自寄發垃圾、炸彈郵包或廣告郵件至對方信箱者。<br>
                                4.於論壇區張貼與主題無關之訊息者。<br>
                                5.蓄意破壞他人信箱或其通信設備者。<br>
                                6.散播電腦病毒者。<br>
                                7.所為言論違背公序良俗者。<br>
                                8.擷取非經所有正式開放或授權之資源者。<br>
                                9.不當使用續傳軟體者。<br>
                                10.其他有危通信或網路品質穩定之情事者。<br>
                                11.提供妨害公共秩序及善良風俗之電信内容為營業者。<br><br>
                        第十四條、<br>本公司於P2P相關軟體上(如:BT、迅雷 ......等等)下載與上傳皆無問題;為维護社區網路之連線品質,對於影響該社區其他用户上網品質之情形,得限制其頻寬,若有大量P2P傳輸需求的使用者,請謹慎評估。<br><br>
                        第十五條、<br>申請電信業務所需之相關證件,依據主管機關通訊傳播委員會相關要求辦理;針對個人資料收集及各項告知義務,則依據個人資料保護法相關細則實行。<br><br>
                        第十六條、<br>本契約條款未規定事項,用户同意遵守相關法令規定及本公司各項業務營業規章之規定。<br><br>
                        第十七條、<br>因本契約涉訟時,雙方合意以桃園地方法院為第一審管法院。<br><br>
                </div>
            </div>
            <label>
                <input type="checkbox" id="agree-check" disabled> 我已閱讀並同意上述條款
                <br><small id="scroll-tip" style="color: gray;">※ 請閱讀完整條款內容後才能勾選同意</small>
            </label>
        </div>
        <table>
            <tr class="section-title"><td colspan="4">完工有線測速</td></tr>
            <tr>
                <td class="label">下載速率(Mbps)</td><td class="val"><input type="number" id="download" min="1" style="width:100%; font-size:18px; box-sizing:border-box;"></td>
                <td class="label">上傳速率(Mbps)</td><td class="val"><input type="number" id="upload" min="1" style="width:100%; font-size:18px; box-sizing:border-box;"></td>
            </tr>   
        </table>
        <div class="section signature-box">
        	<div style="display: flex; flex-wrap: wrap; align-items: center; gap: 12px;">
        		<h3 style="margin: 0;">申請人簽名</h3>
        		<button class="btn" onclick="openSignatureModal()">打開簽名板</button>
        
        		<label>
            		<select id="signature-type" style="font-size:16px; padding:6px;">
                		<option value="本人">本人簽名</option>
                		<option value="代簽">代簽</option>
            		</select>
        		</label>

        		<input type="text" id="proxy-id" placeholder="請輸入代簽人身分證字號" maxlength="10" style="display:none; font-size:16px; padding:6px;" />
    		</div>
        	<div id="signature-preview"></div>
        </div>

        <div class="section photo-box">
            <h3>請上傳雙證件影本</h3>
            <label class="file-btn">身分證正面<input type="file" id="photo-front" accept="image/*" onchange="handlePhoto(this, 'preview-front')"></label>
            <img id="preview-front" style="max-width:100%; margin-top:10px; display:block;">
            <label class="file-btn">身分證反面<input type="file" id="photo-back" accept="image/*" onchange="handlePhoto(this, 'preview-back')"></label>
            <img id="preview-back" style="max-width:100%; margin-top:10px; display:block;">
            <label class="file-btn">第二證件正面<input type="file" id="photo-second" accept="image/*" onchange="handlePhoto(this, 'preview-second')"></label>
            <img id="preview-second" style="max-width:100%; margin-top:10px; display:block;">
        </div>

        <div class="btn-group">
            <button class="btn" onclick="window.location.href='preview.php'">返回上一頁</button>
            <button class="btn" id="submit-btn" onclick="finalSubmit()">送出</button>
        </div>

        <div id="signature-modal">
            <div id="signature-box">
                <div class="signature-actions">
                    <button class="btn" onclick="clearSignature()">清除</button>
                    <button class="btn" onclick="saveSignature()">確認</button>
                    <button class="btn" onclick="cancelSignature()">取消</button>
                </div>
                <canvas id="signature-canvas"></canvas>
            </div>
        </div>

        <script>
            document.getElementById("terms-box").addEventListener("scroll", function () {
                const checkbox = document.getElementById("agree-check");
                const scrollBottom = this.scrollTop + this.clientHeight;
                if (scrollBottom >= this.scrollHeight - 5) checkbox.disabled = false;
            });

            const modal = document.getElementById('signature-modal');
            const canvas = document.getElementById('signature-canvas');
            const ctx = canvas.getContext('2d');
            let drawing = false;

            function resizeCanvas() {
                canvas.width = canvas.offsetWidth;
                canvas.height = canvas.offsetHeight;
            }
            window.addEventListener('resize', resizeCanvas);
            window.addEventListener('load', resizeCanvas);

            canvas.addEventListener('mousedown', (e) => {
                drawing = true;
                ctx.beginPath();
                ctx.moveTo(e.offsetX, e.offsetY);
            });
            canvas.addEventListener('mousemove', (e) => {
                if (!drawing) return;
                ctx.lineTo(e.offsetX, e.offsetY);
                ctx.stroke();
            });
            canvas.addEventListener('mouseup', () => drawing = false);

            canvas.addEventListener('touchstart', function(e) {
                e.preventDefault();
                const touch = e.touches[0];
                const rect = canvas.getBoundingClientRect();
                ctx.beginPath();
                ctx.moveTo(touch.clientX - rect.left, touch.clientY - rect.top);
            });
            canvas.addEventListener('touchmove', function(e) {
                e.preventDefault();
                const touch = e.touches[0];
                const rect = canvas.getBoundingClientRect();
                ctx.lineTo(touch.clientX - rect.left, touch.clientY - rect.top);
                ctx.stroke();
            });

            function clearSignature() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
            }

            function saveSignature() {
                if (canvas.toDataURL() === document.createElement('canvas').toDataURL()) {
                    alert("請簽名後再確認"); return;
                }
                const image = canvas.toDataURL();
                sessionStorage.setItem("signatureData", image);
                modal.style.display = "none";
                document.getElementById("signature-preview").innerHTML =`<img src="${image}" style="max-width:100%; border:1px solid #ccc; margin-top:10px;">`;
            }

            function cancelSignature() {
                clearSignature();
                sessionStorage.removeItem("signatureData");
                document.getElementById("signature-preview").innerHTML = "";
                modal.style.display = "none";
            }

            function openSignatureModal() {
                modal.style.display = "flex";
                setTimeout(resizeCanvas, 0);
            }

            function handlePhoto(input, previewId) {
                const file = input.files[0];
                if (!file) return;
                const reader = new FileReader();
                reader.onload = function (event) {
                    const img = new Image();
                    img.onload = function () {
                        const canvas = document.createElement("canvas");
                        const ctx = canvas.getContext("2d");
                        canvas.width = img.width;
                        canvas.height = img.height;
                        ctx.drawImage(img, 0, 0);
                        ctx.font = `bold ${Math.floor(img.width / 15)}px Microsoft JhengHei`;
                        ctx.fillStyle = "rgba(255, 0, 0, 0.6)";
                        ctx.textAlign = "center";
                        ctx.textBaseline = "middle";
                        ctx.fillText("限申辦亞訊寬頻網路專用", img.width / 2, img.height / 2);
                        const result = canvas.toDataURL("image/jpeg");
                        document.getElementById(previewId).src = result;
                        sessionStorage.setItem(previewId + "_image", result);
                    };
                    img.src = event.target.result;
                };
                reader.readAsDataURL(file);
            }
            
            const proxyField = document.getElementById("proxy-id");
            const signatureTypeSelect = document.getElementById("signature-type");

            // 顯示/隱藏欄位
            signatureTypeSelect.addEventListener("change", function () {
                if (this.value === "代簽") {
                    proxyField.style.display = "inline-block";
                } else {
                    proxyField.style.display = "none";
                    proxyField.value = ""; // 清空欄位
                }
            });

            // 強制限制輸入為 10 碼以內(防止貼上超過)
            proxyField.addEventListener("input", function () {
                if (this.value.length > 10) {
                    this.value = this.value.toUpperCase().slice(0, 10);
                }
            });
                            
        	function base64ToBlob(dataurl) {
  const arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  for (let i = 0; i < n; i++) u8arr[i] = bstr.charCodeAt(i);
  return new Blob([u8arr], { type: mime });
}

function finalSubmit() {
  const agreed = document.getElementById("agree-check").checked;
  const signature = sessionStorage.getItem("signatureData");
  const downloadSpeed = document.getElementById("download").value;
  const uploadSpeed = document.getElementById("upload").value;
  const signatureType = document.getElementById("signature-type").value;
  const proxyID = document.getElementById("proxy-id").value.trim();

  const front = sessionStorage.getItem("preview-front_image");
  const back = sessionStorage.getItem("preview-back_image");
  const second = sessionStorage.getItem("preview-second_image");

  if (!agreed) return alert("請先閱讀並勾選同意條款");
  if (!downloadSpeed || isNaN(downloadSpeed) || Number(downloadSpeed) <= 0) return alert("請輸入有效的下載速率(Mbps)");
  if (!uploadSpeed || isNaN(uploadSpeed) || Number(uploadSpeed) <= 0) return alert("請輸入有效的上傳速率(Mbps)");
  if (!signature) return alert("請簽名後再送出");
  if (!front || !back || !second) return alert("請上傳三張證件圖檔");

  if (signatureType === "代簽") {
    const id = proxyID.toUpperCase();
    const isTaiwanID = /^[A-Z][12]\d{8}$/.test(id);
    const isResidentID = /^[A-Z]{2}\d{8}$/.test(id);
    if (!isTaiwanID && !isResidentID) return alert("請輸入正確的身分證或居留證字號(共 10 碼,格式需正確)");
    sessionStorage.setItem("proxy_id", id);
  } else {
    sessionStorage.removeItem("proxy_id");
  }

  sessionStorage.setItem("download", downloadSpeed);
  sessionStorage.setItem("upload", uploadSpeed);
  sessionStorage.setItem("signature_type", signatureType);

  const formData = new FormData();
  formData.append("signatureData", base64ToBlob(signature), "signature.png");
  formData.append("photo_front", base64ToBlob(front), "front.jpg");
  formData.append("photo_back", base64ToBlob(back), "back.jpg");
  formData.append("photo_second", base64ToBlob(second), "second.jpg");

  fetch("submit.php?preview=1", {
    method: "POST",
    body: formData
  })
  .then(res => {
    if (!res.ok) throw new Error("提交失敗");
    return res.text();
  })
  .then(html => {
    document.open();
    document.write(html);
    document.close();
  })
  .catch(err => alert("送出時發生錯誤:" + err.message));
}

        </script>
    </body>
</html>