Files
tyapi-server/scripts/find_missing_cost_price.go

163 lines
4.0 KiB
Go
Raw Normal View History

2025-11-19 13:41:41 +08:00
package main
import (
"context"
"encoding/csv"
"fmt"
"os"
"strings"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
)
// Product 产品实体(简化版)
type Product struct {
Code string `gorm:"column:code"`
Name string `gorm:"column:name"`
CostPrice *float64 `gorm:"column:cost_price"`
}
func main() {
// 连接数据库
db, err := connectDB()
if err != nil {
fmt.Fprintf(os.Stderr, "连接数据库失败: %v\n", err)
os.Exit(1)
}
ctx := context.Background()
fmt.Println("正在查询数据库中未设置成本价的产品...")
fmt.Println()
// 查询没有设置成本价的产品cost_price IS NULL 或 cost_price = 0
var products []Product
err = db.WithContext(ctx).
Table("product").
Select("code, name, cost_price").
Where("deleted_at IS NULL AND (cost_price IS NULL OR cost_price = 0)").
Order("code ASC").
Find(&products).Error
// 如果单数表名查询失败,尝试复数表名
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
err = db.WithContext(ctx).
Table("products").
Select("code, name, cost_price").
Where("deleted_at IS NULL AND (cost_price IS NULL OR cost_price = 0)").
Order("code ASC").
Find(&products).Error
}
}
if err != nil {
fmt.Fprintf(os.Stderr, "查询失败: %v\n", err)
os.Exit(1)
}
totalCount := len(products)
fmt.Printf("找到 %d 个未设置成本价的产品\n\n", totalCount)
if totalCount == 0 {
fmt.Println("所有产品都已设置成本价!")
return
}
// 打印到控制台
fmt.Println("=== 未设置成本价的产品列表 ===")
fmt.Printf("%-20s %-50s %-15s\n", "产品编号", "产品名称", "成本价")
fmt.Println(strings.Repeat("-", 85))
for _, p := range products {
costPriceStr := "-"
if p.CostPrice != nil && *p.CostPrice != 0 {
costPriceStr = fmt.Sprintf("%.2f", *p.CostPrice)
}
productName := p.Name
if productName == "" {
productName = "-"
}
fmt.Printf("%-20s %-50s %-15s\n", p.Code, productName, costPriceStr)
}
fmt.Println()
// 保存到 CSV 文件
csvFile, err := os.Create("missing_cost_price.csv")
if err != nil {
fmt.Fprintf(os.Stderr, "创建 CSV 文件失败: %v\n", err)
return
}
defer csvFile.Close()
// 写入 UTF-8 BOM
csvFile.WriteString("\xEF\xBB\xBF")
writer := csv.NewWriter(csvFile)
defer writer.Flush()
// 写入表头
headers := []string{"产品编号", "产品名称", "成本价"}
if err := writer.Write(headers); err != nil {
fmt.Fprintf(os.Stderr, "写入 CSV 表头失败: %v\n", err)
return
}
// 写入数据
for _, p := range products {
costPriceStr := ""
if p.CostPrice != nil && *p.CostPrice != 0 {
costPriceStr = fmt.Sprintf("%.2f", *p.CostPrice)
}
productName := p.Name
if productName == "" {
productName = "-"
}
record := []string{p.Code, productName, costPriceStr}
if err := writer.Write(record); err != nil {
fmt.Fprintf(os.Stderr, "写入 CSV 数据失败: %v\n", err)
return
}
}
fmt.Printf("✅ 结果已保存到: missing_cost_price.csv\n")
fmt.Printf("📊 总计: %d 个产品未设置成本价\n", totalCount)
}
// connectDB 连接数据库
func connectDB() (*gorm.DB, error) {
// 数据库连接配置
dsn := "host=1.117.67.95 user=tyapi_user password=Pg9mX4kL8nW2rT5y dbname=tyapi port=25010 sslmode=disable TimeZone=Asia/Shanghai"
// 配置GORM使用单数表名与项目配置一致
gormConfig := &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true, // 使用单数表名
},
Logger: logger.Default.LogMode(logger.Info), // 显示 SQL 日志
}
db, err := gorm.Open(postgres.Open(dsn), gormConfig)
if err != nil {
return nil, fmt.Errorf("连接数据库失败: %w", err)
}
// 测试连接
sqlDB, err := db.DB()
if err != nil {
return nil, fmt.Errorf("获取数据库实例失败: %w", err)
}
if err := sqlDB.Ping(); err != nil {
return nil, fmt.Errorf("数据库连接测试失败: %w", err)
}
fmt.Println("数据库连接成功")
return db, nil
}