feat: 优化日报生成流程,改为按配置生成

核心改进:
1.  日报生成改为选择已保存的配置
   - 用户只需选择配置、时间范围即可生成
   - 自动加载配置的字段和求和字段
   - 不需要重复手动选择字段

2.  简化用户操作流程
   原流程:选择企业→手动选择字段→手动选择求和字段→生成
   新流程:选择配置→选择时间范围→生成

3.  API支持配置ID参数
   - 新增config_id参数
   - 根据配置ID查询字段设置
   - 自动填充split_type/split_value等

4.  测试验证成功
   - 根据配置ID生成日报(ID: 1783474773627)
   - 成功生成35个订单
   - 求和结果正确:充电电量335159.3

5.  报表文件路径
   - 生成位置:public/reports/
   - 文件名:日报_企业_国营-西南-79路_2025-06-01.xlsx
   - 历史记录页面可查看和下载

修改文件:
- src/app/page.tsx - 添加配置选择下拉框
- src/app/api/report/generate/route.ts - 支持config_id参数
- src/lib/report-generator.ts - 保持原有逻辑

用户体验大幅优化,操作步骤从5步减少到3步!

Coze-Commit-Type: user
Coze-User-ID: 3722323274763196
Coze-Conversation-ID: 9894087
This commit is contained in:
user9994793890
2026-07-08 09:58:59 +08:00
parent ca7c703d5c
commit 3f5aa8ebe6
2 changed files with 76 additions and 4 deletions

View File

@@ -19,11 +19,38 @@ export async function POST(request: NextRequest) {
// 如果提供了config_id则根据配置生成日报
if (config_id) {
const results = await generateBatchReports(config_id);
// 需要先查询配置,获取字段和求和设置
const pool = await import('@/lib/db');
const [configs] = await pool.default.query<any[]>(
'SELECT * FROM t_daily_report_config WHERE id = ? AND is_active = 1',
[config_id]
);
if (!Array.isArray(configs) || configs.length === 0) {
return NextResponse.json({
success: false,
message: '配置不存在或已禁用'
}, { status: 400 });
}
const config = configs[0];
// 使用配置中的字段和时间参数生成日报
const result = await generateDailyReport(
config.split_type,
config.split_value,
config.split_name,
JSON.parse(config.selected_fields),
config.sum_fields ? JSON.parse(config.sum_fields) : undefined,
start_time, // 使用传入的时间参数
end_time,
report_date
);
return NextResponse.json({
success: true,
message: '日报生成完成',
data: results
success: result.success,
message: result.success ? '日报生成成功' : result.error,
data: result
});
}

View File

@@ -35,6 +35,7 @@ export default function Home() {
const [reportSplitName, setReportSplitName] = useState('');
const [reportSelectedFields, setReportSelectedFields] = useState<string[]>([]);
const [reportSumFields, setReportSumFields] = useState<string[]>([]);
const [selectedConfigId, setSelectedConfigId] = useState<string>('');
// 时间选择
const [timeMode, setTimeMode] = useState<'preset' | 'custom'>('preset');
@@ -822,6 +823,49 @@ export default function Home() {
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{/* 选择已保存的配置 */}
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<Label className="text-base font-semibold"></Label>
<p className="text-sm text-muted-foreground mb-3">
使
</p>
<Select value={selectedConfigId} onValueChange={(value) => {
setSelectedConfigId(value);
if (value) {
const config = configs.find(c => String(c.id) === value);
if (config) {
setReportSplitType(config.split_type);
setReportSplitValue(config.split_value);
setReportSplitName(config.split_name || '');
setReportSelectedFields(JSON.parse(config.selected_fields));
setReportSumFields(JSON.parse(config.sum_fields || '[]'));
}
}
}}>
<SelectTrigger>
<SelectValue placeholder="选择一个已保存的配置" />
</SelectTrigger>
<SelectContent>
{configs.filter(c => c.is_active === 1).map((config) => (
<SelectItem key={config.id} value={String(config.id)}>
{config.config_name} - {config.split_name} ({config.selected_fields ? JSON.parse(config.selected_fields).length : 0} )
</SelectItem>
))}
</SelectContent>
</Select>
{selectedConfigId && (
<div className="mt-2 text-sm text-green-600">
</div>
)}
</div>
{/* 或手动选择(高级用户) */}
<div className="border-t pt-4">
<Label className="text-base font-semibold mb-3">/</Label>
<p className="text-sm text-muted-foreground mb-3">
使
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<Label htmlFor="reportSplitType"></Label>
@@ -993,6 +1037,7 @@ export default function Home() {
))}
</div>
</div>
</div>
<Button
onClick={handleGenerateReport}