From 52ac6b7827791ff071c5cae1931d8a2116d6c580 Mon Sep 17 00:00:00 2001 From: yml Date: Fri, 22 May 2026 23:13:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E4=BC=98=E5=8C=96=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/modules/listing/dto.go | 78 +- .../internal/modules/listing/repository.go | 37 +- frontend/components.d.ts | 7 - frontend/src/api/listings.ts | 2 + .../mobile/MobileSellerListingCreateView.vue | 1272 +++++++++++++---- 5 files changed, 1106 insertions(+), 290 deletions(-) diff --git a/backend/internal/modules/listing/dto.go b/backend/internal/modules/listing/dto.go index 8ba2104..628bed1 100644 --- a/backend/internal/modules/listing/dto.go +++ b/backend/internal/modules/listing/dto.go @@ -3,47 +3,49 @@ package listing import "time" type ListingDTO struct { - ID uint64 `json:"id"` - AccountID uint64 `json:"account_id"` - OwnerID uint64 `json:"owner_id"` - OwnerPhone string `json:"owner_phone,omitempty"` - OwnerNickname string `json:"owner_nickname,omitempty"` - Title string `json:"title"` - Description string `json:"description"` - GameName string `json:"game_name"` - ServerRegion string `json:"server_region"` - LoginPlatform string `json:"login_platform"` - RankLevel string `json:"rank_level"` - HafCoinAmount int64 `json:"haf_coin_amount"` - ScreenshotURLS []string `json:"screenshot_urls"` - PriceHourly float64 `json:"price_hourly"` - PriceDaily float64 `json:"price_daily"` - PriceWeekly float64 `json:"price_weekly"` - DepositAmount float64 `json:"deposit_amount"` - MinRentHours int `json:"min_rent_hours"` - MaxRentHours int `json:"max_rent_hours"` - Status string `json:"status"` - ReviewStatus string `json:"review_status"` - ReviewReason string `json:"review_reason"` - PublishedAt *time.Time `json:"published_at"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID uint64 `json:"id"` + AccountID uint64 `json:"account_id"` + OwnerID uint64 `json:"owner_id"` + OwnerPhone string `json:"owner_phone,omitempty"` + OwnerNickname string `json:"owner_nickname,omitempty"` + Title string `json:"title"` + Description string `json:"description"` + GameName string `json:"game_name"` + ServerRegion string `json:"server_region"` + LoginPlatform string `json:"login_platform"` + RankLevel string `json:"rank_level"` + HafCoinAmount int64 `json:"haf_coin_amount"` + AssetSummary map[string]any `json:"asset_summary,omitempty"` + ScreenshotURLS []string `json:"screenshot_urls"` + PriceHourly float64 `json:"price_hourly"` + PriceDaily float64 `json:"price_daily"` + PriceWeekly float64 `json:"price_weekly"` + DepositAmount float64 `json:"deposit_amount"` + MinRentHours int `json:"min_rent_hours"` + MaxRentHours int `json:"max_rent_hours"` + Status string `json:"status"` + ReviewStatus string `json:"review_status"` + ReviewReason string `json:"review_reason"` + PublishedAt *time.Time `json:"published_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type CreateRequest struct { - Title string `json:"title" binding:"required"` - Description string `json:"description"` - ServerRegion string `json:"server_region" binding:"required"` - LoginPlatform string `json:"login_platform" binding:"required"` - RankLevel string `json:"rank_level"` - HafCoinAmount int64 `json:"haf_coin_amount"` - ScreenshotURLS []string `json:"screenshot_urls"` - PriceHourly float64 `json:"price_hourly" binding:"required"` - PriceDaily float64 `json:"price_daily"` - PriceWeekly float64 `json:"price_weekly"` - DepositAmount float64 `json:"deposit_amount" binding:"required"` - MinRentHours int `json:"min_rent_hours" binding:"required"` - MaxRentHours int `json:"max_rent_hours" binding:"required"` + Title string `json:"title" binding:"required"` + Description string `json:"description"` + ServerRegion string `json:"server_region" binding:"required"` + LoginPlatform string `json:"login_platform" binding:"required"` + RankLevel string `json:"rank_level"` + HafCoinAmount int64 `json:"haf_coin_amount"` + AssetSummary map[string]any `json:"asset_summary"` + ScreenshotURLS []string `json:"screenshot_urls"` + PriceHourly float64 `json:"price_hourly" binding:"required"` + PriceDaily float64 `json:"price_daily"` + PriceWeekly float64 `json:"price_weekly"` + DepositAmount float64 `json:"deposit_amount" binding:"required"` + MinRentHours int `json:"min_rent_hours" binding:"required"` + MaxRentHours int `json:"max_rent_hours" binding:"required"` } type UpdateRequest = CreateRequest diff --git a/backend/internal/modules/listing/repository.go b/backend/internal/modules/listing/repository.go index f0c5c63..547dc22 100644 --- a/backend/internal/modules/listing/repository.go +++ b/backend/internal/modules/listing/repository.go @@ -29,6 +29,10 @@ func (r *Repository) Create(ownerID uint64, req CreateRequest) (*ListingDTO, err if err != nil { return err } + assetSummary, err := marshalAssetSummary(req.AssetSummary) + if err != nil { + return err + } account := model.GameAccount{ OwnerID: ownerID, GameName: "delta_force", @@ -38,6 +42,7 @@ func (r *Repository) Create(ownerID uint64, req CreateRequest) (*ListingDTO, err Description: req.Description, RankLevel: req.RankLevel, HafCoinAmount: req.HafCoinAmount, + AssetSummary: assetSummary, ScreenshotURLS: screenshots, Status: "draft", } @@ -82,6 +87,11 @@ func (r *Repository) Update(ownerID uint64, listingID uint64, req UpdateRequest) account.LoginPlatform = req.LoginPlatform account.RankLevel = req.RankLevel account.HafCoinAmount = req.HafCoinAmount + assetSummary, err := marshalAssetSummary(req.AssetSummary) + if err != nil { + return err + } + account.AssetSummary = assetSummary screenshots, err := marshalScreenshots(req.ScreenshotURLS) if err != nil { return err @@ -397,7 +407,7 @@ func (r *Repository) findDTO(where string, args ...any) (*ListingDTO, error) { func (r *Repository) baseQuery() *gorm.DB { return r.db.Table("rental_listings AS l"). Select(`l.*, a.title, a.description, a.game_name, a.server_region, a.login_platform, a.rank_level, - a.haf_coin_amount, a.screenshot_urls, COALESCE(u.phone, '') AS owner_phone, COALESCE(u.nickname, '') AS owner_nickname`). + a.haf_coin_amount, a.asset_summary, a.screenshot_urls, COALESCE(u.phone, '') AS owner_phone, COALESCE(u.nickname, '') AS owner_nickname`). Joins("JOIN game_accounts AS a ON a.id = l.account_id"). Joins("LEFT JOIN users AS u ON u.id = l.owner_id") } @@ -425,6 +435,7 @@ type listingRow struct { LoginPlatform string RankLevel string HafCoinAmount int64 + AssetSummary datatypes.JSON ScreenshotURLS datatypes.JSON } @@ -450,6 +461,7 @@ func (row listingRow) toDTO() ListingDTO { LoginPlatform: row.LoginPlatform, RankLevel: row.RankLevel, HafCoinAmount: row.HafCoinAmount, + AssetSummary: decodeAssetSummary(row.AssetSummary), ScreenshotURLS: decodeScreenshots(row.ScreenshotURLS), PriceHourly: row.PriceHourly, PriceDaily: row.PriceDaily, @@ -478,6 +490,7 @@ func toDTO(account model.GameAccount, listing model.RentalListing) *ListingDTO { LoginPlatform: account.LoginPlatform, RankLevel: account.RankLevel, HafCoinAmount: account.HafCoinAmount, + AssetSummary: decodeAssetSummary(account.AssetSummary), ScreenshotURLS: decodeScreenshots(account.ScreenshotURLS), PriceHourly: listing.PriceHourly, PriceDaily: listing.PriceDaily, @@ -518,6 +531,17 @@ func marshalScreenshots(urls []string) (datatypes.JSON, error) { return datatypes.JSON(raw), nil } +func marshalAssetSummary(summary map[string]any) (datatypes.JSON, error) { + if summary == nil { + return nil, nil + } + raw, err := json.Marshal(summary) + if err != nil { + return nil, err + } + return datatypes.JSON(raw), nil +} + func decodeScreenshots(raw datatypes.JSON) []string { if len(raw) == 0 { return []string{} @@ -529,6 +553,17 @@ func decodeScreenshots(raw datatypes.JSON) []string { return urls } +func decodeAssetSummary(raw datatypes.JSON) map[string]any { + if len(raw) == 0 { + return nil + } + var summary map[string]any + if err := json.Unmarshal(raw, &summary); err != nil { + return nil + } + return summary +} + func appendAuditLog(tx *gorm.DB, actorID uint64, action string, bizType string, bizID uint64, meta AuditMeta, detail map[string]any) error { raw, err := json.Marshal(detail) if err != nil { diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 70802f1..3785345 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -17,21 +17,14 @@ declare module 'vue' { VanCell: typeof import('vant/es')['Cell'] VanCellGroup: typeof import('vant/es')['CellGroup'] VanCheckbox: typeof import('vant/es')['Checkbox'] - VanDropdownItem: typeof import('vant/es')['DropdownItem'] - VanDropdownMenu: typeof import('vant/es')['DropdownMenu'] VanEmpty: typeof import('vant/es')['Empty'] VanField: typeof import('vant/es')['Field'] - VanGrid: typeof import('vant/es')['Grid'] - VanGridItem: typeof import('vant/es')['GridItem'] VanIcon: typeof import('vant/es')['Icon'] - VanImage: typeof import('vant/es')['Image'] VanLoading: typeof import('vant/es')['Loading'] VanNoticeBar: typeof import('vant/es')['NoticeBar'] VanPopup: typeof import('vant/es')['Popup'] VanPullRefresh: typeof import('vant/es')['PullRefresh'] VanSearch: typeof import('vant/es')['Search'] - VanTabbar: typeof import('vant/es')['Tabbar'] - VanTabbarItem: typeof import('vant/es')['TabbarItem'] VanTag: typeof import('vant/es')['Tag'] } } diff --git a/frontend/src/api/listings.ts b/frontend/src/api/listings.ts index cc1046c..aca58b5 100644 --- a/frontend/src/api/listings.ts +++ b/frontend/src/api/listings.ts @@ -13,6 +13,7 @@ export interface Listing { login_platform: string rank_level: string haf_coin_amount: number + asset_summary?: Record screenshot_urls: string[] price_hourly: number price_daily: number @@ -35,6 +36,7 @@ export interface ListingPayload { login_platform: string rank_level: string haf_coin_amount: number + asset_summary?: Record screenshot_urls: string[] price_hourly: number price_daily: number diff --git a/frontend/src/views/mobile/MobileSellerListingCreateView.vue b/frontend/src/views/mobile/MobileSellerListingCreateView.vue index 79ae1c7..67468cd 100644 --- a/frontend/src/views/mobile/MobileSellerListingCreateView.vue +++ b/frontend/src/views/mobile/MobileSellerListingCreateView.vue @@ -1,46 +1,273 @@