refactor: 重构项目结构
- 将 Python 代码移至 analyzer/ 目录(含 venv) - 拆分 Go 服务器代码为模块化结构: - config/: 配置加载 - model/: 请求/响应模型 - service/: 业务逻辑 - handler/: API处理器 - 添加 .gitignore 文件 - 删除旧的独立脚本文件
This commit is contained in:
134
server/service/extractor.go
Normal file
134
server/service/extractor.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"billai-server/model"
|
||||
)
|
||||
|
||||
// ExtractNeedsReview 从输出文件中提取需要复核的记录
|
||||
func ExtractNeedsReview(filePath string, format string) []model.ReviewRecord {
|
||||
if format == "json" {
|
||||
return extractFromJSON(filePath)
|
||||
}
|
||||
return extractFromCSV(filePath)
|
||||
}
|
||||
|
||||
// extractFromCSV 从 CSV 文件提取需要复核的记录
|
||||
func extractFromCSV(filePath string) []model.ReviewRecord {
|
||||
var records []model.ReviewRecord
|
||||
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return records
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
reader := csv.NewReader(file)
|
||||
rows, err := reader.ReadAll()
|
||||
if err != nil || len(rows) < 2 {
|
||||
return records
|
||||
}
|
||||
|
||||
// 找到各列的索引
|
||||
header := rows[0]
|
||||
colIdx := make(map[string]int)
|
||||
for i, col := range header {
|
||||
colIdx[col] = i
|
||||
}
|
||||
|
||||
reviewIdx, ok := colIdx["复核等级"]
|
||||
if !ok {
|
||||
return records
|
||||
}
|
||||
|
||||
// 提取需要复核的记录
|
||||
for _, row := range rows[1:] {
|
||||
if len(row) > reviewIdx && (row[reviewIdx] == "HIGH" || row[reviewIdx] == "LOW") {
|
||||
record := model.ReviewRecord{
|
||||
ReviewLevel: row[reviewIdx],
|
||||
}
|
||||
if idx, ok := colIdx["交易时间"]; ok && len(row) > idx {
|
||||
record.Time = row[idx]
|
||||
}
|
||||
if idx, ok := colIdx["交易分类"]; ok && len(row) > idx {
|
||||
record.Category = row[idx]
|
||||
}
|
||||
if idx, ok := colIdx["交易对方"]; ok && len(row) > idx {
|
||||
record.Merchant = row[idx]
|
||||
}
|
||||
if idx, ok := colIdx["商品说明"]; ok && len(row) > idx {
|
||||
record.Description = row[idx]
|
||||
}
|
||||
if idx, ok := colIdx["收/支"]; ok && len(row) > idx {
|
||||
record.IncomeExpense = row[idx]
|
||||
}
|
||||
if idx, ok := colIdx["金额"]; ok && len(row) > idx {
|
||||
record.Amount = row[idx]
|
||||
}
|
||||
if idx, ok := colIdx["备注"]; ok && len(row) > idx {
|
||||
record.Remark = row[idx]
|
||||
}
|
||||
records = append(records, record)
|
||||
}
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
// extractFromJSON 从 JSON 文件提取需要复核的记录
|
||||
func extractFromJSON(filePath string) []model.ReviewRecord {
|
||||
var records []model.ReviewRecord
|
||||
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return records
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var data []map[string]interface{}
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(&data); err != nil {
|
||||
return records
|
||||
}
|
||||
|
||||
for _, item := range data {
|
||||
reviewLevel, ok := item["复核等级"].(string)
|
||||
if !ok || (reviewLevel != "HIGH" && reviewLevel != "LOW") {
|
||||
continue
|
||||
}
|
||||
|
||||
record := model.ReviewRecord{
|
||||
ReviewLevel: reviewLevel,
|
||||
}
|
||||
|
||||
if v, ok := item["交易时间"].(string); ok {
|
||||
record.Time = v
|
||||
}
|
||||
if v, ok := item["交易分类"].(string); ok {
|
||||
record.Category = v
|
||||
}
|
||||
if v, ok := item["交易对方"].(string); ok {
|
||||
record.Merchant = v
|
||||
}
|
||||
if v, ok := item["商品说明"].(string); ok {
|
||||
record.Description = v
|
||||
}
|
||||
if v, ok := item["收/支"].(string); ok {
|
||||
record.IncomeExpense = v
|
||||
}
|
||||
if v, ok := item["金额"].(string); ok {
|
||||
record.Amount = v
|
||||
}
|
||||
if v, ok := item["备注"].(string); ok {
|
||||
record.Remark = v
|
||||
}
|
||||
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user