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/preview.php
<?php
// ============================================================
// preview.php  ─  申請書預覽頁
// ============================================================
session_start();

// 接收 form.php POST 資料,存入 Session(方便返回修改)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $fields = [
        'user_id','member','memberaddress','useraddress','speed','basenumber',
        'pppoeid','pppoepw','fistcount',
        'applicant_name','applicant_usernumber','id_type',
        'applicant_phone','applicant_homenumber','applicant_email',
        'info_devices','info_qty','router_devices','router_qty','use_devices',
        'fee_type','fee_amount','extra_fees','total_fee','deposit_total',
        'install_date','rental_start_date','rental_end_date',
        'gift_months','real_end_date','enname','enphone'
    ];
    foreach ($fields as $f) {
        $_SESSION['preview'][$f] = $_POST[$f] ?? '';
    }
    $_SESSION['preview']['otp_verified'] = $_SESSION['otp_verified'] ?? false;
}

$d = $_SESSION['preview'] ?? [];
if (empty($d)) {
    header('Location: form.php');
    exit;
}

// 解碼 JSON 欄位
$infoList   = json_decode($d['info_devices'] ?? '[]', true) ?: [];
$routerList = json_decode($d['router_devices'] ?? '[]', true) ?: [];
$useList    = json_decode($d['use_devices'] ?? '[]', true) ?: [];
$extraList  = json_decode($d['extra_fees'] ?? '[]', true) ?: [];
$giftList   = json_decode($d['gift_months'] ?? '[]', true) ?: [];

// 費率中文
$feeLabel = [
    'season'=>'季繳','halfyear'=>'半年繳','year'=>'一年繳','twoyear'=>'兩年繳',
    'subscription'=>'定期定額月扣'
][$d['fee_type'] ?? ''] ?? $d['fee_type'] ?? '—';

