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

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 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>