- 新增项目文档和 Docker 配置 - 添加 README.md 和 TODO.md 项目文档 - 为各服务添加 Dockerfile 和 docker-compose 配置 - 重构后端架构 - 新增 adapter 层(HTTP/Python 适配器) - 新增 repository 层(数据访问抽象) - 新增 router 模块统一管理路由 - 新增账单处理 handler - 扩展前端 UI 组件库 - 新增 Calendar、DateRangePicker、Drawer、Popover 等组件 - 集成 shadcn-svelte 组件库 - 增强分析页面功能 - 添加时间范围筛选器(支持本月默认值) - 修复 DateRangePicker 默认值显示问题 - 优化数据获取和展示逻辑 - 完善分析器服务 - 新增 FastAPI 服务接口 - 改进账单清理器实现
95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
// Package python 实现通过子进程调用 Python 脚本的清洗器
|
|
package python
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"billai-server/adapter"
|
|
"billai-server/config"
|
|
)
|
|
|
|
// Cleaner 通过子进程调用 Python 脚本的清洗器实现
|
|
type Cleaner struct {
|
|
pythonPath string // Python 解释器路径
|
|
scriptPath string // 清洗脚本路径
|
|
workDir string // 工作目录
|
|
}
|
|
|
|
// NewCleaner 创建 Python 清洗器
|
|
func NewCleaner() *Cleaner {
|
|
return &Cleaner{
|
|
pythonPath: config.ResolvePath(config.Global.PythonPath),
|
|
scriptPath: config.ResolvePath(config.Global.CleanScript),
|
|
workDir: config.Global.ProjectRoot,
|
|
}
|
|
}
|
|
|
|
// NewCleanerWithConfig 使用自定义配置创建 Python 清洗器
|
|
func NewCleanerWithConfig(pythonPath, scriptPath, workDir string) *Cleaner {
|
|
return &Cleaner{
|
|
pythonPath: pythonPath,
|
|
scriptPath: scriptPath,
|
|
workDir: workDir,
|
|
}
|
|
}
|
|
|
|
// Clean 执行 Python 清洗脚本
|
|
func (c *Cleaner) Clean(inputPath, outputPath string, opts *adapter.CleanOptions) (*adapter.CleanResult, error) {
|
|
// 构建命令参数
|
|
args := []string{c.scriptPath, inputPath, outputPath}
|
|
|
|
if opts != nil {
|
|
if opts.Year != "" {
|
|
args = append(args, "--year", opts.Year)
|
|
}
|
|
if opts.Month != "" {
|
|
args = append(args, "--month", opts.Month)
|
|
}
|
|
if opts.Start != "" {
|
|
args = append(args, "--start", opts.Start)
|
|
}
|
|
if opts.End != "" {
|
|
args = append(args, "--end", opts.End)
|
|
}
|
|
if opts.Format != "" {
|
|
args = append(args, "--format", opts.Format)
|
|
}
|
|
}
|
|
|
|
// 执行 Python 脚本
|
|
fmt.Printf("🐍 执行清洗脚本...\n")
|
|
cmd := exec.Command(c.pythonPath, args...)
|
|
cmd.Dir = c.workDir
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
outputStr := string(output)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("清洗脚本执行失败: %w\n输出: %s", err, outputStr)
|
|
}
|
|
|
|
// 从输出中检测账单类型
|
|
billType := detectBillTypeFromOutput(outputStr)
|
|
|
|
return &adapter.CleanResult{
|
|
BillType: billType,
|
|
Output: outputStr,
|
|
}, nil
|
|
}
|
|
|
|
// detectBillTypeFromOutput 从 Python 脚本输出中检测账单类型
|
|
func detectBillTypeFromOutput(output string) string {
|
|
if strings.Contains(output, "支付宝") {
|
|
return "alipay"
|
|
}
|
|
if strings.Contains(output, "微信") {
|
|
return "wechat"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// 确保 Cleaner 实现了 adapter.Cleaner 接口
|
|
var _ adapter.Cleaner = (*Cleaner)(nil)
|