// 日期格式化
function fmtDate($s) {
    if (!$s) return '—';
    $dt = DateTime::createFromFormat('Y-m-d', $s);
    return $dt ? $dt->format('Y年m月d日') : $s;
}
?>
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>裝機申請書預覽</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3.19.0/dist/tabler-icons.min.css">
    <style>
        *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
        :root {
            --green: #1D9E75; --green-lt: #E1F5EE; --green-dk: #0F6E56; --green-deep: #085041;
            --amber: #FAEEDA; --amber-txt: #633806;
            --red: #E24B4A;
            --gray-bg: #F5F5F5; --gray-bd: rgba(0,0,0,.13); --gray-bd2: rgba(0,0,0,.25);
            --text: #111; --text-sec: #666; --text-tert: #999;
            --radius-md: 8px; --radius-lg: 12px;
        }
        body { font-family: "Microsoft JhengHei","PingFang TC",sans-serif; font-size:15px; background:var(--gray-bg); color:var(--text); padding-bottom:90px; }

        .topbar { position:sticky;top:0;z-index:100;background:#fff;border-bottom:0.5px solid var(--gray-bd);padding:11px 16px;display:flex;align-items:center;gap:10px; }
        .topbar-title { flex:1;text-align:center;font-size:16px;font-weight:500; }
        .status-pill { font-size:11px;padding:3px 10px;border-radius:20px;background:var(--amber);color:var(--amber-txt); }

        .content { padding:12px 16px 16px;display:flex;flex-direction:column;gap:12px; }

        .card { background:#fff;border-radius:var(--radius-lg);border:0.5px solid var(--gray-bd);overflow:hidden; }
        .card-hdr { display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:0.5px solid var(--gray-bd);background:var(--gray-bg); }
        .card-hdr i { font-size:16px;color:var(--green); }
        .card-hdr-txt { font-size:13px;font-weight:500; }

        .row { display:flex;align-items:stretch;border-bottom:0.5px solid var(--gray-bd); }
        .row:last-child { border-bottom:none; }
        .lbl { width:88px;flex-shrink:0;font-size:12px;color:var(--text-sec);padding:9px 10px 9px 14px;background:var(--gray-bg);display:flex;align-items:center;justify-content:center;text-align:center;line-height:1.4; }
        .val { flex:1;padding:9px 14px;font-size:14px;color:var(--text);word-break:break-all; }
        .val.mono { font-family:monospace;font-size:13px;color:var(--text-sec); }
        .val.green { color:var(--green-dk);font-weight:500; }
        .val.big { font-size:16px;font-weight:500;color:var(--green-dk); }

        .device-chip { display:inline-flex;align-items:center;gap:3px;font-size:12px;background:var(--green-lt);color:var(--green-deep);padding:3px 10px;border-radius:20px;margin:3px 3px 3px 0; }
        .device-chip.gray { background:var(--gray-bg);color:var(--text-sec); }

        .fee-row { display:flex;align-items:center;padding:9px 14px;border-bottom:0.5px solid var(--gray-bd); }
        .fee-row:last-child { border-bottom:none; }
        .fee-name { font-size:13px;color:var(--text-sec);flex:1; }
        .fee-amt { font-size:14px;font-weight:500;color:var(--text); }

        .total-row { display:flex;align-items:center;justify-content:space-between;padding:12px 14px; }
        .total-lbl { font-size:13px;color:var(--text-sec); }
        .total-amt { font-size:22px;font-weight:500;color:var(--green); }
        .deposit-row { display:flex;align-items:center;justify-content:space-between;padding:8px 14px;border-top:0.5px solid var(--gray-bd);font-size:13px; }

        .date-row { display:flex;align-items:center;padding:9px 14px;border-bottom:0.5px solid var(--gray-bd); }
        .date-row:last-child { border-bottom:none; }
        .date-lbl { font-size:13px;color:var(--text-sec);flex:1; }
        .date-val { font-size:14px;font-weight:500;color:var(--text); }
        .date-val.accent { color:var(--green-dk); }
        .date-val.highlight { font-size:16px;color:var(--green-dk); }

        .gift-chip { display:inline-flex;align-items:center;gap:4px;font-size:12px;background:var(--amber);color:var(--amber-txt);padding:4px 10px;border-radius:20px;margin:3px; }

        .check-card { background:#fff;border-radius:var(--radius-lg);border:0.5px solid var(--gray-bd);overflow:hidden; }
        .check-item { display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:0.5px solid var(--gray-bd);cursor:pointer; }
        .check-item:last-child { border-bottom:none; }
        .chk-box { width:22px;height:22px;border-radius:5px;border:1.5px solid var(--gray-bd2);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .15s; }
        .chk-box.on { background:var(--green);border-color:var(--green);color:#fff; }
        .chk-txt { font-size:13px;color:var(--text); }
        .chk-sub { font-size:11px;color:var(--text-sec);margin-top:1px; }

        .warn-bar { background:var(--amber);border-radius:var(--radius-md);padding:10px 14px;display:flex;gap:8px;font-size:12px;color:var(--amber-txt);align-items:flex-start; }

        .bottom-bar { position:sticky;bottom:0;background:#fff;border-top:0.5px solid var(--gray-bd);padding:12px 16px;display:flex;align-items:center;gap:10px; }
        .btn-back { flex:1;padding:12px;border:0.5px solid var(--gray-bd2);border-radius:var(--radius-md);background:none;font-size:14px;cursor:pointer;color:var(--text-sec);font-family:inherit; }
        .btn-next { flex:2;padding:12px;background:var(--green);color:#fff;border:none;border-radius:var(--radius-md);font-size:14px;font-weight:500;cursor:pointer;font-family:inherit;display:flex;align-items:center;justify-content:center;gap:6px;transition:opacity .2s; }
        .btn-next:disabled { opacity:.35;cursor:not-allowed; }
    </style>
</head>
<body>

<div class="topbar">
    <i class="ti ti-file-check" style="font-size:20px;color:var(--green)"></i>
    <div class="topbar-title">申請書確認</div>
    <span class="status-pill" id="status-pill">待確認</span>
</div>

<div class="content">

    <div class="warn-bar">
        <i class="ti ti-alert-triangle"></i>
        <span>請仔細核對以下所有資料後再送出,送出後將無法修改</span>
    </div>

    <!-- 申請人 -->
    <div class="card">
        <div class="card-hdr"><i class="ti ti-user"></i><span class="card-hdr-txt">申請人資料</span></div>
        <div class="row"><div class="lbl">用戶編號</div><div class="val mono"><?= htmlspecialchars($d['user_id']) ?></div></div>
        <div class="row"><div class="lbl">社區</div><div class="val"><?= htmlspecialchars($d['member']) ?></div></div>
        <div class="row"><div class="lbl">姓名</div><div class="val"><?= htmlspecialchars($d['applicant_name']) ?></div></div>
        <div class="row"><div class="lbl">證件號碼</div><div class="val mono"><?= htmlspecialchars($d['applicant_usernumber']) ?></div></div>
        <div class="row"><div class="lbl">行動電話</div><div class="val"><?= htmlspecialchars($d['applicant_phone']) ?></div></div>
        <div class="row"><div class="lbl">住宅電話</div><div class="val"><?= htmlspecialchars($d['applicant_homenumber'] ?: '—') ?></div></div>
        <div class="row"><div class="lbl">裝機地址</div><div class="val"><?= htmlspecialchars($d['memberaddress'].$d['useraddress']) ?></div></div>
        <div class="row"><div class="lbl">電子信箱</div><div class="val" style="font-size:13px"><?= htmlspecialchars($d['applicant_email']) ?></div></div>
        <div class="row"><div class="lbl">申請速率</div><div class="val green"><?= htmlspecialchars($d['speed']) ?> Mbps</div></div>
        <div class="row"><div class="lbl">連接據點</div><div class="val mono"><?= htmlspecialchars($d['basenumber']) ?></div></div>
        <div class="row"><div class="lbl">PPPoE<br>帳號</div><div class="val mono"><?= htmlspecialchars($d['pppoeid']) ?></div></div>
        <div class="row"><div class="lbl">PPPoE<br>密碼</div><div class="val mono"><?= htmlspecialchars($d['pppoepw']) ?></div></div>
        <?php if (!empty($d['fistcount'])): ?>
        <div class="row"><div class="lbl">首裝優惠</div><div class="val" style="font-size:12px;color:var(--text-sec)"><?= nl2br(htmlspecialchars($d['fistcount'])) ?></div></div>
        <?php endif; ?>
    </div>

    <!-- 設備 -->
    <div class="card">
        <div class="card-hdr"><i class="ti ti-server"></i><span class="card-hdr-txt">設備資訊</span></div>
        <div class="row">
            <div class="lbl">資訊箱<br>設備</div>
            <div class="val">
                <?php if (empty($infoList)): ?>
                    <span style="color:var(--text-tert)">—</span>
                <?php else: foreach ($infoList as $item): ?>
                    <span class="device-chip"><i class="ti ti-check" style="font-size:11px"></i><?= htmlspecialchars($item['device']) ?><?= ($item['device']==='無'||$item['device']==='UY')?'':' ×'.htmlspecialchars($item['qty']) ?></span>
                <?php endforeach; endif; ?>
            </div>
        </div>
        <div class="row">
            <div class="lbl">網路<br>設備</div>
            <div class="val">
                <?php if (empty($routerList)): ?>
                    <span style="color:var(--text-tert)">—</span>
                <?php else: foreach ($routerList as $item): ?>
                    <span class="device-chip"><?= htmlspecialchars($item['device']) ?><?= $item['device']==='單機'?'':' ×'.htmlspecialchars($item['qty']) ?><?= ($item['tvBrand']==='or'&&!empty($item['tvOther']))?' ('.htmlspecialchars($item['tvOther']).')':'' ?></span>
                <?php endforeach; endif; ?>
            </div>
        </div>
        <?php
        // 只顯示真正的使用設備(use_devices 欄位),不包含 info/router
        $useOnlyList = json_decode($d['use_devices'] ?? '[]', true) ?: [];
        $purposeMap  = ['gift'=>'贈品','borrow'=>'借用','node'=>'據點'];
        if (!empty($useOnlyList)): ?>
        <div class="row">
            <div class="lbl">使用<br>設備</div>
            <div class="val" style="padding-top:8px">
                <?php foreach ($useOnlyList as $item):
                    $purpose = $purposeMap[$item['purpose'] ?? ''] ?? '';
                    $dp      = (int)($item['dp'] ?? 0);
                    $sn      = $item['sn'] ?? '';
                    $nodePos = $item['nodePos'] ?? '';
                ?>
                <div style="margin-bottom:8px">
                    <span class="device-chip" style="background:#FAEEDA;color:#633806"><?= htmlspecialchars($purpose) ?></span>
                    <span class="device-chip gray"><?= htmlspecialchars($item['device']) ?></span>
                    <div style="font-size:11px;color:var(--text-sec);margin-top:3px;margin-left:2px">
                        料號:<?= htmlspecialchars($sn ?: '—') ?>
                        <?php if (($item['purpose']??'') === 'borrow' && $dp > 0): ?>
                             押金:$<?= number_format($dp) ?>
                        <?php endif; ?>
                        <?php if (($item['purpose']??'') === 'node' && $nodePos !== ''): ?>
                             據點編號:<?= htmlspecialchars($nodePos) ?>
                        <?php endif; ?>
                    </div>
                </div>
                <?php endforeach; ?>
            </div>
        </div>
        <?php endif; ?>
    </div>

    <!-- 費用 -->
    <?php
    $isSubsc    = ($d['fee_type'] === 'subscription');
    $totalFeeInt= (int)$d['total_fee'];
    $showDash   = $isSubsc && empty($extraList); // 定期定額且無加購項目時總計顯示 ----
    ?>
    <div class="card">
        <div class="card-hdr"><i class="ti ti-receipt"></i><span class="card-hdr-txt">收費明細</span></div>
        <?php if ($isSubsc): ?>
        <!-- 定期定額:顯示信用卡繳費說明,不顯示 $0 -->
        <div class="fee-row">
            <div class="fee-name">網路費用<span style="font-size:11px;color:var(--text-tert);margin-left:6px"><?= htmlspecialchars($feeLabel) ?></span></div>
            <div class="fee-amt" style="color:var(--green-dk);font-size:13px">信用卡定期定額繳費</div>
        </div>
        <?php else: ?>
        <div class="fee-row">
            <div class="fee-name">網路費用<span style="font-size:11px;color:var(--text-tert);margin-left:6px"><?= htmlspecialchars($feeLabel) ?></span></div>
            <div class="fee-amt">$<?= number_format((int)$d['fee_amount']) ?></div>
        </div>
        <?php endif; ?>
        <?php foreach ($extraList as $ex): ?>
        <div class="fee-row">
            <div class="fee-name">
                <?= htmlspecialchars($ex['type']) ?>
                <?php if ($ex['type']==='周邊設備' && !empty($ex['sn'])): ?>
                <span style="font-size:11px;color:var(--text-tert);margin-left:6px">料號 <?= htmlspecialchars($ex['sn']) ?></span>
                <?php endif; ?>
            </div>
            <div class="fee-amt">$<?= number_format((int)$ex['amt']) ?></div>
        </div>
        <?php endforeach; ?>
        <div style="border-top:0.5px solid var(--gray-bd)">
            <div class="total-row">
                <span class="total-lbl">應繳費用總計</span>
                <?php if ($showDash): ?>
                <span class="total-amt" style="color:var(--text-tert);font-size:20px;letter-spacing:0">—</span>
                <?php else: ?>
                <span class="total-amt">$<?= number_format($totalFeeInt) ?></span>
                <?php endif; ?>
            </div>
        </div>
        <?php if ((int)$d['deposit_total'] > 0): ?>
        <div class="deposit-row">
            <span style="color:var(--text-sec)">使用設備押金</span>
            <span style="color:#BA7517;font-weight:500">$<?= number_format((int)$d['deposit_total']) ?></span>
        </div>
        <?php endif; ?>
    </div>

    <!-- 日期 -->
    <div class="card">
        <div class="card-hdr"><i class="ti ti-calendar"></i><span class="card-hdr-txt">日期資訊</span></div>
        <div class="date-row"><span class="date-lbl">裝機日</span><span class="date-val"><?= fmtDate($d['install_date']) ?></span></div>
        <div class="date-row"><span class="date-lbl">起租日</span><span class="date-val accent"><?= fmtDate($d['rental_start_date']) ?></span></div>
        <div class="date-row"><span class="date-lbl">到期日</span><span class="date-val accent"><?= fmtDate($d['rental_end_date']) ?></span></div>
        <?php if (!empty($giftList)): ?>
        <div class="date-row" style="flex-wrap:wrap">
            <div style="width:100%;font-size:13px;color:var(--text-sec);margin-bottom:4px">贈送月份</div>
            <div style="width:100%">
                <?php foreach ($giftList as $g):
                    $reason = $g['reason'] ?? '';
                    $extra  = '';
                    if ($reason === '住戶介紹' && !empty($g['intro'])) {
                        $extra = '(介紹:'.htmlspecialchars($g['intro']).')';
                    } elseif ($reason === '他網轉入' && !empty($g['network'])) {
                        $extra = '('.htmlspecialchars($g['network']).')';
                    }
                ?>
                <span class="gift-chip">
                    <i class="ti ti-gift" style="font-size:11px"></i>
                    <?= htmlspecialchars($reason) ?><?= $extra ?> <?= htmlspecialchars($g['months']) ?>月
                </span>
                <?php endforeach; ?>
            </div>
        </div>
        <div class="date-row" style="background:var(--green-lt)">
            <span class="date-lbl" style="font-weight:500;color:var(--green-deep)">含贈送後到期</span>
            <span class="date-val highlight"><?= fmtDate($d['real_end_date'] ?: $d['rental_end_date']) ?></span>
        </div>
        <?php endif; ?>
    </div>

    <!-- 核對確認 -->
    <div class="check-card">
        <div class="check-item" onclick="toggleCheck(this)">
            <div class="chk-box"><i class="ti ti-check" style="font-size:13px"></i></div>
            <div><div class="chk-txt">申請人資料已核對正確</div><div class="chk-sub">姓名、證件、地址、聯絡方式</div></div>
        </div>
        <div class="check-item" onclick="toggleCheck(this)">
            <div class="chk-box"><i class="ti ti-check" style="font-size:13px"></i></div>
            <div><div class="chk-txt">設備資訊已核對正確</div><div class="chk-sub">資訊箱、網路設備、使用設備</div></div>
        </div>
        <div class="check-item" onclick="toggleCheck(this)">
            <div class="chk-box"><i class="ti ti-check" style="font-size:13px"></i></div>
            <div><div class="chk-txt">費用與日期已核對正確</div><div class="chk-sub">總金額、裝機日、到期日</div></div>
        </div>
    </div>

    <!-- 工程師簽收(全部勾選後才顯示)-->
    <?php
    // enname 取得優先序:1. 本次 POST  2. form_enname Session  3. 空字串
    $enname = '';
    if (!empty($_POST['enname'])) {
        $enname = trim($_POST['enname']);
    } elseif (!empty($_SESSION['form_enname'])) {
        $enname = $_SESSION['form_enname'];
    } elseif (!empty($d['enname'])) {
        $enname = $d['enname'];
    }
    // 存回 preview session 確保後續頁面可讀取
    $_SESSION['preview']['enname'] = $enname;
    // DEBUG:HTML 註解中顯示取得結果(上線後可移除)
    echo '<!-- DEBUG enname=['.htmlspecialchars($enname).'] POST=['.htmlspecialchars($_POST['enname']??'').'] SESS=['.htmlspecialchars($_SESSION['form_enname']??'').'] -->';
    ?>
    <div id="engineer-confirm-card" style="display:none">
        <div class="card" style="border-color:var(--green);background:var(--green-lt)">
            <div style="padding:14px 16px;display:flex;align-items:center;gap:12px">
                <div style="width:40px;height:40px;border-radius:50%;background:var(--green);display:flex;align-items:center;justify-content:center;flex-shrink:0">
                    <i class="ti ti-user-check" style="font-size:20px;color:#fff"></i>
                </div>
                <div>
                    <div style="font-size:14px;font-weight:500;color:var(--green-deep)">工程師確認簽收</div>
                    <div style="font-size:13px;color:var(--green-dk);margin-top:2px">
                        施工工程師:<strong><?= htmlspecialchars($enname ?: '—') ?></strong>
                    </div>
                    <div style="font-size:11px;color:var(--green-dk);margin-top:2px">
                        已與客戶確認本日費用及收費,資料核對無誤
                    </div>
                    <div style="font-size:11px;color:var(--text-sec);margin-top:4px">
                        確認時間:<span id="confirm-time"></span>
                    </div>
                </div>
            </div>
        </div>
    </div>

</div>

<div class="bottom-bar">
    <button class="btn-back" onclick="goBack()"><i class="ti ti-arrow-left" style="font-size:14px"></i> 返回修改</button>
    <button class="btn-next" id="next-btn" disabled onclick="goConfirm()">
        下一步:簽名送出 <i class="ti ti-arrow-right" style="font-size:15px"></i>
    </button>
</div>

<script>
function toggleCheck(row) {
    const box = row.querySelector('.chk-box');
    box.classList.toggle('on');
    const allChecked = [...document.querySelectorAll('.chk-box')].every(b=>b.classList.contains('on'));
    const btn  = document.getElementById('next-btn');
    const pill = document.getElementById('status-pill');
    const engCard = document.getElementById('engineer-confirm-card');
    btn.disabled = !allChecked;
    if(allChecked){
        btn.innerHTML = '下一步:簽名送出 <i class="ti ti-arrow-right" style="font-size:15px"></i>';
        if(pill){ pill.textContent='已確認'; pill.style.background='var(--green-lt)'; pill.style.color='var(--green-deep)'; }
        if(engCard){
            engCard.style.display = 'block';
            document.getElementById('confirm-time').textContent = new Date().toLocaleString('zh-TW',{hour12:false});
            engCard.scrollIntoView({behavior:'smooth', block:'nearest'});
        }
    } else {
        btn.innerHTML = '請先完成核對 <i class="ti ti-lock" style="font-size:15px"></i>';
        if(pill){ pill.textContent='待確認'; pill.style.background='var(--amber)'; pill.style.color='var(--amber-txt)'; }
        if(engCard) engCard.style.display = 'none';
    }
}

function goBack() {
    // 把 PHP Session 的贈送月份完整寫回 JS sessionStorage
    const giftData = <?= json_encode($giftList) ?>;
    // 無論有沒有資料都寫入(空陣列也要覆蓋,避免 SS 殘留舊值)
    sessionStorage.setItem('ys_gifts', JSON.stringify(giftData || []));
    // 稍微延遲確保 sessionStorage 寫入完成再跳轉
    setTimeout(function(){
        window.location.href = 'form.php?from_preview=1';
    }, 50);
}

function goConfirm() {
    window.location.href = 'confirm.php';
}
</script>
</body>
</html>