refactor: 文件行数超标拆解(Service + Controller 9/16 完成)
- Service 层:energy_service → energize/operations/admin/query 四文件 - Service 层:post_service → helpers/audit + 核心 CRUD 保留 - Service 层:favorite_service → items + 核心文件夹操作保留 - Service 层:auth_service → password + 核心注册/登录保留 - Service 层:notification_service → notify + 核心列表/已读保留 - Service 层:audit_service → review + 核心列表/详情保留 - Controller 层:studio_controller → page/write/api/post_api/action 五文件 - Controller 层:post_controller → page/api/upload 三文件 - Controller 层:comment_controller → list/write/action/upload 四文件 - 清理未使用导入(notification_service.go 移除 fmt)
This commit is contained in:
190
internal/service/energy_energize.go
Normal file
190
internal/service/energy_energize.go
Normal file
@ -0,0 +1,190 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
"metazone.cc/metalab/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Energize 赋能文章
|
||||
// 返回:获得的经验值、错误
|
||||
func (s *EnergyService) Energize(energizerID uint, postID uint, amount int) (int, error) {
|
||||
// 验证赋能量
|
||||
if amount != EnergyEnergize1 && amount != EnergyEnergize2 {
|
||||
return 0, common.ErrInvalidEnergyAmount
|
||||
}
|
||||
|
||||
var expGained int
|
||||
var needExpUpdate bool
|
||||
var expToday time.Time
|
||||
var expTotal int
|
||||
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
txRepo := s.repo.WithTx(tx)
|
||||
var txFundRepo FundStore
|
||||
if s.fundRepo != nil {
|
||||
txFundRepo = s.fundRepo.WithTx(tx)
|
||||
}
|
||||
|
||||
// 1. 检查帖子存在,获取作者
|
||||
post, err := txRepo.FindPostByID(postID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return common.ErrPostNotFound
|
||||
}
|
||||
return fmt.Errorf("查询帖子失败: %w", err)
|
||||
}
|
||||
|
||||
// 2. 不能给自己赋能
|
||||
if post.UserID == energizerID {
|
||||
return common.ErrCannotEnergizeSelf
|
||||
}
|
||||
|
||||
// 3. 检查赋能者域能余额(owner 跳过)
|
||||
energizer, err := txRepo.FindUserByID(energizerID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询用户失败: %w", err)
|
||||
}
|
||||
if energizer.Role != model.RoleOwner && energizer.Energy < amount {
|
||||
return common.ErrInsufficientEnergy
|
||||
}
|
||||
|
||||
// 4. 检查单用户单文章赋能总量 ≤ MaxEnergizePerPost
|
||||
total, err := txRepo.SumUserPostEnergy(energizerID, postID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询赋能记录失败: %w", err)
|
||||
}
|
||||
if total+amount > MaxEnergizePerPost {
|
||||
return common.ErrEnergizeLimitReached
|
||||
}
|
||||
|
||||
// 5. 扣赋能者域能
|
||||
if err := txRepo.AddEnergy(energizerID, -amount); err != nil {
|
||||
return fmt.Errorf("扣减域能失败: %w", err)
|
||||
}
|
||||
|
||||
// 6. 增加被赋能者(文章作者)域能(赋能量的十分之一)
|
||||
receivedAmount := amount / 10 // 1 域能→0.1,2 域能→0.2
|
||||
if err := txRepo.AddEnergy(post.UserID, receivedAmount); err != nil {
|
||||
return fmt.Errorf("增加被赋能者域能失败: %w", err)
|
||||
}
|
||||
|
||||
// 7. 更新 Post.total_energy_received
|
||||
if err := txRepo.IncrPostEnergy(postID, amount); err != nil {
|
||||
return fmt.Errorf("更新文章赋能计数失败: %w", err)
|
||||
}
|
||||
|
||||
// 8. 插入赋能记录
|
||||
eLog := &model.PostEnergizeLog{
|
||||
UserID: energizerID,
|
||||
PostID: postID,
|
||||
Amount: amount,
|
||||
}
|
||||
if err := txRepo.CreateEnergizeLog(eLog); err != nil {
|
||||
return fmt.Errorf("创建赋能记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 9. 写入域能流水 ×2
|
||||
amountDisplay := float64(amount) / 10
|
||||
receivedDisplay := float64(receivedAmount) / 10
|
||||
|
||||
energizerLog := &model.EnergyLog{
|
||||
UserID: energizerID,
|
||||
Amount: -amount,
|
||||
Type: model.EnergyTypeEnergize,
|
||||
RelatedType: "post",
|
||||
RelatedID: postID,
|
||||
Description: fmt.Sprintf("给文章 %d 赋能 %.1f 域能", postID, amountDisplay),
|
||||
}
|
||||
if err := txRepo.CreateEnergyLog(energizerLog); err != nil {
|
||||
return fmt.Errorf("创建赋能者流水失败: %w", err)
|
||||
}
|
||||
|
||||
energizedLog := &model.EnergyLog{
|
||||
UserID: post.UserID,
|
||||
Amount: receivedAmount,
|
||||
Type: model.EnergyTypeEnergized,
|
||||
RelatedType: "post",
|
||||
RelatedID: postID,
|
||||
Description: fmt.Sprintf("文章 %d 被赋能 +%.1f 域能", postID, receivedDisplay),
|
||||
}
|
||||
if err := txRepo.CreateEnergyLog(energizedLog); err != nil {
|
||||
return fmt.Errorf("创建被赋能者流水失败: %w", err)
|
||||
}
|
||||
|
||||
// 10. 赋能税收入公户(差价 = amount - receivedAmount)
|
||||
if txFundRepo != nil {
|
||||
tax := amount - receivedAmount
|
||||
if tax > 0 {
|
||||
if err := txFundRepo.IncrBalance(tax); err != nil {
|
||||
return fmt.Errorf("公户入账失败: %w", err)
|
||||
}
|
||||
taxDisplay := float64(tax) / 10
|
||||
fundLog := &model.FundLog{
|
||||
Amount: tax,
|
||||
Type: model.FundTypeEnergizeTax,
|
||||
RelatedType: "post",
|
||||
RelatedID: postID,
|
||||
Description: fmt.Sprintf("赋能文章 #%d 税收 %.1f 域能,赋能者 uid=%d", postID, taxDisplay, energizerID),
|
||||
}
|
||||
if err := txFundRepo.CreateLog(fundLog); err != nil {
|
||||
return fmt.Errorf("创建公户流水失败: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 11. 计算经验值(溢出截断)—— 在事务内读取以保证一致性
|
||||
loc, _ := time.LoadLocation("Asia/Shanghai")
|
||||
now := time.Now().In(loc)
|
||||
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
|
||||
|
||||
summary, err := txRepo.GetDailyEnergizeExp(energizerID, today)
|
||||
currentDaily := 0
|
||||
if err == nil && summary != nil {
|
||||
currentDaily = summary.ExpEarned
|
||||
}
|
||||
|
||||
expGain := amount // 1域能(DB10) → 10经验, 2域能(DB20) → 20经验
|
||||
expRoom := DailyEnergizeExpCap - currentDaily
|
||||
if expRoom < 0 {
|
||||
expRoom = 0
|
||||
}
|
||||
if expGain > expRoom {
|
||||
expGain = expRoom
|
||||
}
|
||||
|
||||
expGained = expGain
|
||||
if expGain > 0 {
|
||||
needExpUpdate = true
|
||||
expToday = today
|
||||
expTotal = currentDaily + expGain
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 12. 事务提交后,在事务外增加经验 + 更新每日汇总
|
||||
if needExpUpdate {
|
||||
if s.expSvc != nil {
|
||||
if _, _, err := s.expSvc.AddExp(energizerID, expGained); err != nil {
|
||||
return expGained, fmt.Errorf("赋能成功,但增加经验失败: %w", err)
|
||||
}
|
||||
}
|
||||
newSummary := &model.DailyExpSummary{
|
||||
UserID: energizerID,
|
||||
Date: expToday,
|
||||
ExpEarned: expTotal,
|
||||
}
|
||||
if err := s.repo.UpsertDailyExp(newSummary); err != nil {
|
||||
return expGained, fmt.Errorf("赋能成功,但更新经验汇总失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return expGained, nil
|
||||
}
|
||||
Reference in New Issue
Block a user