163 lines
4.0 KiB
Go
163 lines
4.0 KiB
Go
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
|
||
}
|
||
|