488 lines
27 KiB
HTML
488 lines
27 KiB
HTML
<!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="/public/static/css/style.css?v=2026071507">
|
||
</head>
|
||
<body>
|
||
<!-- 登录遮罩层 -->
|
||
<div id="login-overlay" class="login-overlay">
|
||
<div class="login-box">
|
||
<h2>订单日报系统</h2>
|
||
<p class="login-subtitle">请登录以继续</p>
|
||
<form id="login-form" onsubmit="handleLogin(event)">
|
||
<div class="form-group">
|
||
<label>用户名</label>
|
||
<input type="text" id="login-username" placeholder="请输入用户名" value="admin">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>密码</label>
|
||
<input type="password" id="login-password" placeholder="请输入密码">
|
||
</div>
|
||
<button type="submit" class="btn btn-primary btn-block" id="login-btn">登 录</button>
|
||
</form>
|
||
<p class="login-tip">默认账号:admin / 123586</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container" id="main-container" style="display: none;">
|
||
<div class="header-bar">
|
||
<h1>订单日报系统</h1>
|
||
<div class="user-info">
|
||
<span id="user-display">admin</span>
|
||
<button class="btn btn-link" onclick="showChangePasswordModal()">修改密码</button>
|
||
<button class="btn btn-link" onclick="handleLogout()">退出登录</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<button class="tab active" onclick="switchTab('config')">配置管理</button>
|
||
<button class="tab" onclick="switchTab('generate')">日报生成</button>
|
||
<button class="tab" onclick="switchTab('history')">历史记录</button>
|
||
<button class="tab" onclick="switchTab('sum-data')">求和数据</button>
|
||
</div>
|
||
|
||
<!-- 配置管理 -->
|
||
<div id="config-tab" class="tab-content active">
|
||
<div class="card">
|
||
<button class="btn btn-primary" onclick="showCreateModal()">创建配置</button>
|
||
<button class="btn btn-info" onclick="exportConfigs()">导出配置</button>
|
||
<button class="btn btn-warning" onclick="downloadTemplate()">下载模板</button>
|
||
<button class="btn btn-success" onclick="document.getElementById('import-config-file').click()">导入配置</button>
|
||
<input type="file" id="import-config-file" accept=".xlsx,.xls" style="display: none;" onchange="importConfigs(event)">
|
||
</div>
|
||
|
||
<div class="card">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th style="min-width: 60px; width: 60px;">序号</th>
|
||
<th>配置名称</th>
|
||
<th>拆分方式</th>
|
||
<th>拆分值</th>
|
||
<th>字段数</th>
|
||
<th>状态</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="config-list">
|
||
<tr><td colspan="7" class="loading">加载中...</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 日报生成 -->
|
||
<div id="generate-tab" class="tab-content">
|
||
<div class="card">
|
||
<div class="alert alert-info" style="margin-bottom: 20px;">
|
||
<strong> 使用说明:</strong><br>
|
||
1. 选择已创建的配置(可多选)<br>
|
||
2. 选择时间范围(可点击预设按钮快速选择)<br>
|
||
3. 点击"生成日报"按钮<br>
|
||
4. 生成成功后,点击"立即下载 Excel 文件"按钮下载,或切换到"历史记录"标签页查看和下载
|
||
</div>
|
||
|
||
<h3 style="margin-bottom: 20px;">生成日报</h3>
|
||
|
||
<div class="form-group">
|
||
<label>选择配置(可多选):</label>
|
||
<div style="margin-bottom: 10px;">
|
||
<button type="button" class="btn btn-sm" onclick="toggleSelectAllConfigs()">全选/取消全选</button>
|
||
</div>
|
||
<div id="generate-config-list" style="max-height: 300px; overflow-y: auto; border: 1px solid var(--border); border-radius: 6px; padding: 10px;">
|
||
<div class="loading">加载中...</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>时间范围:</label>
|
||
<div style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
|
||
<input type="datetime-local" id="start-time" class="form-control">
|
||
<span>至</span>
|
||
<input type="datetime-local" id="end-time" class="form-control">
|
||
<button type="button" class="btn btn-sm" onclick="setPresetTime('yesterday')">昨天</button>
|
||
<button type="button" class="btn btn-sm" onclick="setPresetTime('last3days')">最近 3 天</button>
|
||
<button type="button" class="btn btn-sm" onclick="setPresetTime('last7days')">最近 7 天</button>
|
||
</div>
|
||
</div>
|
||
|
||
<button id="generate-btn" class="btn btn-success" onclick="generateReport()">生成日报</button>
|
||
|
||
<div id="generate-result" style="margin-top: 20px;"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 历史记录 -->
|
||
<div id="history-tab" class="tab-content">
|
||
<div class="card">
|
||
<div style="display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; align-items: center;">
|
||
<select id="history-status-filter" class="form-control" style="width: auto;" onchange="onHistoryStatusChange()">
|
||
<option value="">全部状态</option>
|
||
<option value="1">成功</option>
|
||
<option value="0">失败</option>
|
||
</select>
|
||
<input type="date" id="history-start-date" class="form-control" style="width: auto;">
|
||
<span style="line-height: 38px;">至</span>
|
||
<input type="date" id="history-end-date" class="form-control" style="width: auto;">
|
||
<button class="btn btn-primary" onclick="queryHistoryByDate()">查询</button>
|
||
<button class="btn" onclick="clearHistoryFilter()">清除</button>
|
||
<div style="margin-left: auto; display: flex; gap: 10px; align-items: center;">
|
||
<span style="font-size: 14px; color: #666;">每页显示:</span>
|
||
<select id="history-page-size" class="form-control" style="width: auto;" onchange="onHistoryPageSizeChange()">
|
||
<option value="10">10条</option>
|
||
<option value="20">20条</option>
|
||
<option value="50">50条</option>
|
||
<option value="100">100条</option>
|
||
</select>
|
||
</div>
|
||
<button class="btn btn-danger" onclick="batchDeleteHistory()">批量删除</button>
|
||
<button class="btn btn-danger" onclick="batchDownloadHistory()">批量下载</button>
|
||
</div>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><input type="checkbox" id="select-all-history" onchange="toggleSelectAllHistory()"></th>
|
||
<th>报表日期</th>
|
||
<th>时间范围</th>
|
||
<th>配置名称</th>
|
||
<th>拆分值</th>
|
||
<th>订单数</th>
|
||
<th>总电量(kWh)</th>
|
||
<th>状态</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="history-list">
|
||
<tr><td colspan="9" class="loading">加载中...</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div id="history-pagination" style="margin-top: 20px; display: flex; justify-content: center; gap: 5px;"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 求和数据 -->
|
||
<div id="sum-data-tab" class="tab-content">
|
||
<div class="card">
|
||
<div style="display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; align-items: center;">
|
||
<input type="date" id="sum-data-start-date" class="form-control" style="width: auto;">
|
||
<span style="color: #999;">至</span>
|
||
<input type="date" id="sum-data-end-date" class="form-control" style="width: auto;">
|
||
<input type="text" id="sum-data-config-name" class="form-control" style="width: 180px;" placeholder="配置名称搜索" autocomplete="off">
|
||
<select id="sum-data-source" class="form-control" style="width: auto;" onchange="loadSumData()">
|
||
<option value="">全部来源</option>
|
||
<option value="auto">自动采集</option>
|
||
<option value="manual">手动编辑</option>
|
||
</select>
|
||
<button class="btn btn-primary" onclick="loadSumData()">查询</button>
|
||
<button class="btn" onclick="clearSumDataQuery()">清除</button>
|
||
<button class="btn btn-success" onclick="showAddSumDataModal()">手动添加</button>
|
||
<button class="btn btn-warning" onclick="collectSumDataFromHistory()">从历史采集</button>
|
||
<button class="btn btn-info" onclick="exportSumData()">导出</button>
|
||
<button class="btn btn-secondary" onclick="showSumDataConfigModal()">全局配置</button>
|
||
<button class="btn btn-danger" onclick="batchDeleteSumData()" style="margin-left: auto;">批量删除</button>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table id="sum-data-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="min-width: 40px;"><input type="checkbox" id="select-all-sum-data" onchange="toggleSelectAllSumData()"></th>
|
||
<th style="min-width: 110px;">报表日期</th>
|
||
<th style="min-width: 100px;">配置名称</th>
|
||
<th style="min-width: 120px;">拆分值</th>
|
||
<th id="th-charge-degree" style="min-width: 120px; background: #eff6ff; color: #1d4ed8;">充电电量(kWh) <span style="font-weight: normal; font-size: 11px;">(必选)</span></th>
|
||
<th id="th-total-orders" style="min-width: 80px;">订单数</th>
|
||
<th style="min-width: 90px;">数据来源</th>
|
||
<th style="min-width: 150px;">修改原因/备注</th>
|
||
<th style="min-width: 140px;">操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="sum-data-list">
|
||
<tr><td colspan="12" class="loading">加载中...</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div id="sum-data-pagination" style="margin-top: 20px; display: flex; justify-content: center; gap: 5px;"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 创建/编辑配置模态框 -->
|
||
<div id="config-modal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h2 id="modal-title">创建配置</h2>
|
||
<div style="display: flex; align-items: center; gap: 10px;">
|
||
<button class="btn btn-sm" onclick="closeModal()">取消</button>
|
||
<button class="btn btn-sm btn-primary" onclick="saveConfig()">保存</button>
|
||
<button class="close-btn" onclick="closeModal()">×</button>
|
||
</div>
|
||
</div>
|
||
<div class="modal-body">
|
||
<input type="hidden" id="config-id">
|
||
|
||
<div class="form-group">
|
||
<label>配置名称:</label>
|
||
<input type="text" id="config-name" class="form-control" placeholder="例如:108 路日报" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>拆分方式:</label>
|
||
<select id="split-type" class="form-control" onchange="onSplitTypeChange()">
|
||
<option value="company_id">按企业</option>
|
||
<option value="user_id">按用户</option>
|
||
<option value="station_id">按场站</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label id="split-value-label">选择企业(可多选):</label>
|
||
<div style="margin-bottom: 10px;">
|
||
<input type="text" id="entity-search" class="form-control" placeholder="搜索..." onkeyup="handleSearchEnter(event)" style="width: 200px; display: inline-block;" autocomplete="off">
|
||
<button type="button" class="btn btn-sm" onclick="searchEntities()" style="display: inline-block;">搜索</button>
|
||
<button type="button" class="btn btn-sm" onclick="toggleSelectAllEntities()" style="display: inline-block;">全选/取消全选</button>
|
||
<span id="selected-count" style="margin-left: 10px; color: var(--muted-foreground);">已选:0 个</span>
|
||
</div>
|
||
<div id="entity-list" style="max-height: 300px; overflow-y: auto; border: 1px solid var(--border); border-radius: 6px; padding: 10px;">
|
||
<div class="loading">加载中...</div>
|
||
</div>
|
||
<div id="entity-pagination" style="margin-top: 10px; text-align: center;"></div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>选择字段:</label>
|
||
<div id="field-list" style="max-height: 400px; overflow-y: auto; border: 1px solid var(--border); border-radius: 6px; padding: 10px;">
|
||
<div class="loading">加载中...</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group" id="field-order-section" style="display: none;">
|
||
<label>字段顺序(上移/下移调整):</label>
|
||
<div id="selected-fields-order" style="border: 1px solid var(--border); border-radius: 6px; padding: 10px; min-height: 50px;">
|
||
<div class="empty">请先选择字段</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>求和字段(仅数值类型字段):</label>
|
||
<div id="sum-fields-list" style="border: 1px solid var(--border); border-radius: 6px; padding: 10px; min-height: 50px;">
|
||
<div class="empty">请先选择字段,数值类型字段将显示在此处</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>
|
||
<input type="checkbox" id="merge-telecom" onchange="toggleTelecomVehicleNo()">
|
||
合并特来电平台数据
|
||
</label>
|
||
</div>
|
||
|
||
<div class="form-group" id="telecom-vehicle-section" style="display: none;">
|
||
<label>特来电车量自编号(多个用逗号分隔):</label>
|
||
<input type="text" id="telecom-vehicle-no" class="form-control" placeholder="例如:车 001,车 002" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>自定义服务费单价(元/kWh):</label>
|
||
<input type="number" id="custom-service-fee-price" class="form-control" step="0.0001" placeholder="留空则不启用,设置后按充电电量×单价计算自定义服务费" style="width: 200px;">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>自定义服务费表头名称:</label>
|
||
<input type="text" id="custom-service-fee-name" class="form-control" placeholder="留空则使用默认名称(如:自定义服务费(0.8元/kWh))" style="width: 300px;" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>
|
||
<input type="checkbox" id="show-custom-service-fee" class="inline-checkbox" onchange="onVirtualFieldToggle(this)">
|
||
在报表中显示自定义服务费字段
|
||
</label>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>
|
||
<input type="checkbox" id="show-total-amount" class="inline-checkbox" onchange="onVirtualFieldToggle(this)">
|
||
在报表中显示实收总金额字段(实收电费+自定义服务费)
|
||
</label>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>实收总金额表头名称:</label>
|
||
<input type="text" id="total-amount-name" class="form-control" placeholder="留空则使用默认名称(实收总金额)" style="width: 300px;" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>分时段电量统计:</label>
|
||
<div id="time-period-editor">
|
||
<div style="margin-bottom: 10px;">
|
||
<button type="button" class="btn btn-sm" onclick="clearTimePeriods()">清空</button>
|
||
<button type="button" class="btn btn-sm" onclick="setDefaultTimePeriods()">默认配置</button>
|
||
</div>
|
||
<div id="tp-hours-row" style="display: grid; grid-template-columns: 60px repeat(24, 1fr); gap: 2px; margin-bottom: 10px;"></div>
|
||
<div id="tp-period-rows"></div>
|
||
<div class="time-period-summary" id="time-period-summary"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>
|
||
<input type="checkbox" id="show-monthly-total">
|
||
报表底部显示当月充电量累计总计(数据来源于求和采集表,对账后数据)
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn" onclick="closeModal()">取消</button>
|
||
<button class="btn btn-primary" onclick="saveConfig()">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 求和数据全局配置模态框 -->
|
||
<div id="sum-data-config-modal" class="modal">
|
||
<div class="modal-content" style="max-width: 500px;">
|
||
<div class="modal-header">
|
||
<h2>求和数据全局配置</h2>
|
||
<button class="close-btn" onclick="closeSumDataConfigModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>采集字段(勾选后将在求和数据页面显示和采集,充电电量始终采集):</label>
|
||
<div id="sum-data-config-fields-list" style="border: 1px solid var(--border); border-radius: 6px; padding: 10px; min-height: 100px; max-height: 300px; overflow-y: auto;">
|
||
<div class="loading">加载中...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn" onclick="closeSumDataConfigModal()">取消</button>
|
||
<button class="btn btn-primary" onclick="saveSumDataConfig()">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 添加/编辑求和数据模态框 -->
|
||
<div id="sum-data-modal" class="modal">
|
||
<div class="modal-content" style="max-width: 600px;">
|
||
<div class="modal-header">
|
||
<h2 id="sum-data-modal-title">添加求和数据</h2>
|
||
<button class="close-btn" onclick="closeSumDataModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<input type="hidden" id="sum-data-id">
|
||
|
||
<div class="form-group">
|
||
<label>报表日期:</label>
|
||
<input type="date" id="sum-data-report-date-input" class="form-control">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>配置名称:</label>
|
||
<input type="text" id="sum-data-config-name-input" class="form-control" placeholder="请输入配置名称" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>拆分方式:</label>
|
||
<select id="sum-data-split-type-input" class="form-control">
|
||
<option value="company_id">按企业</option>
|
||
<option value="user_id">按用户</option>
|
||
<option value="station_id">按场站</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>拆分值:</label>
|
||
<input type="text" id="sum-data-split-value-input" class="form-control" placeholder="请输入拆分值" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>拆分显示名称:</label>
|
||
<input type="text" id="sum-data-split-name-input" class="form-control" placeholder="请输入拆分显示名称" autocomplete="off">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>求和字段值:</label>
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
|
||
<div class="form-group" style="margin-bottom: 0;">
|
||
<label>充电电量(kWh) <span style="color: #dc3545;">*</span></label>
|
||
<input type="number" step="0.001" id="sum-data-charge-degree-input" class="form-control" placeholder="充电电量">
|
||
</div>
|
||
<div class="form-group" style="margin-bottom: 0;">
|
||
<label>尖时电量(kWh)</label>
|
||
<input type="number" step="0.001" id="sum-data-peak-degree-input" class="form-control" placeholder="尖时电量">
|
||
</div>
|
||
<div class="form-group" style="margin-bottom: 0;">
|
||
<label>峰时电量(kWh)</label>
|
||
<input type="number" step="0.001" id="sum-data-peak-time-input" class="form-control" placeholder="峰时电量">
|
||
</div>
|
||
<div class="form-group" style="margin-bottom: 0;">
|
||
<label>平时电量(kWh)</label>
|
||
<input type="number" step="0.001" id="sum-data-normal-time-input" class="form-control" placeholder="平时电量">
|
||
</div>
|
||
<div class="form-group" style="margin-bottom: 0;">
|
||
<label>谷时电量(kWh)</label>
|
||
<input type="number" step="0.001" id="sum-data-valley-time-input" class="form-control" placeholder="谷时电量">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>订单数:</label>
|
||
<input type="number" id="sum-data-total-orders-input" class="form-control" placeholder="请输入订单数" value="0">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>修改原因 <span style="color: red;">*</span>:</label>
|
||
<textarea id="sum-data-remark-input" class="form-control" rows="3" placeholder="请输入修改原因(必填)"></textarea>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn" onclick="closeSumDataModal()">取消</button>
|
||
<button class="btn btn-primary" onclick="saveSumData()">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 修改密码弹窗 -->
|
||
<div id="change-password-modal" class="modal">
|
||
<div class="modal-content" style="max-width: 450px;">
|
||
<div class="modal-header">
|
||
<h2>修改密码</h2>
|
||
<span class="close" onclick="closeChangePasswordModal()">×</span>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label>旧密码 <span style="color: red;">*</span>:</label>
|
||
<input type="password" id="old-password" class="form-control" placeholder="请输入旧密码">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>新密码 <span style="color: red;">*</span>:</label>
|
||
<input type="password" id="new-password" class="form-control" placeholder="请输入新密码(至少6位)">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>确认新密码 <span style="color: red;">*</span>:</label>
|
||
<input type="password" id="confirm-password" class="form-control" placeholder="请再次输入新密码">
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn" onclick="closeChangePasswordModal()">取消</button>
|
||
<button class="btn btn-primary" onclick="saveChangePassword()">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- JavaScript 文件 -->
|
||
<script src="/public/static/js/common.js?v=2026072102"></script>
|
||
<script src="/public/static/js/config.js?v=2026071507"></script>
|
||
<script src="/public/static/js/entity.js?v=2026071507"></script>
|
||
<script src="/public/static/js/report.js?v=2026072103"></script>
|
||
<script src="/public/static/js/history.js?v=2026072104"></script>
|
||
<script src="/public/static/js/sum_data.js?v=2026072103"></script>
|
||
</body>
|
||
</html>
|