货币体系: 全平台统一使用积分(POINT)替代人民币(CNY)

后端:
- 模型 currency 默认值 CNY→POINT (MerchantProduct/WalletAccount/FulfillmentOrder)
- DashboardStats TotalSales/TotalFees 从 float64 改为 int64,去掉 /100.0 转换
- 上游 OpenOrderQuery.Amount 从 float64 改为 int64,直接返回积分整数
- 钱包/商品创建时 currency 默认 POINT

前端:
- 去掉 centsToYuan/yuanToCents 转换函数,金额直接用整数积分
- money() 显示从 ¥X.XX 改为 X 积分
- 商品售价/成本表单字段名改回 price_amount/cost_amount,precision 改 0
- 钱包调整表单 amount_yuan→amount,precision 改 0
- 手续费固定金额表单 precision 改 0,label 改积分
- 币种选项 CNY→POINT
- Dashboard 成交金额/手续费 suffix 元→积分,去掉 precision

数据库:
- 新增迁移 004: currency 默认值 CNY→POINT,存量数据更新
This commit is contained in:
yml2213
2026-07-30 14:30:34 +08:00
parent bafe41a3ea
commit 0de0ad9e9d
9 changed files with 52 additions and 69 deletions
+10 -10
View File
@@ -581,12 +581,12 @@ func orderCallbackData(order *model.FulfillmentOrder) map[string]interface{} {
// DashboardStats 仪表盘聚合指标。
type DashboardStats struct {
ProductCount int64 `json:"product_count"`
MerchantCount int64 `json:"merchant_count"`
OrderCount int64 `json:"order_count"`
TotalSales float64 `json:"total_sales"`
TotalFees float64 `json:"total_fees"`
PendingOrderCount int64 `json:"pending_order_count"`
ProductCount int64 `json:"product_count"`
MerchantCount int64 `json:"merchant_count"`
OrderCount int64 `json:"order_count"`
TotalSales int64 `json:"total_sales"`
TotalFees int64 `json:"total_fees"`
PendingOrderCount int64 `json:"pending_order_count"`
}
// Dashboard 汇总商户维度的商品、商户、订单与金额统计。
@@ -605,11 +605,11 @@ func (s *FulfillmentService) Dashboard(merchantID uint, isPlatformAdmin bool) (*
s.db.Model(&model.FulfillmentOrder{}).
Where("merchant_id = ?", merchantID).
Where("payment_status = ?", model.PaymentStatusPaid).
Select("COALESCE(SUM(amount),0) / 100.0").Scan(&stats.TotalSales)
Select("COALESCE(SUM(amount),0)").Scan(&stats.TotalSales)
s.db.Model(&model.FulfillmentOrder{}).
Where("merchant_id = ?", merchantID).
Where("payment_status = ?", model.PaymentStatusPaid).
Select("COALESCE(SUM(service_fee_amount),0) / 100.0").Scan(&stats.TotalFees)
Select("COALESCE(SUM(service_fee_amount),0)").Scan(&stats.TotalFees)
return stats, nil
}
@@ -623,7 +623,7 @@ type OpenOrderQuery struct {
CannotShipReason string `json:"cannot_ship_reason,omitempty"`
Product *OpenOrderProduct `json:"product,omitempty"`
BuyerName string `json:"buyer_name"`
Amount float64 `json:"amount"`
Amount int64 `json:"amount"`
ProviderOrderNo string `json:"provider_order_no,omitempty"`
CreatedAt time.Time `json:"created_at"`
ShippedAt *time.Time `json:"shipped_at"`
@@ -691,7 +691,7 @@ func (s *FulfillmentService) QueryOpenOrder(orderNo string) (*OpenOrderQuery, er
CanShip: canShip,
CannotShipReason: reason,
BuyerName: order.BuyerReference,
Amount: float64(order.Amount) / 100.0,
Amount: order.Amount,
ProviderOrderNo: order.ProviderOrderNo,
CreatedAt: order.CreatedAt,
ShippedAt: order.DeliveredAt,
+2 -2
View File
@@ -32,7 +32,7 @@ func seedFulfillmentMerchant(t *testing.T, db *gorm.DB, code string, balance, st
}
if err := db.Create(&model.WalletAccount{
MerchantID: merchant.ID,
Currency: "CNY",
Currency: "POINT",
AvailableBalance: balance,
}).Error; err != nil {
t.Fatalf("create wallet: %v", err)
@@ -47,7 +47,7 @@ func seedFulfillmentMerchant(t *testing.T, db *gorm.DB, code string, balance, st
SKU: "sku-basic",
DisplayName: "测试商品",
PriceAmount: price,
Currency: "CNY",
Currency: "POINT",
Stock: stock,
Status: model.ProductStatusActive,
}
+2 -2
View File
@@ -91,7 +91,7 @@ func (s *MerchantService) CreateMerchant(in CreateMerchantInput, actorUserID uin
if err := tx.Create(merchant).Error; err != nil {
return err
}
if err := tx.Create(&model.WalletAccount{MerchantID: merchant.ID, Currency: "CNY"}).Error; err != nil {
if err := tx.Create(&model.WalletAccount{MerchantID: merchant.ID, Currency: "POINT"}).Error; err != nil {
return err
}
if err := tx.Create(&model.MerchantMember{
@@ -332,7 +332,7 @@ func (s *MerchantService) CreateMerchantProduct(merchantID uint, in CreateMercha
return nil, errors.New("库存只能为 -1 或非负整数")
}
if in.Currency == "" {
in.Currency = "CNY"
in.Currency = "POINT"
}
in.Currency = strings.ToUpper(in.Currency)
if in.Status == "" {