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.

953 lines
33 KiB

4 months ago
<!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 rel="stylesheet" href="https://cdn.staticfile.org/bootstrap/5.3.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.staticfile.org/bootstrap-icons/1.11.0/font/bootstrap-icons.min.css">
<style>
:root {
--panel-bg: #fff;
--border: #e5e7eb;
--muted: #6b7280;
--primary: #4f46e5;
--a4-width: 210mm;
--a4-height: 297mm;
}
* { box-sizing: border-box; }
body {
background: #f5f7fb;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif;
color: #111827;
height: 100vh;
display: flex;
flex-direction: column;
margin: 0;
overflow: hidden;
}
.layout {
display: grid;
grid-template-columns: 380px 1fr 400px;
grid-template-rows: 1fr;
gap: 12px;
padding: 12px;
height: calc(100vh - 60px);
overflow: hidden;
}
.bottom-toolbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--panel-bg);
border-top: 1px solid var(--border);
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 12px;
box-shadow: 0 -2px 8px rgba(0,0,0,0.04);
z-index: 100;
}
.panel {
background: var(--panel-bg);
border: 1px solid var(--border);
border-radius: 10px;
box-shadow: 0 4px 16px rgba(0,0,0,0.05);
overflow: hidden;
display: flex;
flex-direction: column;
}
.panel-header {
padding: 12px 14px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 600;
color: #374151;
font-size: 14px;
}
.panel-body { padding: 12px; overflow: auto; }
/* 分支配置区域 */
.branch-config-section {
margin-bottom: 20px;
}
.branch-list-table {
font-size: 12px;
}
.branch-list-table table {
width: 100%;
border-collapse: collapse;
font-size: 11px;
}
.branch-list-table th {
background: #f9fafb;
padding: 8px 6px;
text-align: left;
font-weight: 600;
border: 1px solid var(--border);
}
.branch-list-table td {
padding: 6px;
border: 1px solid var(--border);
}
.branch-list-table tbody tr {
cursor: pointer;
transition: background 0.2s;
}
.branch-list-table tbody tr:hover {
background: #f3f4f6;
}
.branch-list-table tbody tr.active {
background: #eef2ff;
border-left: 3px solid var(--primary);
}
.branch-badge {
display: inline-block;
padding: 2px 6px;
border-radius: 4px;
font-size: 10px;
background: #eef2ff;
color: var(--primary);
margin: 1px;
}
.condition-editor {
background: #f9fafb;
border: 1px solid var(--border);
border-radius: 6px;
padding: 10px;
margin-top: 10px;
}
.condition-row {
display: grid;
grid-template-columns: 100px 1fr 80px;
gap: 8px;
margin-bottom: 8px;
align-items: center;
}
/* A4画布区域 */
.canvas-wrapper {
display: flex;
justify-content: center;
align-items: flex-start;
padding: 20px;
overflow: auto;
background: #e5e7eb;
}
.a4-canvas {
width: var(--a4-width);
min-height: var(--a4-height);
background: white;
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
padding: 20mm;
position: relative;
}
.document-section {
margin-bottom: 20px;
border: 1px dashed #d1d5db;
border-radius: 6px;
padding: 12px;
position: relative;
min-height: 80px;
}
.document-section:hover {
border-color: var(--primary);
background: #fafbff;
}
.section-header {
font-weight: 700;
font-size: 16px;
color: var(--primary);
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 2px solid var(--primary);
display: flex;
justify-content: space-between;
align-items: center;
}
.section-header .section-badge {
font-size: 12px;
padding: 2px 8px;
background: var(--primary);
color: white;
border-radius: 4px;
}
.field-item {
display: flex;
margin-bottom: 10px;
align-items: center;
}
.field-label {
min-width: 100px;
font-weight: 500;
color: #374151;
font-size: 13px;
}
.field-value {
flex: 1;
padding: 6px 10px;
border: 1px solid var(--border);
border-radius: 4px;
background: #f9fafb;
font-size: 13px;
min-height: 32px;
}
.field-value.empty {
color: #9ca3af;
font-style: italic;
}
.field-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.payment-round {
border: 1px solid var(--border);
border-radius: 6px;
padding: 10px;
margin-bottom: 10px;
background: #f9fafb;
}
.payment-round-header {
font-weight: 600;
color: var(--primary);
margin-bottom: 8px;
font-size: 13px;
}
/* 属性面板 */
.property-group {
border: 1px solid var(--border);
border-radius: 8px;
padding: 10px;
margin-bottom: 12px;
background: #fafbff;
}
.property-group-title {
font-weight: 600;
margin-bottom: 10px;
color: #374151;
font-size: 13px;
}
.json-editor {
font-family: 'Courier New', monospace;
font-size: 12px;
min-height: 300px;
}
</style>
</head>
<body>
<div class="layout">
<!-- 左侧:分支配置区域 -->
<div class="panel">
<div class="panel-header">
<span>分支配置管理</span>
</div>
<div class="panel-body">
<!-- 第一层:事前流程分类选择 -->
<div class="branch-config-section">
<div class="panel-header" style="padding: 8px 0; border-bottom: 1px solid var(--border); margin-bottom: 10px;">
<span style="font-size: 13px; font-weight: 600;">事前流程分类</span>
</div>
<select class="form-select form-select-sm mb-3" id="processCategorySelect" onchange="switchProcessCategory()">
<option value="">请选择分类</option>
<option value="采购管理">采购管理</option>
<option value="会议培训接待">会议、培训、接待</option>
<option value="车船管理及维修">车船管理及维修</option>
<option value="仪器管理">仪器管理</option>
<option value="出差管理">出差管理</option>
<option value="合同管理">合同管理</option>
<option value="安装维修">安装维修</option>
</select>
</div>
<!-- 第二层:该分类下的分支列表 -->
<div class="branch-config-section" id="branchListSection" style="display: none;">
<div class="d-flex justify-content-between align-items-center mb-2">
<span style="font-size: 13px; font-weight: 600;">分支条件组合</span>
<button class="btn btn-sm btn-outline-primary" id="btnAddBranch" style="padding: 2px 8px; font-size: 11px;">
<i class="bi bi-plus"></i> 添加分支
</button>
</div>
<div class="branch-list-table">
<table>
<thead>
<tr>
<th style="width: 30px;">#</th>
<th>条件组合</th>
<th style="width: 50px;">操作</th>
</tr>
</thead>
<tbody id="branchListTableBody">
<!-- 动态生成 -->
</tbody>
</table>
</div>
</div>
<!-- 第三层:当前分支条件设置 -->
<div class="branch-config-section" id="conditionSection" style="display: none;">
<div class="panel-header" style="padding: 8px 0; border-bottom: 1px solid var(--border); margin-bottom: 10px;">
<span style="font-size: 13px;">当前分支条件设置</span>
</div>
<div id="conditionEditor">
<div class="condition-editor">
<div class="condition-row">
<label class="form-label small">合同分类</label>
<select class="form-select form-select-sm" id="condContractClass">
<option value="">全部</option>
<option value="合同类">合同类</option>
<option value="其他支出类">其他支出类</option>
</select>
<button class="btn btn-sm btn-outline-secondary" onclick="clearCondition('contract_classification')">清除</button>
</div>
<div class="condition-row">
<label class="form-label small">事务类型</label>
<select class="form-select form-select-sm" id="condBusinessType">
<option value="">全部</option>
<option value="项目采购类">项目采购类</option>
<option value="信水借电类">信水借电类</option>
<option value="差旅报销">差旅报销</option>
</select>
<button class="btn btn-sm btn-outline-secondary" onclick="clearCondition('business_type')">清除</button>
</div>
<div class="condition-row">
<label class="form-label small">合同类型</label>
<select class="form-select form-select-sm" id="condContractType">
<option value="">全部</option>
<option value="支出类">支出类</option>
<option value="收入类">收入类</option>
<option value="无费用发生类">无费用发生类</option>
</select>
<button class="btn btn-sm btn-outline-secondary" onclick="clearCondition('contract_type')">清除</button>
</div>
<div class="condition-row">
<label class="form-label small">采购形式</label>
<select class="form-select form-select-sm" id="condProcurementMethod">
<option value="">全部</option>
<option value="政府采购">政府采购</option>
<option value="小型项目">小型项目</option>
<option value="直接发包">直接发包</option>
</select>
<button class="btn btn-sm btn-outline-secondary" onclick="clearCondition('procurement_method')">清除</button>
</div>
<button class="btn btn-primary btn-sm w-100 mt-2" onclick="applyConditions()">
<i class="bi bi-check-circle me-1"></i>应用条件
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 中间A4画布区域 -->
<div class="panel">
<div class="panel-header">
<span>A4文档预览</span>
<span class="badge bg-info" id="canvasBranchBadge">全部可见</span>
</div>
<div class="canvas-wrapper">
<div class="a4-canvas" id="a4Canvas">
<!-- 区域a基本信息 -->
<div class="document-section" data-section="basic_info">
<div class="section-header">
<span>a. 基本信息</span>
<span class="section-badge">基本信息</span>
</div>
<div id="sectionBasicInfo" class="section-content">
<!-- 动态生成字段 -->
</div>
</div>
<!-- 区域b资金申请上会 -->
<div class="document-section" data-section="meeting_info">
<div class="section-header">
<span>b. 资金申请上会</span>
<span class="section-badge">上会流程</span>
</div>
<div id="sectionMeetingInfo" class="section-content">
<!-- 动态生成字段 -->
</div>
</div>
<!-- 区域c事前流程 -->
<div class="document-section" data-section="pre_approval">
<div class="section-header">
<span>c. 事前流程</span>
<span class="section-badge">附件流程</span>
</div>
<div id="sectionPreApproval" class="section-content">
<!-- 动态生成字段 -->
</div>
</div>
<!-- 区域d支付流程 -->
<div class="document-section" data-section="payment">
<div class="section-header">
<span>d. 支付流程</span>
<span class="section-badge">多轮次支付</span>
</div>
<div id="sectionPayment" class="section-content">
<!-- 动态生成字段 -->
</div>
</div>
</div>
</div>
</div>
<!-- 右侧JSON配置和属性面板 -->
<div class="panel">
<div class="panel-header">
<ul class="nav nav-tabs nav-tabs-sm" style="border-bottom: none; margin: -12px -14px 0;">
<li class="nav-item">
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab-json">JSON配置</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-properties">字段属性</button>
</li>
</ul>
</div>
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane fade show active" id="tab-json">
<div class="property-group">
<div class="property-group-title">区域配置JSON</div>
<textarea class="form-control json-editor" id="jsonConfig" rows="15"></textarea>
<button class="btn btn-primary btn-sm w-100 mt-2" onclick="applyJsonConfig()">
<i class="bi bi-check-circle me-1"></i>应用配置
</button>
</div>
</div>
<div class="tab-pane fade" id="tab-properties">
<div id="propertyPanel">
<div class="text-muted small">点击画布区域进行配置</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 底部工具栏 -->
<div class="bottom-toolbar">
<button class="btn btn-outline-secondary btn-sm" id="btnImport">
<i class="bi bi-upload me-1"></i>导入
</button>
<button class="btn btn-outline-secondary btn-sm" id="btnExport">
<i class="bi bi-download me-1"></i>导出
</button>
<button class="btn btn-primary btn-sm" id="btnSave">
<i class="bi bi-save me-1"></i>保存
</button>
<button class="btn btn-success btn-sm" id="btnPreview">
<i class="bi bi-printer me-1"></i>打印预览
</button>
</div>
<script src="https://cdn.staticfile.org/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
<script>
// 默认区域配置JSON
const defaultSectionConfig = {
basic_info: {
title: "基本信息",
fields: [
{ key: "title", label: "事项标题", type: "text", required: true },
{ key: "amount", label: "金额", type: "number", required: true },
{ key: "project_name", label: "项目名称", type: "text" },
{ key: "budget_source", label: "资金来源", type: "text" },
{ key: "apply_date", label: "申请日期", type: "date" }
]
},
meeting_info: {
title: "拟支上会",
fields: [
{ key: "meeting_date", label: "上会日期", type: "date" },
{ key: "meeting_result", label: "上会结果", type: "text" },
{ key: "meeting_amount", label: "上会金额", type: "number" },
{ key: "meeting_notes", label: "上会备注", type: "textarea" }
]
},
pre_approval: {
title: "事前流程",
fields: [
{ key: "procurement_approval", label: "采购审批", type: "checkbox" },
{ key: "contract_approval", label: "合同审批", type: "checkbox" },
{ key: "bidding_process", label: "招标流程", type: "checkbox" },
{ key: "attachments", label: "附件清单", type: "textarea" }
]
},
payment: {
title: "支付流程",
rounds: [
{
round: 1,
fields: [
{ key: "payment_amount_1", label: "支付金额", type: "number" },
{ key: "payment_date_1", label: "支付日期", type: "date" },
{ key: "payment_status_1", label: "支付状态", type: "text" }
]
}
]
}
};
let currentProcessCategory = ''; // 当前选中的事前流程分类
let currentBranch = ''; // 当前选中的分支ID
let processCategories = {}; // 数据结构:{ "采购管理": { branches: {...}, configs: {...} } }
// 初始化分类结构
function initProcessCategories() {
const categories = ['采购管理', '会议培训接待', '车船管理及维修', '仪器管理', '出差管理', '合同管理', '安装维修'];
categories.forEach(category => {
if (!processCategories[category]) {
processCategories[category] = {
branches: {},
configs: {}
};
}
});
}
// 初始化
function initialize() {
initProcessCategories();
// 绑定事件
document.getElementById('btnAddBranch').addEventListener('click', addNewBranch);
document.getElementById('btnSave').addEventListener('click', saveConfig);
document.getElementById('btnExport').addEventListener('click', exportConfig);
document.getElementById('btnImport').addEventListener('click', importConfig);
document.getElementById('btnPreview').addEventListener('click', previewPrint);
// 区域点击事件
document.querySelectorAll('.document-section').forEach(section => {
section.addEventListener('click', () => {
const sectionId = section.dataset.section;
showSectionProperties(sectionId);
});
});
}
// 切换事前流程分类
function switchProcessCategory() {
const category = document.getElementById('processCategorySelect').value;
currentProcessCategory = category;
currentBranch = '';
if (category) {
document.getElementById('branchListSection').style.display = 'block';
document.getElementById('conditionSection').style.display = 'none';
renderBranchListTable();
document.getElementById('canvasBranchBadge').textContent = category;
} else {
document.getElementById('branchListSection').style.display = 'none';
document.getElementById('conditionSection').style.display = 'none';
document.getElementById('canvasBranchBadge').textContent = '请选择分类';
}
renderDocument();
updateJsonConfig();
}
// 渲染分支列表(显示当前分类下的分支)
function renderBranchListTable() {
const tbody = document.getElementById('branchListTableBody');
tbody.innerHTML = '';
if (!currentProcessCategory || !processCategories[currentProcessCategory]) {
return;
}
const categoryData = processCategories[currentProcessCategory];
const branches = Object.values(categoryData.branches);
if (branches.length === 0) {
tbody.innerHTML = '<tr><td colspan="3" class="text-center text-muted" style="padding: 20px;">该分类下暂无分支,点击"添加分支"创建</td></tr>';
return;
}
branches.forEach((branch, index) => {
const tr = document.createElement('tr');
tr.className = branch.id === currentBranch ? 'active' : '';
tr.onclick = () => switchToBranch(branch.id);
const conditionBadges = branch.conditionLabels.map(label =>
`<span class="branch-badge">${label}</span>`
).join('');
tr.innerHTML = `
<td>${index + 1}</td>
<td>
<div style="font-weight: 500; margin-bottom: 2px; font-size: 12px;">${branch.name}</div>
<div style="font-size: 10px;">${conditionBadges || '<span class="text-muted">默认分支</span>'}</div>
</td>
<td>
<button class="btn btn-xs btn-outline-danger" onclick="event.stopPropagation(); deleteBranch('${branch.id}')" title="删除">
<i class="bi bi-trash"></i>
</button>
</td>
`;
tbody.appendChild(tr);
});
}
// 渲染文档
function renderDocument() {
let config = defaultSectionConfig;
if (currentProcessCategory && currentBranch) {
const categoryData = processCategories[currentProcessCategory];
if (categoryData && categoryData.configs[currentBranch]) {
config = categoryData.configs[currentBranch];
}
} else if (currentProcessCategory) {
// 如果只选择了分类,使用分类的默认配置
const categoryData = processCategories[currentProcessCategory];
if (categoryData && categoryData.defaultConfig) {
config = categoryData.defaultConfig;
}
}
// 渲染基本信息
renderSection('sectionBasicInfo', config.basic_info);
// 渲染拟支上会
renderSection('sectionMeetingInfo', config.meeting_info);
// 渲染事前流程
renderSection('sectionPreApproval', config.pre_approval);
// 渲染支付流程
renderPaymentSection('sectionPayment', config.payment);
}
function renderSection(containerId, sectionConfig) {
const container = document.getElementById(containerId);
if (!container || !sectionConfig) return;
container.innerHTML = '';
if (sectionConfig.fields) {
sectionConfig.fields.forEach(field => {
const fieldDiv = document.createElement('div');
fieldDiv.className = 'field-item';
fieldDiv.innerHTML = `
<div class="field-label">${field.label}${field.required ? '<span style="color: red;">*</span>' : ''}:</div>
<div class="field-value ${!field.value ? 'empty' : ''}">${field.value || `[${field.type}]`}</div>
`;
container.appendChild(fieldDiv);
});
}
}
function renderPaymentSection(containerId, paymentConfig) {
const container = document.getElementById(containerId);
if (!container || !paymentConfig) return;
container.innerHTML = '';
if (paymentConfig.rounds) {
paymentConfig.rounds.forEach((round, index) => {
const roundDiv = document.createElement('div');
roundDiv.className = 'payment-round';
roundDiv.innerHTML = `<div class="payment-round-header">第 ${round.round} 轮支付</div>`;
const fieldsDiv = document.createElement('div');
fieldsDiv.className = 'field-row';
round.fields.forEach(field => {
const fieldDiv = document.createElement('div');
fieldDiv.className = 'field-item';
fieldDiv.innerHTML = `
<div class="field-label">${field.label}:</div>
<div class="field-value ${!field.value ? 'empty' : ''}">${field.value || `[${field.type}]`}</div>
`;
fieldsDiv.appendChild(fieldDiv);
});
roundDiv.appendChild(fieldsDiv);
container.appendChild(roundDiv);
});
}
}
// 切换分支
function switchToBranch(branchId) {
if (!currentProcessCategory) return;
currentBranch = branchId;
const categoryData = processCategories[currentProcessCategory];
const branch = categoryData.branches[branchId];
if (branch) {
document.getElementById('canvasBranchBadge').textContent = `${currentProcessCategory} - ${branch.name}`;
renderBranchListTable();
renderDocument();
updateJsonConfig();
// 显示条件设置区域
document.getElementById('conditionSection').style.display = 'block';
// 回填条件设置到编辑器
if (branch.conditions) {
const conditions = branch.conditions;
document.getElementById('condContractClass').value = conditions.contract_classification || '';
document.getElementById('condBusinessType').value = conditions.business_type || '';
document.getElementById('condContractType').value = conditions.contract_type || '';
document.getElementById('condProcurementMethod').value = conditions.procurement_method || '';
}
} else {
// 清空所有条件
document.getElementById('condContractClass').value = '';
document.getElementById('condBusinessType').value = '';
document.getElementById('condContractType').value = '';
document.getElementById('condProcurementMethod').value = '';
document.getElementById('conditionSection').style.display = 'none';
}
}
// 应用条件
function applyConditions() {
if (!currentProcessCategory) {
alert('请先选择事前流程分类');
return;
}
const conditions = {
contract_classification: document.getElementById('condContractClass').value,
business_type: document.getElementById('condBusinessType').value,
contract_type: document.getElementById('condContractType').value,
procurement_method: document.getElementById('condProcurementMethod').value
};
const labels = Object.values(conditions).filter(v => v).join('-');
if (!labels) {
alert('请至少选择一个条件');
return;
}
const branchId = 'branch_' + Date.now();
const categoryData = processCategories[currentProcessCategory];
categoryData.branches[branchId] = {
id: branchId,
name: labels || '新分支',
conditions,
conditionLabels: Object.values(conditions).filter(v => v)
};
categoryData.configs[branchId] = JSON.parse(JSON.stringify(defaultSectionConfig));
switchToBranch(branchId);
}
function clearCondition(key) {
// 清除对应条件的下拉框
const map = {
'contract_classification': 'condContractClass',
'business_type': 'condBusinessType',
'contract_type': 'condContractType',
'procurement_method': 'condProcurementMethod'
};
const el = document.getElementById(map[key]);
if (el) el.value = '';
}
// 更新JSON配置
function updateJsonConfig() {
let config = defaultSectionConfig;
if (currentProcessCategory && currentBranch) {
const categoryData = processCategories[currentProcessCategory];
if (categoryData && categoryData.configs[currentBranch]) {
config = categoryData.configs[currentBranch];
}
}
document.getElementById('jsonConfig').value = JSON.stringify(config, null, 2);
}
// 应用JSON配置
function applyJsonConfig() {
if (!currentProcessCategory || !currentBranch) {
alert('请先选择分类和分支');
return;
}
try {
const config = JSON.parse(document.getElementById('jsonConfig').value);
const categoryData = processCategories[currentProcessCategory];
categoryData.configs[currentBranch] = config;
renderDocument();
alert('配置已应用');
} catch (e) {
alert('JSON格式错误' + e.message);
}
}
// 显示区域属性
function showSectionProperties(sectionId) {
let config = defaultSectionConfig;
if (currentProcessCategory && currentBranch) {
const categoryData = processCategories[currentProcessCategory];
if (categoryData && categoryData.configs[currentBranch]) {
config = categoryData.configs[currentBranch];
}
}
const sectionConfig = config[sectionId];
if (!sectionConfig) return;
const panel = document.getElementById('propertyPanel');
panel.innerHTML = `
<div class="property-group">
<div class="property-group-title">${sectionConfig.title || sectionId}</div>
<div class="mb-2">
<label class="form-label small">区域标题</label>
<input class="form-control form-control-sm" value="${sectionConfig.title || ''}"
onchange="updateSectionTitle('${sectionId}', this.value)">
</div>
<div class="mb-2">
<label class="form-label small">字段数量</label>
<input type="number" class="form-control form-control-sm"
value="${sectionConfig.fields ? sectionConfig.fields.length : (sectionConfig.rounds ? sectionConfig.rounds.length : 0)}" readonly>
</div>
<button class="btn btn-primary btn-sm w-100" onclick="editSectionFields('${sectionId}')">
<i class="bi bi-pencil me-1"></i>编辑字段
</button>
</div>
`;
// 切换到属性标签页
document.querySelector('[data-bs-target="#tab-properties"]').click();
}
function updateSectionTitle(sectionId, title) {
if (!currentProcessCategory || !currentBranch) return;
const categoryData = processCategories[currentProcessCategory];
if (!categoryData.configs[currentBranch]) {
categoryData.configs[currentBranch] = JSON.parse(JSON.stringify(defaultSectionConfig));
}
categoryData.configs[currentBranch][sectionId].title = title;
renderDocument();
updateJsonConfig();
}
function editSectionFields(sectionId) {
alert('字段编辑功能(可扩展为弹窗编辑)');
}
function addNewBranch() {
if (!currentProcessCategory) {
alert('请先选择事前流程分类');
return;
}
// 显示条件设置区域
document.getElementById('conditionSection').style.display = 'block';
// 清空条件
document.getElementById('condContractClass').value = '';
document.getElementById('condBusinessType').value = '';
document.getElementById('condContractType').value = '';
document.getElementById('condProcurementMethod').value = '';
currentBranch = '';
}
function deleteBranch(branchId) {
if (!currentProcessCategory) return;
if (confirm('确定要删除该分支吗?')) {
const categoryData = processCategories[currentProcessCategory];
delete categoryData.branches[branchId];
delete categoryData.configs[branchId];
if (currentBranch === branchId) {
currentBranch = '';
document.getElementById('conditionSection').style.display = 'none';
document.getElementById('canvasBranchBadge').textContent = currentProcessCategory;
}
renderBranchListTable();
renderDocument();
}
}
// 保存配置
function saveConfig() {
const data = {
processCategories: processCategories
};
console.log('保存配置:', data);
alert('配置已保存(模拟)');
}
// 导出配置
function exportConfig() {
const data = {
processCategories: processCategories
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'canvas-config.json';
a.click();
URL.revokeObjectURL(url);
}
// 导入配置
function importConfig() {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.json';
input.onchange = (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
try {
const data = JSON.parse(event.target.result);
if (data.processCategories) {
processCategories = data.processCategories;
// 重新初始化分类选择器
if (currentProcessCategory && processCategories[currentProcessCategory]) {
renderBranchListTable();
renderDocument();
updateJsonConfig();
}
alert('配置已导入');
} else {
alert('文件格式不正确');
}
} catch (e) {
alert('文件格式错误:' + e.message);
}
};
reader.readAsText(file);
};
input.click();
}
// 打印预览
function previewPrint() {
window.print();
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialize);
} else {
initialize();
}
</script>
</body>
</html>