<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<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;
}
* {
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;
}
}
</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="form-grid">
<div class="form-field">
<label class="form-label">退款原因</label>
<select id="reason">
<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 class="form-field">
<label class="form-label">联系邮箱</label>
<input id="email" type="email" placeholder="[email protected]" />
</div>
</div>
</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="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 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;
// 根据退款原因显示不同内容
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 {
// 隐藏降价退款信息
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);
}
// 处理图片上传
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>
index.html
style.css
index.js
md
项目介绍.md
index.html