You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

389 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>暂存流程 - 资金使用管理系统</title>
<link href="https://cdn.staticfile.org/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.staticfile.org/bootstrap-icons/1.11.0/font/bootstrap-icons.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
background-color: #f5f7fa;
padding: 20px;
}
.page-header {
background: white;
padding: 25px 30px;
border-radius: 10px;
margin-bottom: 20px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
.page-title {
font-size: 24px;
font-weight: 600;
color: #333;
margin: 0;
}
.page-title i {
margin-right: 10px;
color: #667eea;
}
.main-content {
background: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.content-header {
padding: 20px 25px;
border-bottom: 1px solid #e5e7eb;
display: flex;
justify-content: space-between;
align-items: center;
}
.content-title {
font-size: 18px;
font-weight: 600;
color: #333;
margin: 0;
}
.table-container {
padding: 25px;
}
.table {
margin: 0;
}
.table thead th {
border-top: none;
border-bottom: 2px solid #e5e7eb;
font-weight: 600;
color: #666;
font-size: 14px;
padding: 12px;
background-color: #f8f9fa;
}
.table tbody td {
padding: 15px 12px;
vertical-align: middle;
font-size: 14px;
}
.table tbody tr:hover {
background-color: #f8f9fa;
}
.status-badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
}
.status-draft {
background-color: #fff3cd;
color: #856404;
}
.empty-state {
text-align: center;
padding: 60px 20px;
color: #9ca3af;
}
.empty-state i {
font-size: 64px;
margin-bottom: 20px;
opacity: 0.5;
}
.btn-action {
margin: 0 3px;
}
</style>
</head>
<body>
<!-- 页面头部 -->
<div class="page-header">
<h1 class="page-title">
<i class="bi bi-file-earmark-text"></i> 暂存流程
</h1>
</div>
<!-- 主内容 -->
<div class="main-content">
<div class="content-header">
<h2 class="content-title">暂存的支付流程</h2>
<button type="button" class="btn btn-outline-primary" onclick="refreshDraftList()">
<i class="bi bi-arrow-clockwise"></i> 刷新
</button>
</div>
<div class="table-container">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>流程类型</th>
<th>当前步骤</th>
<th>暂存时间</th>
<th>流程信息</th>
<th>操作</th>
</tr>
</thead>
<tbody id="draftList">
<!-- 动态加载暂存列表 -->
</tbody>
</table>
</div>
<div id="emptyState" class="empty-state" style="display: none;">
<i class="bi bi-inbox"></i>
<p>暂无暂存流程</p>
</div>
</div>
</div>
<script src="https://cdn.staticfile.org/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
// 流程类型映射
const processTypeMap = {
'procurement': '采购管理',
'meeting': '会议、培训、接待',
'vehicle': '车船管理及维修',
'instrument': '仪器管理',
'travel': '出差管理',
'contract': '合同管理',
'installation': '安装维修'
};
// 支付方式映射
const paymentModeMap = {
'single': '单条流程实例支付',
'batch': '批量支付'
};
// 步骤名称映射
const stepNameMap = {
1: '选择流程',
2: '选择实例',
3: '选择金额',
4: '招标流程',
5: '合同流程',
6: '上传材料',
7: '填写信息',
8: '确认提交'
};
// 加载暂存列表
function loadDraftList() {
const tbody = document.getElementById('draftList');
const emptyState = document.getElementById('emptyState');
// 从localStorage获取所有暂存数据
const drafts = [];
// 获取非直接支付的暂存
const beijingDraft = localStorage.getItem('beijingPaymentDraft');
if (beijingDraft) {
try {
const draftData = JSON.parse(beijingDraft);
drafts.push({
type: 'beijing',
typeName: '非直接支付',
data: draftData
});
} catch (e) {
console.error('解析非直接支付暂存数据失败:', e);
}
}
// 可以添加其他类型的暂存数据
// const directDraft = localStorage.getItem('directPaymentDraft');
// if (directDraft) { ... }
tbody.innerHTML = '';
if (drafts.length === 0) {
emptyState.style.display = 'block';
return;
}
emptyState.style.display = 'none';
drafts.forEach((draft, index) => {
const draftData = draft.data;
const processType = draftData.formData?.processType || '';
const paymentMode = draftData.formData?.paymentMode || '';
const currentStep = draftData.currentStep || 1;
const timestamp = draftData.timestamp || '';
// 格式化时间
let timeText = '-';
if (timestamp) {
try {
const date = new Date(timestamp);
timeText = date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
timeText = timestamp;
}
}
// 流程信息摘要
let infoText = '';
if (processType) {
infoText += processTypeMap[processType] || processType;
}
if (paymentMode) {
infoText += ' / ' + (paymentModeMap[paymentMode] || paymentMode);
}
if (draftData.formData?.selectedInstanceName) {
infoText += ' / ' + draftData.formData.selectedInstanceName;
}
if (!infoText) {
infoText = '未填写';
}
const tr = document.createElement('tr');
tr.innerHTML = `
<td>${draft.typeName}</td>
<td>
<span class="badge bg-info">步骤 ${currentStep}</span>
<small class="text-muted d-block mt-1">${stepNameMap[currentStep] || '未知步骤'}</small>
</td>
<td>${timeText}</td>
<td>
<div style="max-width: 300px;">
<small class="text-muted">${infoText}</small>
</div>
</td>
<td>
<button type="button" class="btn btn-sm btn-primary btn-action" onclick="restoreDraft('${draft.type}', ${index})">
<i class="bi bi-arrow-clockwise"></i> 恢复
</button>
<button type="button" class="btn btn-sm btn-outline-secondary btn-action" onclick="viewDraft('${draft.type}', ${index})">
<i class="bi bi-eye"></i> 查看
</button>
<button type="button" class="btn btn-sm btn-outline-danger btn-action" onclick="deleteDraft('${draft.type}', ${index})">
<i class="bi bi-trash"></i> 删除
</button>
</td>
`;
tbody.appendChild(tr);
});
}
// 恢复暂存流程
function restoreDraft(draftType, index) {
if (confirm('确定要恢复此暂存流程吗?恢复后将跳转到对应的支付页面。')) {
if (draftType === 'beijing') {
// 跳转到非直接支付页面
if (parent && parent.loadPage) {
parent.loadPage('pages/payment/beijing-payment.html');
// 等待页面加载后恢复数据
setTimeout(() => {
const iframe = parent.document.getElementById('mainFrame');
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage({
action: 'restoreDraft',
draftType: 'beijing'
}, '*');
}
}, 500);
} else {
window.location.href = 'beijing-payment.html?restore=true';
}
}
}
}
// 查看暂存详情
function viewDraft(draftType, index) {
let draftData = null;
if (draftType === 'beijing') {
const draftStr = localStorage.getItem('beijingPaymentDraft');
if (draftStr) {
draftData = JSON.parse(draftStr);
}
}
if (!draftData) {
alert('暂存数据不存在');
return;
}
// 构建详情文本
let detailText = '暂存流程详情:\n\n';
detailText += '流程类型:' + (processTypeMap[draftData.formData?.processType] || '-') + '\n';
detailText += '支付方式:' + (paymentModeMap[draftData.formData?.paymentMode] || '-') + '\n';
detailText += '当前步骤:' + (stepNameMap[draftData.currentStep] || draftData.currentStep) + '\n';
detailText += '暂存时间:' + (draftData.timestamp ? new Date(draftData.timestamp).toLocaleString('zh-CN') : '-') + '\n\n';
if (draftData.formData?.selectedInstanceName) {
detailText += '流程实例:' + draftData.formData.selectedInstanceName + '\n';
}
if (draftData.formData?.inputAmount) {
detailText += '支付金额:¥' + parseFloat(draftData.formData.inputAmount).toLocaleString() + '\n';
}
if (draftData.formData?.paymentItem) {
detailText += '支付事项:' + draftData.formData.paymentItem + '\n';
}
alert(detailText);
}
// 删除暂存
function deleteDraft(draftType, index) {
if (confirm('确定要删除此暂存流程吗?删除后无法恢复。')) {
if (draftType === 'beijing') {
localStorage.removeItem('beijingPaymentDraft');
}
loadDraftList();
alert('暂存流程已删除');
}
}
// 刷新列表
function refreshDraftList() {
loadDraftList();
}
// 页面加载时加载列表
document.addEventListener('DOMContentLoaded', function() {
loadDraftList();
});
// 监听来自iframe的消息用于恢复暂存
window.addEventListener('message', function(event) {
if (event.data && event.data.action === 'restoreDraft') {
// 这里可以处理恢复逻辑
}
});
</script>
</body>
</html>