60 lines
1.9 KiB
Go
60 lines
1.9 KiB
Go
package billing
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
|
|
"juhe-factory/api/internal/model"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// PrechargeGenerationTask creates a task and reserves its full quoted cost in
|
|
// the same transaction. A zero price is allowed only when the model has an
|
|
// explicit zero-price record; callers must reject a missing price record.
|
|
func PrechargeGenerationTask(tx *gorm.DB, task *model.GenerationTask, unitPrice string, quantity int, remark string) error {
|
|
price, err := strconv.ParseFloat(unitPrice, 64)
|
|
if err != nil || price < 0 || quantity <= 0 {
|
|
return errors.New("生成任务价格无效")
|
|
}
|
|
var amount string
|
|
if err := tx.Raw("SELECT round(?::numeric * ?::numeric,2)::text", unitPrice, quantity).Scan(&amount).Error; err != nil {
|
|
return err
|
|
}
|
|
if amount == "" {
|
|
return errors.New("生成任务价格无效")
|
|
}
|
|
task.EstimatedPoints = amount
|
|
task.PrepaidPoints = amount
|
|
if task.ID == uuid.Nil {
|
|
task.ID = uuid.New()
|
|
}
|
|
|
|
if amountValue, _ := strconv.ParseFloat(amount, 64); amountValue > 0 {
|
|
if _, err := DebitPoints(tx, task.UserID, amount, "generation_hold", task.ID.String(), remark, "generation:hold:"+task.ID.String()); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if err := tx.Create(task).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RefundGenerationTask refunds a prepaid task exactly once. The caller must
|
|
// hold a row lock on task inside the same transaction.
|
|
func RefundGenerationTask(tx *gorm.DB, task *model.GenerationTask, remark string) (bool, error) {
|
|
amount, _ := strconv.ParseFloat(task.PrepaidPoints, 64)
|
|
if task.CostRefunded || amount <= 0 {
|
|
return false, nil
|
|
}
|
|
refunded, err := RefundDebit(tx, task.UserID, "generation:hold:"+task.ID.String(), "generation:refund:"+task.ID.String(),
|
|
"generation_refund", task.ID.String(), remark)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
task.CostRefunded = true
|
|
return refunded, nil
|
|
}
|