feat: 初始提交(仅核心代码,已排除大文件)

This commit is contained in:
yangxiangyuan
2026-07-08 10:29:50 +08:00
commit be7c5842f1
623 changed files with 332897 additions and 0 deletions
+210
View File
@@ -0,0 +1,210 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>报销系统</title>
<link rel="icon" href="/icons/expense.svg" type="image/svg+xml" />
<link rel="stylesheet" href="/common/common.css" />
<link rel="stylesheet" href="/tools/expense/expense.css" />
<link rel="stylesheet" href="/tools/expense/theme/tokens.css" />
<link rel="stylesheet" href="/tools/expense/theme/components.css" />
</head>
<body class="theme-expense" data-theme="dark">
<div id="topbar"></div>
<main class="container">
<div class="expense-header">
<h2><span class="logo-ico" aria-hidden="true"></span>报销系统</h2>
<div class="expense-tabs">
<div class="tabs horizontal">
<button id="tab-expense" class="tab active">
<svg width="16" height="16" viewBox="0 0 24 24"><path d="M3 7h18v10H3z" fill="none" stroke="currentColor" stroke-width="2"/><path d="M3 7l9-4 9 4" fill="none" stroke="currentColor" stroke-width="2"/></svg>报销列表
</button>
<button id="tab-maint" class="tab">
<svg width="16" height="16" viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h10" stroke="currentColor" stroke-width="2"/></svg>数据维护
</button>
<button id="tab-stat" class="tab">
<svg width="16" height="16" viewBox="0 0 24 24"><path d="M4 18h4V10H4v8zm6 0h4V6h-4v12zm6 0h4V14h-4v4z" fill="currentColor"/></svg>统计分析
</button>
</div>
</div>
<div class="header-actions">
<button id="expense-toggle-theme" class="icon-theme" title="深色/浅色切换" aria-label="深色/浅色切换">🌙</button>
<button id="expense-toggle-nav" class="icon-toggle" title="显示/隐藏导航" aria-label="显示/隐藏导航"></button>
</div>
</div>
<div class="expense-layout">
<div id="expense-content">
<div id="status" class="status" style="display:none"></div>
<button id="font-size-toggle" class="font-size-toggle" title="切换字体大小">字体大小</button>
<section id="panel-expense" class="panel card">
<div class="action-buttons">
<button class="action-btn" onclick="openModal('expense', 'add')">
<span>➕</span>新增报销记录
</button>
<div style="margin-left:16px; display:inline-flex; align-items:center; gap:12px; font-size:14px">
<label style="cursor:pointer"><input type="radio" name="filter-cost-type" value="全部" checked> 全部</label>
<label style="cursor:pointer"><input type="radio" name="filter-cost-type" value="个人费用"> 个人费用</label>
<label style="cursor:pointer"><input type="radio" name="filter-cost-type" value="家庭费用"> 家庭费用</label>
<label style="cursor:pointer"><input type="radio" name="filter-cost-type" value="公司费用"> 公司费用</label>
</div>
<div style="flex:1"></div>
<button class="action-btn" id="records-export" title="导出Excel" aria-label="导出Excel">
⬇️
</button>
</div>
<div class="list-card">
<table class="grid">
<thead>
<tr>
<th onclick="handleSort('date')" style="cursor:pointer; user-select:none">报销日期 <span id="sort-icon-date" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th onclick="handleSort('cost_type')" style="cursor:pointer; user-select:none">费用类型 <span id="sort-icon-cost_type" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th onclick="handleSort('type')" style="cursor:pointer; user-select:none">报销类型 <span id="sort-icon-type" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th onclick="handleSort('amount')" style="cursor:pointer; user-select:none">报销金额 <span id="sort-icon-amount" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th onclick="handleSort('subject')" style="cursor:pointer; user-select:none">报销主体 <span id="sort-icon-subject" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th onclick="handleSort('content')" style="cursor:pointer; user-select:none">报销内容 <span id="sort-icon-content" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th onclick="handleSort('arrived')" style="cursor:pointer; user-select:none">是否到账 <span id="sort-icon-arrived" style="font-size:12px; margin-left:4px">🔻🔺</span></th>
<th class="col-actions">操作</th>
</tr>
</thead>
<tbody id="ex-body"></tbody>
</table>
</div>
</section>
<section id="panel-stat" class="panel card" style="display:none">
<div class="card" style="margin-bottom:12px">
<h3>统计分析</h3>
<div class="action-buttons">
<label class="modal-label" style="margin-right:8px">开始日期:</label>
<input type="date" id="stat-start" class="modal-input" style="max-width:160px">
<label class="modal-label" style="margin:0 8px">结束日期:</label>
<input type="date" id="stat-end" class="modal-input" style="max-width:160px">
<button class="action-btn" id="stat-refresh"><span>🔄</span>刷新</button>
<button class="action-btn" id="stats-export" title="导出Excel" aria-label="导出Excel">⬇️</button>
</div>
<div id="stat-summary" class="list-card" style="padding:12px"></div>
</div>
<div class="card" style="margin-bottom:12px">
<h3>按费用类别统计</h3>
<div class="list-card">
<table class="grid">
<thead><tr><th>类别</th><th>金额(元)</th><th>已到账(元)</th><th>未到账(元)</th><th>记录数</th></tr></thead>
<tbody id="stat-cost-type-body"></tbody>
</table>
</div>
</div>
<div class="card" style="margin-bottom:12px">
<h3>按类型统计</h3>
<div class="list-card">
<table class="grid">
<thead><tr><th>类型</th><th>金额(元)</th><th>已到账(元)</th><th>未到账(元)</th><th>记录数</th></tr></thead>
<tbody id="stat-type-body"></tbody>
</table>
</div>
</div>
<div class="card">
<h3>按主体统计</h3>
<div class="list-card">
<table class="grid">
<thead><tr><th>主体</th><th>金额(元)</th><th>已到账(元)</th><th>未到账(元)</th><th>记录数</th></tr></thead>
<tbody id="stat-subject-body"></tbody>
</table>
</div>
</div>
<div class="card">
<h3>月度趋势</h3>
<div class="list-card">
<table class="grid">
<thead><tr><th>月份</th><th>金额(元)</th><th>已到账(元)</th><th>未到账(元)</th><th>记录数</th></tr></thead>
<tbody id="stat-monthly-body"></tbody>
</table>
</div>
</div>
</section>
<section id="panel-maint" class="panel card" style="display:none">
<div class="action-buttons" style="margin-bottom:8px">
<div style="display:inline-flex; align-items:center; gap:12px; font-size:14px">
<label style="cursor:pointer"><input type="radio" name="maint-cost-type" value="全部" checked> 全部</label>
<label style="cursor:pointer"><input type="radio" name="maint-cost-type" value="个人费用"> 个人费用</label>
<label style="cursor:pointer"><input type="radio" name="maint-cost-type" value="家庭费用"> 家庭费用</label>
<label style="cursor:pointer"><input type="radio" name="maint-cost-type" value="公司费用"> 公司费用</label>
</div>
</div>
<div class="card" style="margin-bottom:12px">
<h3>报销类型</h3>
<div class="action-buttons">
<button class="action-btn" onclick="openModal('cfgType', 'add')">
<span>➕</span>新增类型
</button>
</div>
<div class="list-card">
<table class="grid">
<thead><tr><th>类型名称</th><th>费用类型</th><th class="col-actions">操作</th></tr></thead>
<tbody id="cfg-type-body"></tbody>
</table>
</div>
</div>
<div class="card">
<h3>报销主体</h3>
<div class="action-buttons">
<button class="action-btn" onclick="openModal('cfgSubject', 'add')">
<span>➕</span>新增主体
</button>
</div>
<div class="list-card">
<table class="grid">
<thead><tr><th>主体名称</th><th>费用类型</th><th class="col-actions">操作</th></tr></thead>
<tbody id="cfg-subject-body"></tbody>
</table>
</div>
</div>
</section>
<div id="expense-modal-overlay" class="expense-modal-overlay">
<div id="expense-modal" class="expense-modal">
<div class="expense-modal-header">
<h3 id="expense-modal-title" class="expense-modal-title">模态框标题</h3>
<button class="expense-modal-close" onclick="closeModal()">×</button>
</div>
<div id="expense-modal-body" class="expense-modal-body"></div>
<div id="expense-modal-footer" class="expense-modal-footer"></div>
</div>
</div>
<div id="loading-overlay" class="expense-modal-overlay" style="z-index: 2000;">
<div class="expense-modal loading-modal">
<div class="expense-modal-header">
<h3 id="loading-title" class="expense-modal-title">加载中</h3>
<button id="loading-close-btn" class="expense-modal-close" style="display:none" onclick="closeLoading()">×</button>
</div>
<div class="expense-modal-body loading-body">
<div style="display: flex; align-items: center; gap: 12px;">
<div id="loading-spinner" class="loading-spinner"></div>
<p id="loading-text" style="margin: 0; font-size: 14px; color: var(--color-text); font-weight: 500;">正在处理...</p>
</div>
<div id="loading-logs" class="loading-logs"></div>
</div>
</div>
</div>
<style>@keyframes spin { to { transform: rotate(360deg); } }</style>
<section class="debug" id="expense-debug" style="display:none">
<div class="debug-actions">
<button id="ed-btn-copy" class="btn">复制调试信息</button>
<button id="ed-btn-refresh" class="btn">刷新</button>
<button id="ed-btn-clear" class="btn">清空</button>
</div>
<div id="ed-output" class="debug-output"></div>
</section>
</div>
</div>
</main>
<script src="/common/common.js"></script>
<script src="/tools/expense/expense.js"></script>
<script src="/tools/expense/theme/script.js"></script>
</body>
</html>