所有需求实现完成

This commit is contained in:
Your Name
2026-02-01 15:57:42 +08:00
parent e651b92d7c
commit 6e1174a59a
16 changed files with 2354 additions and 173 deletions
+204 -39
View File
@@ -33,31 +33,28 @@
</section>
<div class="app" id="appMain" style="display: none;">
<aside class="sidebar">
<div class="sidebar-brand">
<span class="brand-icon"></span>
<span class="brand-text">项目管理系统</span>
</div>
<nav class="sidebar-nav">
<a href="#" class="nav-item active" id="navList" data-nav="list">
<span class="nav-icon"></span>
<span>项目列表</span>
</a>
</nav>
<div class="sidebar-footer">
<span class="user-info" id="userInfo"></span>
<button type="button" class="btn-logout" id="btnLogout">退出</button>
</div>
</aside>
<main class="main">
<section id="view-list" class="view view-list active">
<header class="page-header">
<h1 class="page-title">项目列表</h1>
<div class="header-actions">
<div class="header-actions" id="listHeaderActions">
<button type="button" class="btn btn-secondary" id="btnExportXls" title="导出当前列表为 XLS 文件">
<span class="btn-icon"></span> 导出 XLS
</button>
<button type="button" class="btn btn-secondary" id="btnStats" title="按当前搜索条件统计并图表展示">
<span class="btn-icon">📊</span> 统计
</button>
<button type="button" class="btn btn-secondary" id="btnGlobalStats" title="调用后端统计 API 查看各类型项目">
<span class="btn-icon">📈</span> 全局统计
</button>
<button type="button" class="btn btn-primary btn-new-project" id="btnNewProject" style="display: none;">
<span class="btn-icon">+</span> 新建项目
</button>
<div id="topbarUserWrap" class="topbar-user">
<a href="#" class="topbar-link" id="btnUserManage" style="display: none;">用户管理</a>
<span class="user-info" id="userInfo"></span>
<button type="button" class="btn-logout" id="btnLogout">退出</button>
</div>
</div>
</header>
<div class="toolbar">
@@ -70,25 +67,6 @@
<button type="button" class="btn btn-search" id="btnSearch">搜索</button>
</div>
<div class="filter-row">
<div class="filter-group">
<label>项目进度</label>
<select id="filterProgress" class="input input-filter">
<option value="">全部</option>
<option value="planning">筹备中</option>
<option value="ongoing">进行中</option>
<option value="completed">已竣工</option>
<option value="settled">已结算</option>
</select>
</div>
<div class="filter-group">
<label>项目费用</label>
<select id="filterCost" class="input input-filter">
<option value="">全部</option>
<option value="normal">正常</option>
<option value="over">超支</option>
<option value="under">节余</option>
</select>
</div>
<div class="filter-group">
<label>日期筛选</label>
<select id="dateFilterType" class="input input-filter">
@@ -113,7 +91,7 @@
</div>
<div class="filter-row filter-row-amount">
<div class="filter-group">
<label>合同金额(万元)</label>
<label>中标合同金额(万元)</label>
<input type="number" id="amountMin" class="input input-amount" placeholder="最小" step="0.01" min="0" />
</div>
<div class="filter-group">
@@ -147,6 +125,7 @@
</div>
<div class="pagination" id="pagination">
<span class="pagination-info" id="paginationInfo">共 0 条</span>
<span class="pagination-page" id="paginationPage">第 1 / 1 页</span>
<div class="pagination-btns">
<button type="button" class="btn btn-sm" id="btnPrev" disabled>上一页</button>
<button type="button" class="btn btn-sm" id="btnNext">下一页</button>
@@ -154,11 +133,128 @@
</div>
</section>
<section id="view-statistics" class="view view-statistics">
<header class="page-header">
<button type="button" class="btn-back" id="btnBackFromStats">← 返回列表</button>
<h1 class="page-title">统计</h1>
<div class="header-actions" id="statsHeaderActions"></div>
</header>
<div class="stats-loading" id="statsLoading">正在加载符合当前搜索条件的项目数据…</div>
<div class="stats-content" id="statsContent" style="display: none;">
<p class="stats-desc" id="statsDesc">以下为当前搜索条件下的统计结果</p>
<div class="stats-cards">
<div class="stats-card">
<h3 class="stats-card-title">项目个数</h3>
<div class="stats-card-value" id="statsCount">0</div>
<canvas id="chartCount" class="stats-chart" width="280" height="120"></canvas>
</div>
<div class="stats-card">
<h3 class="stats-card-title">合计合同金额(万元)</h3>
<div class="stats-card-value" id="statsAmount">0</div>
<canvas id="chartAmount" class="stats-chart" width="280" height="120"></canvas>
</div>
<div class="stats-card stats-card-wide">
<h3 class="stats-card-title">工程进度分布</h3>
<canvas id="chartProgress" class="stats-chart stats-chart-pie" width="360" height="240"></canvas>
</div>
<div class="stats-card">
<h3 class="stats-card-title">应收账款总额(万元)</h3>
<div class="stats-card-value" id="statsReceivable">0</div>
<canvas id="chartReceivable" class="stats-chart" width="280" height="120"></canvas>
</div>
<div class="stats-card">
<h3 class="stats-card-title">应付账款总额(万元)</h3>
<div class="stats-card-value" id="statsPayable">0</div>
<canvas id="chartPayable" class="stats-chart" width="280" height="120"></canvas>
</div>
</div>
</div>
<div class="stats-empty" id="statsEmpty" style="display: none;">
<span class="empty-icon">📊</span>
<p>当前搜索条件下暂无项目数据</p>
</div>
</section>
<section id="view-global-stats" class="view view-global-stats">
<header class="page-header">
<button type="button" class="btn-back" id="btnBackFromGlobalStats">← 返回列表</button>
<h1 class="page-title">全局统计</h1>
<div class="header-actions" id="globalStatsHeaderActions"></div>
</header>
<p class="global-stats-desc">按统计类型查看项目,数据来自后端统计 API。</p>
<div class="global-stats-tabs" id="globalStatsTabs" role="tablist">
<button type="button" class="tab global-stats-tab active" data-type="基建工程" role="tab">基建工程</button>
<button type="button" class="tab global-stats-tab" data-type="业扩项目" role="tab">业扩项目</button>
<button type="button" class="tab global-stats-tab" data-type="户表" role="tab">户表</button>
<button type="button" class="tab global-stats-tab" data-type="客户工程" role="tab">客户工程</button>
<button type="button" class="tab global-stats-tab" data-type="营销项目" role="tab">营销项目</button>
<button type="button" class="tab global-stats-tab" data-type="检修-技改-抢修" role="tab">检修-技改-抢修</button>
<button type="button" class="tab global-stats-tab" data-type="其他" role="tab">其他</button>
</div>
<div class="global-stats-content">
<div class="global-stats-loading" id="globalStatsLoading">加载中…</div>
<div class="global-stats-body" id="globalStatsBody" style="display: none;">
<p class="global-stats-total" id="globalStatsTotal">项目数:0</p>
<div class="global-stats-charts-wrap" id="globalStatsChartsWrap">
<div class="global-stats-charts-loading" id="globalStatsChartsLoading">加载图表数据…</div>
<div class="stats-cards global-stats-cards" id="globalStatsCards" style="display: none;">
<div class="stats-card">
<h3 class="stats-card-title">项目个数</h3>
<div class="stats-card-value" id="globalStatsCount">0</div>
<canvas id="chartGlobalCount" class="stats-chart" width="280" height="120"></canvas>
</div>
<div class="stats-card">
<h3 class="stats-card-title">合计合同金额(万元)</h3>
<div class="stats-card-value" id="globalStatsAmount">0</div>
<canvas id="chartGlobalAmount" class="stats-chart" width="280" height="120"></canvas>
</div>
<div class="stats-card stats-card-wide">
<h3 class="stats-card-title">工程进度分布</h3>
<canvas id="chartGlobalProgress" class="stats-chart stats-chart-pie" width="360" height="240"></canvas>
</div>
<div class="stats-card">
<h3 class="stats-card-title">应收账款总额(万元)</h3>
<div class="stats-card-value" id="globalStatsReceivable">0</div>
<canvas id="chartGlobalReceivable" class="stats-chart" width="280" height="120"></canvas>
</div>
<div class="stats-card">
<h3 class="stats-card-title">应付账款总额(万元)</h3>
<div class="stats-card-value" id="globalStatsPayable">0</div>
<canvas id="chartGlobalPayable" class="stats-chart" width="280" height="120"></canvas>
</div>
</div>
</div>
<div class="table-wrap">
<table class="table" id="globalStatsTable">
<thead>
<tr>
<th>合同编号</th>
<th>项目名称</th>
<th>合同金额</th>
<th>业主单位</th>
<th>签订日期</th>
<th>所属项目部</th>
<th>总体成本</th>
<th>项目负责人及电话</th>
<th>操作</th>
</tr>
</thead>
<tbody id="globalStatsTableBody"></tbody>
</table>
</div>
</div>
<div class="global-stats-empty" id="globalStatsEmpty" style="display: none;">
<span class="empty-icon">📋</span>
<p>该类型暂无项目</p>
</div>
</div>
</section>
<section id="view-detail" class="view view-detail">
<header class="page-header">
<button type="button" class="btn-back" id="btnBack">← 返回列表</button>
<h1 class="page-title detail-title" id="detailTitle">项目详情</h1>
<div class="header-actions">
<div class="header-actions" id="detailHeaderActions">
<button type="button" class="btn btn-ghost" id="btnViewLog">查看操作日志</button>
<button type="button" class="btn btn-primary" id="btnSave">
<span class="btn-text">保存</span>
@@ -259,9 +355,77 @@
</div>
</div>
</section>
<section id="view-users" class="view view-users">
<header class="page-header">
<button type="button" class="btn-back" id="btnBackFromUsers">← 返回列表</button>
<h1 class="page-title">用户管理</h1>
<div class="header-actions" id="usersHeaderActions">
<button type="button" class="btn btn-primary" id="btnAddUser">+ 新增用户</button>
</div>
</header>
<div class="table-wrap">
<div class="table-loading" id="usersLoading">加载中…</div>
<div class="table-empty" id="usersEmpty" style="display: none;">
<span class="empty-icon">👤</span>
<p>暂无用户</p>
</div>
<table class="table" id="usersTable">
<thead>
<tr>
<th>账号</th>
<th>显示名称</th>
<th>角色</th>
<th>更新时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="usersTableBody"></tbody>
</table>
</div>
</section>
</main>
</div>
<div class="modal-overlay" id="userModalOverlay" aria-hidden="true"></div>
<div class="modal" id="userModal">
<div class="modal-header">
<h2 class="modal-title" id="userModalTitle">新增用户</h2>
<button type="button" class="modal-close" id="userModalClose">×</button>
</div>
<form id="userForm" class="modal-form">
<input type="hidden" id="userFormId" value="" />
<div class="form-group">
<label for="userFormUsername">账号 <em>*</em></label>
<input type="text" id="userFormUsername" class="input" required placeholder="唯一账号" />
</div>
<div class="form-group">
<label for="userFormPassword">密码 <em>*</em></label>
<input type="password" id="userFormPassword" class="input" placeholder="留空则不修改(编辑时)" />
</div>
<div class="form-group">
<label for="userFormRole">角色 <em>*</em></label>
<select id="userFormRole" class="input" required>
<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="form-group">
<label for="userFormDisplayName">显示名称</label>
<input type="text" id="userFormDisplayName" class="input" placeholder="可选" />
</div>
<div class="modal-actions">
<button type="button" class="btn btn-ghost" id="userModalCancel">取消</button>
<button type="submit" class="btn btn-primary" id="userFormSubmit">保存</button>
</div>
</form>
</div>
<div class="drawer-overlay" id="logOverlay" aria-hidden="true"></div>
<div class="drawer" id="logDrawer">
<div class="drawer-header">
@@ -283,6 +447,7 @@
<!-- Agentation 可视化反馈工具栏(https://github.com/benjitaylor/agentation -->
<div id="agentation-root"></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<script src="js/api.js"></script>
<script src="js/app.js"></script>
<script type="module" src="dist/agentation.js"></script>