feat:项目完成

This commit is contained in:
2025-06-17 19:55:10 +08:00
commit e166ec615b
21 changed files with 1548 additions and 0 deletions

187
templates/order_detail.html Normal file
View File

@@ -0,0 +1,187 @@
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>订单详情 - 订单管理后台</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { background: #f4f6fb; font-family: 'Poppins', 'Microsoft YaHei', Arial, sans-serif; margin: 0; min-height: 100vh; }
.container { max-width: 500px; margin: 40px auto; background: #fff; border-radius: 16px; box-shadow: 0 6px 32px rgba(30,60,114,0.10); padding: 36px 28px 28px 28px; }
h2 { color: #2563eb; font-size: 2rem; font-weight: 700; margin-bottom: 18px; letter-spacing: 1px; }
.field { margin-bottom: 18px; }
.label { color: #1e293b; font-weight: 600; margin-bottom: 4px; }
.value { color: #222; font-size: 1.1rem; }
.back-btn { margin-bottom: 18px; background: #e0e7ef; color: #222; }
.back-btn:hover { background: #2563eb; color: #fff; }
#msg { margin: 10px 0 0 0; color: #e11d48; font-size: 1rem; text-align: center; min-height: 1.2em; }
</style>
</head>
<body>
<div class="container">
<h2>订单详情</h2>
<button class="back-btn" onclick="window.location.href='/orders/panel'">返回订单管理</button>
<div id="msg"></div>
<div id="detail"></div>
</div>
<script>
window.ORDER_ID = {{ order_id|tojson }};
</script>
<script>
const jwt = localStorage.getItem('jwt');
if (!jwt) location.href = '/login_page';
const msgBox = document.getElementById('msg');
const orderId = window.ORDER_ID;
async function fetchDetail() {
msgBox.innerText = '加载中...';
const res = await fetch(`/orders/${orderId}`, {
headers: {Authorization: 'Bearer ' + jwt}
});
if (res.status === 401) {
msgBox.innerText = '未登录或无权限';
setTimeout(()=>{window.location.href='/login_page';}, 1200);
return;
}
if (res.status === 404) {
msgBox.innerText = '订单不存在';
return;
}
const order = await res.json();
const detailElement = document.getElementById('detail');
detailElement.innerHTML = '';
// 订单ID
const idDiv = document.createElement('div');
idDiv.className = 'field';
idDiv.innerHTML = '<span class="label">订单ID</span><span class="value">' + order.id + '</span>';
// 标题
const titleDiv = document.createElement('div');
titleDiv.className = 'field';
titleDiv.innerHTML = '<span class="label">标题:</span><span class="value">' + order.title + '</span>';
// 描述
const descDiv = document.createElement('div');
descDiv.className = 'field';
descDiv.innerHTML = '<span class="label">描述:</span><span class="value">' + (order.description || '') + '</span>';
// 状态
const statusDiv = document.createElement('div');
statusDiv.className = 'field';
const statusLabel = document.createElement('span');
statusLabel.className = 'label';
statusLabel.textContent = '状态:';
const statusTag = document.createElement('span');
statusTag.className = 'value status-tag ' +
(order.status === "pending" ? "status-pending" : "status-completed");
statusTag.textContent = order.status === "pending" ? "待处理" : "已完成";
const statusSelect = document.createElement('select');
statusSelect.id = 'status-select';
statusSelect.className = 'status-select';
const pendingOption = document.createElement('option');
pendingOption.value = 'pending';
pendingOption.textContent = '待处理';
const completedOption = document.createElement('option');
completedOption.value = 'completed';
completedOption.textContent = '已完成';
statusSelect.appendChild(pendingOption);
statusSelect.appendChild(completedOption);
const updateBtn = document.createElement('button');
updateBtn.className = 'update-btn';
updateBtn.textContent = '更新状态';
updateBtn.onclick = updateStatus;
statusDiv.appendChild(statusLabel);
statusDiv.appendChild(statusTag);
statusDiv.appendChild(statusSelect);
statusDiv.appendChild(updateBtn);
// 创建时间
const timeDiv = document.createElement('div');
timeDiv.className = 'field';
timeDiv.innerHTML = '<span class="label">创建时间:</span><span class="value">' +
(order.created_at ? order.created_at.replace("T", " ").slice(0, 19) : "") + '</span>';
// 添加所有元素
detailElement.appendChild(idDiv);
detailElement.appendChild(titleDiv);
detailElement.appendChild(descDiv);
detailElement.appendChild(statusDiv);
detailElement.appendChild(timeDiv);
msgBox.innerText = '';
}
function updateStatus() {
const newStatus = document.getElementById('status-select').value;
fetch(`/orders/${orderId}`, {
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + jwt,
'Content-Type': 'application/json'
},
body: JSON.stringify({ status: newStatus })
})
.then(res => {
if (res.status === 401) {
msgBox.innerText = '未登录或无权限';
setTimeout(() => window.location.href = '/login_page', 1200);
return;
}
if (res.status === 404) {
msgBox.innerText = '订单不存在';
return;
}
return res.json();
})
.then(data => {
if (data) {
msgBox.innerText = '状态更新成功';
fetchDetail();
}
})
.catch(error => {
msgBox.innerText = '网络错误,请重试';
});
}
fetchDetail();
</script>
<style>
.status-tag {
padding: 4px 8px;
border-radius: 4px;
font-size: 0.9rem;
margin-left: 8px;
}
.status-pending { background: #fee2e2; color: #be123c; }
.status-completed { background: #dcfce7; color: #15803d; }
.status-select {
margin-left: 8px;
padding: 4px 8px;
border-radius: 6px;
border: 1px solid #cbd5e1;
}
.update-btn {
margin-left: 12px;
padding: 4px 8px;
background: #2563eb;
color: #fff;
border: none;
border-radius: 6px;
cursor: pointer;
}
.update-btn:hover {
background: #1d4ed8;
}
</style>
</body>
</html>