退款取消订单页面第二版edit icon

创建者:
Kitty
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
md
项目介绍.md
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <title>退款取消订单</title>
    <style>
        :root {
            --bg: #fef8f8;
            --card-bg: #ffffff;
            --primary: #d32f2f;
            --primary-light: #ef5350;
            --primary-dark: #b71c1c;
            --accent: #ff5252;
            --text: #2c1818;
            --muted: #6e4b4b;
            --border: #f1d4d4;
            --shadow: rgba(211, 47, 47, 0.1);
            --success: #43a047;
            --warning: #ff9800;
            --radius-sm: 8px;
            --radius-md: 12px;
            --radius-lg: 16px;
            --primary-red: #d32f2f;
            --primary-red-light: #f44336;
            --primary-red-dark: #b71c1c;
            --primary-red-transparent: rgba(211, 47, 47, 0.08);
            --secondary-gold: #ffd700;
            --text-dark: #222222;
            --text-light: #666666;
            --text-lightest: #999999;
            --border-color: #eaeaea;
            --background-light: #fafafa;
            --background-white: #ffffff;
            --success-color: #2e7d32;
            --warning-color: #ff9800;
            --warning-bg: #fff3e0;
            --info-bg: #e3f2fd;
            --shadow-light: 0 2px 12px rgba(0, 0, 0, 0.04);
            --shadow-medium: 0 4px 20px rgba(0, 0, 0, 0.08);
            --shadow-heavy: 0 8px 30px rgba(0, 0, 0, 0.12);
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        html, body {
            height: 100%;
            margin: 0;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "PingFang SC", "Microsoft YaHei", sans-serif;
            color: var(--text);
            background: linear-gradient(135deg, #fff8f8 0%, #ffecec 100%);
            line-height: 1.5;
        }

        .app {
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 16px;
        }

        .card {
            width: 100%;
            max-width: 1000px;
            background: var(--card-bg);
            border-radius: var(--radius-lg);
            box-shadow: 0 10px 40px var(--shadow);
            overflow: hidden;
            border: 1px solid var(--border);
        }

        .card-header {
            background: linear-gradient(90deg, var(--primary) 0%, var(--primary-light) 100%);
            color: white;
            padding: 20px 24px;
        }

        .card-title {
            font-size: 22px;
            font-weight: 700;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .card-title-icon {
            width: 24px;
            height: 24px;
            fill: white;
        }

        .card-subtitle {
            font-size: 14px;
            opacity: 0.9;
            margin-top: 4px;
        }

        .card-body {
            padding: 24px;
        }

        .section {
            margin-bottom: 28px;
        }

        .section-title {
            font-size: 17px;
            font-weight: 600;
            margin-bottom: 16px;
            color: var(--primary-dark);
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .section-title::before {
            content: "";
            display: block;
            width: 4px;
            height: 16px;
            background-color: var(--primary);
            border-radius: 2px;
        }

        .policy-box {
            background: #fff9f9;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            padding: 16px;
            margin-bottom: 24px;
            font-size: 14px;
            line-height: 1.6;
            color: var(--muted);
        }

        .form-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 20px;
            margin-bottom: 24px;
        }

        @media (min-width: 768px) {
            .form-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        .form-field {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .form-label {
            font-size: 14px;
            font-weight: 500;
            color: var(--muted);
        }

        select, input, textarea {
            width: 100%;
            padding: 12px 16px;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            font-size: 15px;
            background: #fffefe;
            transition: all 0.2s ease;
            color: var(--text);
        }

        select:focus, input:focus, textarea:focus {
            outline: none;
            border-color: var(--accent);
            box-shadow: 0 0 0 3px rgba(255, 82, 82, 0.2);
        }

        textarea {
            min-height: 100px;
            resize: vertical;
        }

        .products-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 12px;
        }

        @media (min-width: 640px) {
            .products-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        .product-card {
            display: grid;
            grid-template-columns: auto 1fr auto;
            gap: 14px;
            align-items: center;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            padding: 14px;
            background: #fffefe;
            transition: all 0.2s ease;
        }

        .product-card:hover {
            border-color: var(--accent);
            box-shadow: 0 4px 12px var(--shadow);
        }

        .product-image {
            width: 70px;
            height: 70px;
            object-fit: cover;
            border-radius: var(--radius-sm);
            border: 1px solid var(--border);
        }

        .product-info {
            display: flex;
            flex-direction: column;
            gap: 6px;
        }

        .product-name {
            font-weight: 600;
            font-size: 15px;
        }

        .product-sku {
            font-size: 12px;
            color: var(--muted);
        }

        .product-controls {
            display: flex;
            align-items: center;
            gap: 10px;
            flex-wrap: wrap;
        }

        .product-price {
            font-weight: 700;
            color: var(--primary-dark);
            font-size: 16px;
            text-align: right;
        }

        .checkbox-label {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 14px;
            cursor: pointer;
        }

        .checkbox-label input[type="checkbox"] {
            width: 16px;
            height: 16px;
            accent-color: var(--primary);
        }

        .qty-input {
            width: 70px;
            padding: 6px 8px;
            text-align: center;
        }

        /* 金额汇总区域 */
        .amount-summary {
            background: #fff9f9;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            padding: 20px;
            margin-top: 24px;
        }

        .amount-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 0;
            border-bottom: 1px dashed var(--border);
        }

        .amount-row:last-child {
            border-bottom: none;
            padding-bottom: 0;
        }

        .amount-row.total-row {
            border-top: 2px solid var(--border);
            padding-top: 16px;
            margin-top: 8px;
        }

        .amount-label {
            font-size: 15px;
            color: var(--muted);
        }

        .amount-value {
            font-weight: 600;
            color: var(--text);
        }

        .total-amount {
            font-size: 24px;
            font-weight: 800;
            color: var(--primary-dark);
        }

        /* 附加费区域 */
        .fees-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 12px;
        }

        @media (min-width: 640px) {
            .fees-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        .fee-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 14px;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            background: #fffefe;
        }

        .fee-info {
            display: flex;
            flex-direction: column;
            gap: 4px;
        }

        .fee-name {
            font-weight: 500;
            font-size: 14px;
        }

        .fee-desc {
            font-size: 12px;
            color: var(--muted);
        }

        .fee-amount {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .fee-input {
            width: 100px;
            text-align: right;
        }

        /* 降价退款区域 */
        .price-drop-info {
            display: grid;
            grid-template-columns: 1fr;
            gap: 16px;
            background: #fff9f9;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            padding: 20px;
        }

        @media (min-width: 640px) {
            .price-drop-info {
                grid-template-columns: repeat(3, 1fr);
            }
        }

        .price-drop-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            text-align: center;
            gap: 8px;
            padding: 12px;
            background: white;
            border-radius: var(--radius-sm);
            border: 1px solid var(--border);
        }

        .price-drop-label {
            font-size: 14px;
            color: var(--muted);
        }

        .price-drop-value {
            font-weight: 700;
            font-size: 18px;
        }

        .price-drop-total {
            color: var(--primary-dark);
            font-size: 22px;
        }

        /* 图片上传区域 */
        .upload-area {
            border: 2px dashed var(--border);
            border-radius: var(--radius-md);
            padding: 20px;
            text-align: center;
            background: #fff9f9;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .upload-area:hover {
            border-color: var(--accent);
            background: #fff5f5;
        }

        .upload-icon {
            width: 48px;
            height: 48px;
            fill: var(--primary-light);
            margin-bottom: 12px;
        }

        .upload-text {
            font-size: 15px;
            color: var(--muted);
            margin-bottom: 8px;
        }

        .upload-hint {
            font-size: 13px;
            color: var(--muted);
        }

        .image-preview {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
            gap: 10px;
            margin-top: 16px;
        }

        .preview-image {
            width: 100%;
            height: 80px;
            object-fit: cover;
            border-radius: var(--radius-sm);
            border: 1px solid var(--border);
        }

        /* 按钮区域 */
        .action-buttons {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 32px;
            padding-top: 20px;
            border-top: 1px solid var(--border);
            flex-wrap: wrap;
            gap: 16px;
        }

        .btn {
            padding: 14px 28px;
            border-radius: var(--radius-md);
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
            border: none;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        .btn-primary {
            background: linear-gradient(90deg, var(--primary) 0%, var(--primary-light) 100%);
            color: white;
            box-shadow: 0 4px 12px rgba(211, 47, 47, 0.3);
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 16px rgba(211, 47, 47, 0.4);
        }

        .btn-primary:active {
            transform: translateY(0);
        }

        .btn-secondary {
            background: white;
            color: var(--text);
            border: 1px solid var(--border);
        }

        .btn-secondary:hover {
            background: #fff5f5;
            border-color: var(--accent);
        }

        .btn-icon {
            width: 18px;
            height: 18px;
        }

        .footer-note {
            font-size: 13px;
            color: var(--muted);
        }

        /* 隐藏元素 */
        .hidden {
            display: none !important;
        }

        .disabled {
            opacity: 0.6;
            pointer-events: none;
        }

        /* 状态指示器 */
        .status-badge {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 6px 12px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 500;
            background: rgba(211, 47, 47, 0.1);
            color: var(--primary-dark);
            border: 1px solid rgba(211, 47, 47, 0.2);
        }

        /* 响应式调整 */
        @media (max-width: 640px) {
            .card-body {
                padding: 16px;
            }

            .btn {
                padding: 12px 20px;
                width: 100%;
            }

            .action-buttons {
                flex-direction: column;
                align-items: stretch;
            }

            .product-controls {
                flex-direction: column;
                align-items: flex-start;
            }
        }
        .select-wrapper {
            position: relative;
        }

        .custom-select {
            width: 100%;
            padding: 16px 20px;
            /*border: 2px solid var(--border-color);*/
            border-radius: 12px;
            font-size: 16px;
            background-color: var(--background-white);
            cursor: pointer;
            appearance: none;
            transition: all 0.3s ease;
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23d32f2f' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
            background-repeat: no-repeat;
            background-position: right 20px center;
            background-size: 16px;
            font-weight: 500;
        }

        .custom-select:focus {
            border-color: var(--primary-red);
            outline: none;
            box-shadow: 0 0 0 4px var(--primary-red-transparent);
        }

        /* 动态显示的区域 */
        .dynamic-content {
            margin-top: -20px;
            padding: 24px;
            background-color: var(--background-light);
            border-radius: 12px;
            border: 1px solid var(--border-color);
            transition: all 0.3s ease;
        }

        .fee-options {
            display: flex;
            flex-direction: column;
            gap: 16px;
        }

        .fee-option {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 16px;
            background-color: white;
            border-radius: 10px;
            border: 1px solid var(--border-color);
            transition: all 0.3s ease;
            cursor: pointer;
        }

        .fee-option:hover {
            border-color: var(--primary-red);
            box-shadow: 0 4px 12px rgba(211, 47, 47, 0.1);
        }

        .fee-option.selected {
            border-color: var(--primary-red);
            background-color: var(--primary-red-transparent);
        }

        .fee-checkbox {
            width: 24px;
            height: 24px;
            border-radius: 6px;
            border: 2px solid var(--border-color);
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
            flex-shrink: 0;
        }

        .fee-option.selected .fee-checkbox {
            background-color: var(--primary-red);
            border-color: var(--primary-red);
        }

        .fee-checkbox i {
            color: white;
            font-size: 14px;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .fee-option.selected .fee-checkbox i {
            opacity: 1;
        }

        .fee-details {
            flex: 1;
            margin-left: 16px;
        }

        .fee-name {
            font-size: 16px;
            font-weight: 600;
            color: var(--text-dark);
            margin-bottom: 4px;
        }

        .fee-description {
            font-size: 14px;
            color: var(--text-light);
        }

        .fee-amount {
            font-size: 18px;
            font-weight: 700;
            color: var(--primary-red);
            margin-left: 16px;
        }
    </style>
</head>
<body>
<div class="app">
    <div class="card">
        <div class="card-header">
            <div class="card-title">
                <svg class="card-title-icon" viewBox="0 0 24 24">
                    <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" />
                </svg>
                退款取消订单
            </div>
            <div class="card-subtitle">请填写退款信息并提交申请,我们将在1-3个工作日内处理</div>
        </div>

        <div class="card-body">
            <!-- 退款政策提醒 -->
            <div class="policy-box">
                <strong>重要提示:</strong> 对于定制个性化产品,一旦开始生产,可能无法更改或取消。这包括根据订单中的规格定制的专业设计、成型和造型。如果您需要在生产过程中取消或修改订单,则定制费(也称为补货费)将收取,来抵消已产生的费用。
            </div>

            <!-- 退款原因 -->
            <div class="section" >
                <div class="section-title">退款原因</div>
                <div class="select-wrapper">
                    <select  id="reason" class="custom-select" id="refundReason" name="refundReason" required>
                        <option value="">请选择退款原因</option>
                        <option value="vip_insurance">取消VIP/运费保险</option>
                        <option value="price_drop">购买后降价</option>
                        <option value="delay">生产或交期延误</option>
                        <option value="wrong_info">订单信息错误(尺码/颜色/数量)</option>
                        <option value="quality">品质问题 / 与描述不符</option>
                        <option value="other">其他原因</option>
                    </select>
                </div>
            </div>
            <!-- 动态内容区域 -->
            <div id="dynamicContent" class="dynamic-content" style="display: none;margin-bottom: 28px" >
                <!-- 这里会根据选择的退款原因动态显示内容 -->
            </div>
            <!-- 产品明细 -->
            <div class="section">
                <div class="section-title">产品明细</div>
                <div id="products" class="products-grid"></div>
            </div>

            <!-- 附加费区域(仅显示当选择VIP/运费保险时) -->
            <div id="fee-section" class="section hidden">
                <div class="section-title">附加费用</div>
                <div class="fees-grid">
                    <div class="fee-item">
                        <div class="fee-info">
                            <div class="fee-name">VIP费用</div>
                            <div class="fee-desc">会员专享服务</div>
                        </div>
                        <div class="fee-amount">
                            <label class="checkbox-label">
                                <input type="checkbox" class="fee-check" data-key="vip" checked /> 退款
                            </label>
                            <input type="number" class="fee-input" data-key="vip" value="19.99" min="0" step="0.01" />
                        </div>
                    </div>

                    <div class="fee-item">
                        <div class="fee-info">
                            <div class="fee-name">运费保险</div>
                            <div class="fee-desc">物流运输保障</div>
                        </div>
                        <div class="fee-amount">
                            <label class="checkbox-label">
                                <input type="checkbox" class="fee-check" data-key="insurance" checked /> 退款
                            </label>
                            <input type="number" class="fee-input" data-key="insurance" value="5.00" min="0" step="0.01" />
                        </div>
                    </div>

                    <div class="fee-item">
                        <div class="fee-info">
                            <div class="fee-name">保修费用</div>
                            <div class="fee-desc">延长保修服务</div>
                        </div>
                        <div class="fee-amount">
                            <label class="checkbox-label">
                                <input type="checkbox" class="fee-check" data-key="warranty" /> 退款
                            </label>
                            <input type="number" class="fee-input" data-key="warranty" value="9.99" min="0" step="0.01" />
                        </div>
                    </div>

                    <div class="fee-item">
                        <div class="fee-info">
                            <div class="fee-name">服务费</div>
                            <div class="fee-desc">人工客服服务</div>
                        </div>
                        <div class="fee-amount">
                            <label class="checkbox-label">
                                <input type="checkbox" class="fee-check" data-key="service" /> 退款
                            </label>
                            <input type="number" class="fee-input" data-key="service" value="3.00" min="0" step="0.01" />
                        </div>
                    </div>
                </div>
            </div>

            <!-- 降价退款信息(仅显示当选择降价时) -->
            <div id="price-drop" class="section hidden">
                <div class="section-title">降价退款详情</div>
                <div class="price-drop-info">
                    <div class="price-drop-item">
                        <div class="price-drop-label">原始订单金额</div>
                        <div class="price-drop-value">¥<span id="pd-original">42.91</span></div>
                    </div>

                    <div class="price-drop-item">
                        <div class="price-drop-label">定制费用</div>
                        <div class="price-drop-value">¥<span id="pd-custom">8.99</span></div>
                    </div>

                    <div class="price-drop-item">
                        <div class="price-drop-label">退款总额</div>
                        <div class="price-drop-value price-drop-total">¥<span id="pd-refund">33.92</span></div>
                    </div>
                </div>
            </div>

            <!-- 金额汇总区域 -->
            <div class="section">
                <div class="section-title">金额明细</div>
                <div class="amount-summary">
                    <div class="amount-row">
                        <span class="amount-label">商品合计</span>
                        <span class="amount-value">¥<span id="subtotal">0.00</span></span>
                    </div>

                    <div class="amount-row">
                        <span class="amount-label">附加费退款</span>
                        <span class="amount-value">¥<span id="fee-total">0.00</span></span>
                    </div>

                    <div class="amount-row">
                        <span class="amount-label">运费退款</span>
                        <span class="amount-value">¥<span id="shipping-refund">0.00</span></span>
                    </div>

                    <div class="amount-row total-row">
                        <span class="amount-label">退款总金额</span>
                        <span class="amount-value total-amount">¥<span id="total">0.00</span></span>
                    </div>
                </div>
            </div>

            <!-- 取消说明 -->
            <div class="section">
                <div class="section-title">取消说明</div>
                <div class="form-field">
                    <label class="form-label">备注说明</label>
                    <textarea id="note" placeholder="请补充取消和退款的原因或细节,以便我们更好地处理您的申请..."></textarea>
                </div>

                <div class="form-field">
                    <label class="form-label">上传凭证(最多6张)</label>
                    <div class="upload-area" id="upload-area">
                        <svg class="upload-icon" viewBox="0 0 24 24">
                            <path d="M14,13V17H10V13H7L12,8L17,13M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z" />
                        </svg>
                        <div class="upload-text">点击或拖拽上传图片</div>
                        <div class="upload-hint">支持 JPG、PNG 格式,每张不超过5MB</div>
                        <input id="images" type="file" accept="image/*" multiple class="hidden" />
                    </div>
                    <div id="thumbs" class="image-preview"></div>
                </div>
            </div>
            <!-- 联系邮箱 -->
            <div class="section">
                <div class="section-title">联系邮箱</div>
                <div >
                    <input id="email" type="email" placeholder="[email protected]" />
                </div>
            </div>
            <!-- 操作按钮 -->
            <div class="action-buttons">
                <div class="footer-note">
                    <span class="status-badge">演示版本</span> 本页面为前端示例,不会提交到服务器
                </div>

                <div style="display: flex; gap: 12px; flex-wrap: wrap;">
                    <button id="submit-btn" class="btn btn-primary">
                        <svg class="btn-icon" viewBox="0 0 24 24">
                            <path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" fill="white"/>
                        </svg>
                        提交申请
                    </button>
                    <button id="cancel-btn" class="btn btn-secondary">
                        <svg class="btn-icon" viewBox="0 0 24 24">
                            <path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="currentColor"/>
                        </svg>
                        取消
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    // 示例产品数据
    const productsData = [
        { id: 'p1', name: '定制T恤(白色)', sku: 'TS-001-W', price: 129.00, img: 'https://picsum.photos/seed/t1/200/200' },
        { id: 'p2', name: '定制帽子(红色)', sku: 'CP-207-R', price: 89.00, img: 'https://picsum.photos/seed/cp/200/200' },
        { id: 'p3', name: 'LOGO贴纸包', sku: 'ST-511-M', price: 39.00, img: 'https://picsum.photos/seed/st/200/200' },
        { id: 'p4', name: '限定托特包', sku: 'TB-888-K', price: 159.00, img: 'https://picsum.photos/seed/tb/200/200' }
    ];
    const dynamicContent = document.getElementById('dynamicContent');
    const openUploadModalBtn = document.getElementById('openUploadModal');
    const uploadModal = document.getElementById('uploadModal');
    const closeUploadModalBtn = document.getElementById('closeUploadModal');
    const cancelUploadBtn = document.getElementById('cancelUploadBtn');
    const confirmUploadBtn = document.getElementById('confirmUploadBtn');
    const fileUploadArea = document.getElementById('fileUploadArea');
    const fileUploadInput = document.getElementById('fileUpload');
    const uploadPreview = document.getElementById('uploadPreview');
    const attachmentsPreview = document.getElementById('attachmentsPreview');
    const els = {
        reason: document.getElementById('reason'),
        email: document.getElementById('email'),
        products: document.getElementById('products'),
        subtotal: document.getElementById('subtotal'),
        feeTotal: document.getElementById('fee-total'),
        shippingRefund: document.getElementById('shipping-refund'),
        total: document.getElementById('total'),
        feeSection: document.getElementById('fee-section'),
        priceDrop: document.getElementById('price-drop'),
        note: document.getElementById('note'),
        images: document.getElementById('images'),
        thumbs: document.getElementById('thumbs'),
        uploadArea: document.getElementById('upload-area'),
        submitBtn: document.getElementById('submit-btn'),
        cancelBtn: document.getElementById('cancel-btn')
    };

    // 初始化页面
    function init() {
        renderProducts();
        bindEvents();
        calcTotals();

        // 设置默认邮箱
        els.email.value = '[email protected]';

        // 设置默认原因
        els.reason.value = 'price_drop';
        els.reason.dispatchEvent(new Event('change'));
    }

    // 渲染产品列表
    function renderProducts() {
        els.products.innerHTML = '';
        productsData.forEach(p => {
            const row = document.createElement('div');
            row.className = 'product-card';
            row.innerHTML = `
          <img src="${p.img}" alt="${p.name}" class="product-image" />
          <div class="product-info">
            <div class="product-name">${p.name}</div>
            <div class="product-sku">货号:${p.sku}</div>
            <div class="product-controls">
              <label class="checkbox-label">
                <input type="checkbox" class="pick" data-id="${p.id}" checked /> 申请退款
              </label>
              <div style="display: flex; align-items: center; gap: 6px;">
                <span style="font-size: 14px; color: var(--muted);">数量</span>
                <input type="number" class="qty-input" data-id="${p.id}" value="1" min="1" class="qty-input" />
              </div>
            </div>
          </div>
          <div class="product-price">¥${p.price.toFixed(2)}</div>
        `;
            els.products.appendChild(row);
        });
    }

    // 计算商品小计
    function getProductsSubtotal() {
        let sum = 0;
        const picks = Array.from(document.querySelectorAll('.pick'));
        picks.forEach(chk => {
            const id = chk.getAttribute('data-id');
            const prod = productsData.find(x => x.id === id);
            const qtyEl = document.querySelector('.qty-input[data-id="' + id + '"]');
            const qty = Math.max(1, parseInt(qtyEl.value || '1', 10));
            if (chk.checked) sum += prod.price * qty;
        });
        return sum;
    }

    // 计算附加费总额
    function getFeesTotal() {
        let sum = 0;
        const checks = Array.from(document.querySelectorAll('.fee-check'));
        checks.forEach(chk => {
            const key = chk.getAttribute('data-key');
            const input = document.querySelector('.fee-input[data-key="' + key + '"]');
            const val = parseFloat(input.value);
            if (chk.checked && !isNaN(val) && val > 0) sum += val;
        });
        return sum;
    }

    // 计算运费退款(模拟)
    function getShippingRefund() {
        const subtotal = getProductsSubtotal();
        // 假设订单满200免运费,否则收取15元运费
        return subtotal >= 200 ? 15.00 : 0.00;
    }

    // 计算总额并更新显示
    function calcTotals() {
        const reason = els.reason.value;
        const subtotal = getProductsSubtotal();
        const shippingRefund = getShippingRefund();

        let feeTotal = 0;
        let total = 0;
        dynamicContent.style.display = 'none';
        // 根据退款原因显示不同内容
        if (reason === 'price_drop') {
            // 显示降价退款信息
            els.priceDrop.classList.remove('hidden');
            els.feeSection.classList.add('hidden');

            // 禁用产品选择
            els.products.classList.add('disabled');
            document.querySelectorAll('.pick, .qty-input').forEach(el => el.disabled = true);

            // 显示固定退款金额
            total = 33.92;
            els.subtotal.textContent = '0.00';
            els.feeTotal.textContent = '0.00';
            els.shippingRefund.textContent = '0.00';
        }else {
            dynamicContent.style.display = 'block';

            // 清空动态内容
            dynamicContent.innerHTML = '';
            //显示退款提示
            showDefaultRefundInfo();
            // 隐藏降价退款信息
            els.priceDrop.classList.add('hidden');
            els.products.classList.remove('disabled');
            document.querySelectorAll('.pick, .qty-input').forEach(el => el.disabled = false);

            // 根据原因显示附加费区域
            if (reason === 'vip_insurance') {
                els.feeSection.classList.remove('hidden');
                feeTotal = getFeesTotal();
            } else {
                els.feeSection.classList.add('hidden');
            }

            // 计算总额
            total = subtotal + feeTotal + shippingRefund;
            els.subtotal.textContent = subtotal.toFixed(2);
            els.feeTotal.textContent = feeTotal.toFixed(2);
            els.shippingRefund.textContent = shippingRefund.toFixed(2);

        }

        // 更新总金额
        els.total.textContent = total.toFixed(2);
        dynamicContent.classList.add('slide-in');
        setTimeout(() => {
            dynamicContent.classList.remove('slide-in');
        }, 300);
    }
    // 显示默认退款信息
    function showDefaultRefundInfo() {
        const content = `
                <div class="default-refund-info">
                    <p style="font-size: 15px; color: var(--text-dark); line-height: 1.6; margin-bottom: 16px;">
                        Please note that refunds may take 5-10 business days to process after approval. Customization fees may apply for personalized products.
                    </p>
                    <div style="display: flex; align-items: center; gap: 10px; padding: 12px; background-color: rgba(0, 0, 0, 0.03); border-radius: 8px;">
                        <i class="fas fa-info-circle" style="color: var(--primary-red);"></i>
                        <span style="font-size: 14px; color: var(--text-light);">You can select specific products for refund above.</span>
                    </div>
                </div>
            `;

        dynamicContent.innerHTML = content;
    }
    // 处理图片上传
    function handleImages() {
        const files = Array.from(els.images.files || []).slice(0, 6);
        els.thumbs.innerHTML = '';

        if (files.length === 0) return;

        files.forEach(f => {
            const reader = new FileReader();
            reader.onload = function(e) {
                const img = document.createElement('img');
                img.src = e.target.result;
                img.className = 'preview-image';
                img.alt = f.name;
                els.thumbs.appendChild(img);
            };
            reader.readAsDataURL(f);
        });
    }

    // 验证表单
    function validate() {
        const reason = (els.reason.value || '').trim();
        const email = (els.email.value || '').trim();
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        const anyPicked = Array.from(document.querySelectorAll('.pick')).some(el => el.checked);

        if (!reason) {
            alert('请选择退款原因');
            els.reason.focus();
            return false;
        }

        if (!email || !emailRegex.test(email)) {
            alert('请输入有效的邮箱地址');
            els.email.focus();
            return false;
        }

        if (reason !== 'price_drop' && !anyPicked) {
            alert('请至少选择一个产品进行退款');
            return false;
        }

        return true;
    }

    // 提交表单
    function submit() {
        if (!validate()) return;

        const reason = els.reason.value;
        const payload = {
            reason,
            email: els.email.value,
            note: els.note.value,
            items: [],
            fees: {},
            totals: {
                subtotal: parseFloat(els.subtotal.textContent),
                feeTotal: parseFloat(els.feeTotal.textContent),
                shippingRefund: parseFloat(els.shippingRefund.textContent),
                total: parseFloat(els.total.textContent)
            }
        };

        if (reason === 'price_drop') {
            payload.priceDrop = {
                original: 42.91,
                custom: 8.99,
                refund: 33.92
            };
        } else {
            payload.items = Array.from(document.querySelectorAll('.pick'))
                .filter(el => el.checked)
                .map(el => {
                    const id = el.getAttribute('data-id');
                    const prod = productsData.find(x => x.id === id);
                    const qtyEl = document.querySelector('.qty-input[data-id="' + id + '"]');
                    const qty = Math.max(1, parseInt(qtyEl.value || '1', 10));
                    return {
                        id,
                        name: prod.name,
                        sku: prod.sku,
                        price: prod.price,
                        qty,
                        total: prod.price * qty
                    };
                });

            if (reason === 'vip_insurance') {
                Array.from(document.querySelectorAll('.fee-check')).forEach(chk => {
                    const key = chk.getAttribute('data-key');
                    const val = parseFloat(document.querySelector('.fee-input[data-key="' + key + '"]').value);
                    payload.fees[key] = {
                        checked: chk.checked,
                        amount: isNaN(val) ? 0 : val
                    };
                });
            }
        }

        // 在实际应用中,这里应该发送数据到服务器
        console.log('提交退款申请:', payload);

        // 显示成功提示
        alert('退款申请已提交成功!我们将在1-3个工作日内处理您的申请。\n\n(演示版本,数据不会实际提交)');

        // 重置表单
        setTimeout(() => {
            els.note.value = '';
            els.images.value = '';
            els.thumbs.innerHTML = '';
        }, 100);
    }

    // 取消操作
    function cancelPage() {
        if (confirm('确定要离开此页面吗?您填写的信息将不会被保存。')) {
            // 在实际应用中,这里应该返回上一页或关闭页面
            console.log('用户取消操作');
            // 模拟返回上一页
            window.history.back();
        }
    }

    // 绑定事件
    function bindEvents() {
        // 监听所有输入变化
        document.addEventListener('input', (e) => {
            if (
                e.target.classList.contains('pick') ||
                e.target.classList.contains('qty-input') ||
                e.target.classList.contains('fee-input') ||
                e.target.classList.contains('fee-check')
            ) {
                calcTotals();
            }
        });

        // 监听选择变化
        document.addEventListener('change', (e) => {
            if (
                e.target === els.reason ||
                e.target.classList.contains('pick') ||
                e.target.classList.contains('fee-check')
            ) {
                calcTotals();
            }
        });

        // 监听退款原因变化
        els.reason.addEventListener('change', calcTotals);

        // 图片上传事件
        els.uploadArea.addEventListener('click', () => els.images.click());
        els.uploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            els.uploadArea.style.borderColor = 'var(--accent)';
            els.uploadArea.style.background = '#fff5f5';
        });
        els.uploadArea.addEventListener('dragleave', () => {
            els.uploadArea.style.borderColor = 'var(--border)';
            els.uploadArea.style.background = '#fff9f9';
        });
        els.uploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            els.uploadArea.style.borderColor = 'var(--border)';
            els.uploadArea.style.background = '#fff9f9';
            els.images.files = e.dataTransfer.files;
            handleImages();
        });
        els.images.addEventListener('change', handleImages);

        // 按钮事件
        els.submitBtn.addEventListener('click', submit);
        els.cancelBtn.addEventListener('click', cancelPage);
    }

    // 页面加载完成后初始化
    document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>
        
编辑器加载中
预览
控制台