增加上传接口
This commit is contained in:
@@ -3,6 +3,7 @@ package listing
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -81,6 +82,83 @@ func (r *Repository) Create(ownerID uint64, req CreateRequest, reviewRequired bo
|
||||
return dto, err
|
||||
}
|
||||
|
||||
type externalUploadCreate struct {
|
||||
UploaderName string
|
||||
ClientUploadTime *time.Time
|
||||
ClientIP string
|
||||
RawPayload []byte
|
||||
ParsedPayload []byte
|
||||
}
|
||||
|
||||
func (r *Repository) CreateFromExternalUpload(upload externalUploadCreate, req CreateRequest) (*ListingDTO, error) {
|
||||
var dto *ListingDTO
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
admin, err := r.findActiveUploadAdmin(tx, upload.UploaderName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
owner, err := r.ensureUploadOwnerUser(tx, admin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
screenshots, err := marshalScreenshots(req.ScreenshotURLS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assetSummary, err := marshalAssetSummary(req.AssetSummary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
account := model.GameAccount{
|
||||
OwnerID: owner.ID,
|
||||
GameName: "delta_force",
|
||||
ServerRegion: req.ServerRegion,
|
||||
LoginPlatform: req.LoginPlatform,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
RankLevel: req.RankLevel,
|
||||
HafCoinAmount: req.HafCoinAmount,
|
||||
AssetSummary: assetSummary,
|
||||
ScreenshotURLS: screenshots,
|
||||
Status: "draft",
|
||||
}
|
||||
if err := tx.Create(&account).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
listing := model.RentalListing{
|
||||
AccountID: account.ID,
|
||||
OwnerID: owner.ID,
|
||||
Price: normalizedListingPrice(req),
|
||||
DepositAmount: roundMoney(req.DepositAmount),
|
||||
Status: "draft",
|
||||
ReviewStatus: "pending",
|
||||
}
|
||||
if err := tx.Create(&listing).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
matchedAdminID := admin.ID
|
||||
ownerID := owner.ID
|
||||
listingID := listing.ID
|
||||
uploadRow := model.ListingUpload{
|
||||
UploaderName: upload.UploaderName,
|
||||
MatchedAdminID: &matchedAdminID,
|
||||
OwnerID: &ownerID,
|
||||
ClientUploadTime: upload.ClientUploadTime,
|
||||
ClientIP: upload.ClientIP,
|
||||
RawPayload: datatypes.JSON(upload.RawPayload),
|
||||
ParsedPayload: datatypes.JSON(upload.ParsedPayload),
|
||||
ListingID: &listingID,
|
||||
Status: "draft_created",
|
||||
}
|
||||
if err := tx.Create(&uploadRow).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
dto = toDTO(account, listing)
|
||||
return nil
|
||||
})
|
||||
return dto, err
|
||||
}
|
||||
|
||||
func (r *Repository) Update(ownerID uint64, listingID uint64, req UpdateRequest, reviewRequired bool) (*ListingDTO, error) {
|
||||
var dto *ListingDTO
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
@@ -224,6 +302,68 @@ func (r *Repository) applyAdminListFilters(db *gorm.DB, query AdminListQuery) *g
|
||||
return db
|
||||
}
|
||||
|
||||
func (r *Repository) findActiveUploadAdmin(tx *gorm.DB, uploaderName string) (*model.AdminUser, error) {
|
||||
uploaderName = strings.TrimSpace(uploaderName)
|
||||
var admin model.AdminUser
|
||||
if err := tx.Where("username = ? AND status = ?", uploaderName, "active").First(&admin).Error; err == nil {
|
||||
return &admin, nil
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var admins []model.AdminUser
|
||||
if err := tx.Where("nickname = ? AND status = ?", uploaderName, "active").Limit(2).Find(&admins).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(admins) {
|
||||
case 0:
|
||||
return nil, ErrUploaderNotFound
|
||||
case 1:
|
||||
return &admins[0], nil
|
||||
default:
|
||||
return nil, ErrUploaderAmbiguous
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repository) ensureUploadOwnerUser(tx *gorm.DB, admin *model.AdminUser) (*model.User, error) {
|
||||
phone := fmt.Sprintf("admin:%d", admin.ID)
|
||||
nickname := strings.TrimSpace(admin.Nickname)
|
||||
if nickname == "" {
|
||||
nickname = admin.Username
|
||||
}
|
||||
var user model.User
|
||||
err := tx.Where("phone = ?", phone).First(&user).Error
|
||||
if err == nil {
|
||||
updates := map[string]any{
|
||||
"nickname": nickname,
|
||||
"status": "active",
|
||||
"realname_status": "verified",
|
||||
}
|
||||
if err := tx.Model(&user).Updates(updates).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Nickname = nickname
|
||||
user.Status = "active"
|
||||
user.RealnameStatus = "verified"
|
||||
return &user, nil
|
||||
}
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
user = model.User{
|
||||
Phone: phone,
|
||||
Nickname: nickname,
|
||||
RealnameStatus: "verified",
|
||||
RiskStatus: "normal",
|
||||
CreditScore: 100,
|
||||
Status: "active",
|
||||
}
|
||||
if err := tx.Create(&user).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *Repository) FindAdmin(listingID uint64) (*ListingDTO, error) {
|
||||
return r.findDTO("l.id = ?", listingID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user