兼容接入商品固定价格字段
This commit is contained in:
@@ -32,6 +32,7 @@ type RentalListing struct {
|
|||||||
ID uint64 `gorm:"primaryKey" json:"id"`
|
ID uint64 `gorm:"primaryKey" json:"id"`
|
||||||
AccountID uint64 `gorm:"not null;index" json:"account_id"`
|
AccountID uint64 `gorm:"not null;index" json:"account_id"`
|
||||||
OwnerID uint64 `gorm:"not null;index" json:"owner_id"`
|
OwnerID uint64 `gorm:"not null;index" json:"owner_id"`
|
||||||
|
Price float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price"`
|
||||||
PriceHourly float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price_hourly"`
|
PriceHourly float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price_hourly"`
|
||||||
PriceDaily float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price_daily"`
|
PriceDaily float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price_daily"`
|
||||||
PriceWeekly float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price_weekly"`
|
PriceWeekly float64 `gorm:"type:decimal(12,2);not null;default:0" json:"price_weekly"`
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ type ListingDTO struct {
|
|||||||
AssetSummary map[string]any `json:"asset_summary,omitempty"`
|
AssetSummary map[string]any `json:"asset_summary,omitempty"`
|
||||||
ScreenshotURLS []string `json:"screenshot_urls"`
|
ScreenshotURLS []string `json:"screenshot_urls"`
|
||||||
CoverURL string `json:"cover_url"`
|
CoverURL string `json:"cover_url"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
PriceHourly float64 `json:"price_hourly"`
|
PriceHourly float64 `json:"price_hourly"`
|
||||||
PriceDaily float64 `json:"price_daily"`
|
PriceDaily float64 `json:"price_daily"`
|
||||||
PriceWeekly float64 `json:"price_weekly"`
|
PriceWeekly float64 `json:"price_weekly"`
|
||||||
DepositAmount float64 `json:"deposit_amount"`
|
DepositAmount float64 `json:"deposit_amount"`
|
||||||
IsAccelerated bool `json:"is_accelerated_sale"`
|
IsAccelerated bool `json:"is_accelerated_sale"`
|
||||||
|
InTransaction bool `json:"in_transaction"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
ReviewStatus string `json:"review_status"`
|
ReviewStatus string `json:"review_status"`
|
||||||
ReviewReason string `json:"review_reason"`
|
ReviewReason string `json:"review_reason"`
|
||||||
@@ -40,6 +42,7 @@ type CreateRequest struct {
|
|||||||
HafCoinAmount int64 `json:"haf_coin_amount"`
|
HafCoinAmount int64 `json:"haf_coin_amount"`
|
||||||
AssetSummary map[string]any `json:"asset_summary"`
|
AssetSummary map[string]any `json:"asset_summary"`
|
||||||
ScreenshotURLS []string `json:"screenshot_urls"`
|
ScreenshotURLS []string `json:"screenshot_urls"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
PriceHourly float64 `json:"price_hourly"`
|
PriceHourly float64 `json:"price_hourly"`
|
||||||
PriceDaily float64 `json:"price_daily"`
|
PriceDaily float64 `json:"price_daily"`
|
||||||
PriceWeekly float64 `json:"price_weekly"`
|
PriceWeekly float64 `json:"price_weekly"`
|
||||||
|
|||||||
@@ -60,12 +60,14 @@ func (r *Repository) Create(ownerID uint64, req CreateRequest, reviewRequired bo
|
|||||||
if err := tx.Create(&account).Error; err != nil {
|
if err := tx.Create(&account).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
price := normalizedListingPrice(req)
|
||||||
listing := model.RentalListing{
|
listing := model.RentalListing{
|
||||||
AccountID: account.ID,
|
AccountID: account.ID,
|
||||||
OwnerID: ownerID,
|
OwnerID: ownerID,
|
||||||
PriceHourly: req.PriceHourly,
|
Price: price,
|
||||||
PriceDaily: req.PriceDaily,
|
PriceHourly: listingHourlyPrice(req, price),
|
||||||
PriceWeekly: req.PriceWeekly,
|
PriceDaily: listingDailyPrice(req, price),
|
||||||
|
PriceWeekly: listingWeeklyPrice(req, price),
|
||||||
DepositAmount: req.DepositAmount,
|
DepositAmount: req.DepositAmount,
|
||||||
Status: listingStatus,
|
Status: listingStatus,
|
||||||
ReviewStatus: reviewStatus,
|
ReviewStatus: reviewStatus,
|
||||||
@@ -87,7 +89,7 @@ func (r *Repository) Update(ownerID uint64, listingID uint64, req UpdateRequest,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if listing.Status == "rented" {
|
if listing.Status == "rented" || listing.InTransaction {
|
||||||
return ErrListingLocked
|
return ErrListingLocked
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,9 +110,11 @@ func (r *Repository) Update(ownerID uint64, listingID uint64, req UpdateRequest,
|
|||||||
}
|
}
|
||||||
account.ScreenshotURLS = screenshots
|
account.ScreenshotURLS = screenshots
|
||||||
|
|
||||||
listing.PriceHourly = req.PriceHourly
|
price := normalizedListingPrice(req)
|
||||||
listing.PriceDaily = req.PriceDaily
|
listing.Price = price
|
||||||
listing.PriceWeekly = req.PriceWeekly
|
listing.PriceHourly = listingHourlyPrice(req, price)
|
||||||
|
listing.PriceDaily = listingDailyPrice(req, price)
|
||||||
|
listing.PriceWeekly = listingWeeklyPrice(req, price)
|
||||||
listing.DepositAmount = req.DepositAmount
|
listing.DepositAmount = req.DepositAmount
|
||||||
listingStatus, reviewStatus, publishedAt := initialPublishState(reviewRequired)
|
listingStatus, reviewStatus, publishedAt := initialPublishState(reviewRequired)
|
||||||
listing.Status = listingStatus
|
listing.Status = listingStatus
|
||||||
@@ -137,7 +141,7 @@ func (r *Repository) SubmitReview(ownerID uint64, listingID uint64, reviewRequir
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if listing.Status == "rented" {
|
if listing.Status == "rented" || listing.InTransaction {
|
||||||
return ErrListingLocked
|
return ErrListingLocked
|
||||||
}
|
}
|
||||||
listingStatus, reviewStatus, publishedAt := initialPublishState(reviewRequired)
|
listingStatus, reviewStatus, publishedAt := initialPublishState(reviewRequired)
|
||||||
@@ -215,7 +219,7 @@ func (r *Repository) adminUpdateStatus(adminID uint64, listingID uint64, req Adm
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if listing.Status == "rented" {
|
if listing.Status == "rented" || listing.InTransaction {
|
||||||
return ErrListingLocked
|
return ErrListingLocked
|
||||||
}
|
}
|
||||||
beforeListingStatus := listing.Status
|
beforeListingStatus := listing.Status
|
||||||
@@ -270,7 +274,7 @@ func (r *Repository) Approve(listingID uint64) (*ListingDTO, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if listing.Status == "rented" {
|
if listing.Status == "rented" || listing.InTransaction {
|
||||||
return ErrListingLocked
|
return ErrListingLocked
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -309,7 +313,7 @@ func (r *Repository) Reject(listingID uint64, req ReviewRequest) (*ListingDTO, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if listing.Status == "rented" {
|
if listing.Status == "rented" || listing.InTransaction {
|
||||||
return ErrListingLocked
|
return ErrListingLocked
|
||||||
}
|
}
|
||||||
listing.Status = "draft"
|
listing.Status = "draft"
|
||||||
@@ -346,7 +350,7 @@ func (r *Repository) Offline(ownerID uint64, listingID uint64) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if listing.Status == "rented" {
|
if listing.Status == "rented" || listing.InTransaction {
|
||||||
return ErrListingLocked
|
return ErrListingLocked
|
||||||
}
|
}
|
||||||
listing.Status = "offline"
|
listing.Status = "offline"
|
||||||
@@ -484,6 +488,66 @@ func rowsToDTO(rows []listingRow) []ListingDTO {
|
|||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizedListingPrice(req CreateRequest) float64 {
|
||||||
|
if req.Price > 0 {
|
||||||
|
return req.Price
|
||||||
|
}
|
||||||
|
if req.PriceDaily > 0 {
|
||||||
|
return req.PriceDaily
|
||||||
|
}
|
||||||
|
if req.PriceHourly > 0 {
|
||||||
|
return req.PriceHourly * 24
|
||||||
|
}
|
||||||
|
if req.PriceWeekly > 0 {
|
||||||
|
return req.PriceWeekly / 7
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func listingHourlyPrice(req CreateRequest, price float64) float64 {
|
||||||
|
if req.PriceHourly > 0 {
|
||||||
|
return req.PriceHourly
|
||||||
|
}
|
||||||
|
return price / 24
|
||||||
|
}
|
||||||
|
|
||||||
|
func listingDailyPrice(req CreateRequest, price float64) float64 {
|
||||||
|
if req.PriceDaily > 0 {
|
||||||
|
return req.PriceDaily
|
||||||
|
}
|
||||||
|
return price
|
||||||
|
}
|
||||||
|
|
||||||
|
func listingWeeklyPrice(req CreateRequest, price float64) float64 {
|
||||||
|
if req.PriceWeekly > 0 {
|
||||||
|
return req.PriceWeekly
|
||||||
|
}
|
||||||
|
return price * 7
|
||||||
|
}
|
||||||
|
|
||||||
|
func listingDisplayPrices(price float64, hourly float64, daily float64, weekly float64) (float64, float64, float64, float64) {
|
||||||
|
if price <= 0 {
|
||||||
|
switch {
|
||||||
|
case daily > 0:
|
||||||
|
price = daily
|
||||||
|
case hourly > 0:
|
||||||
|
price = hourly * 24
|
||||||
|
case weekly > 0:
|
||||||
|
price = weekly / 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if daily <= 0 {
|
||||||
|
daily = price
|
||||||
|
}
|
||||||
|
if hourly <= 0 && price > 0 {
|
||||||
|
hourly = price / 24
|
||||||
|
}
|
||||||
|
if weekly <= 0 && price > 0 {
|
||||||
|
weekly = price * 7
|
||||||
|
}
|
||||||
|
return price, hourly, daily, weekly
|
||||||
|
}
|
||||||
|
|
||||||
func publicListings(items []ListingDTO) []ListingDTO {
|
func publicListings(items []ListingDTO) []ListingDTO {
|
||||||
for index := range items {
|
for index := range items {
|
||||||
applyPublicListingURLs(&items[index])
|
applyPublicListingURLs(&items[index])
|
||||||
@@ -501,6 +565,7 @@ func applyPublicListingURLs(item *ListingDTO) {
|
|||||||
func (row listingRow) toDTO() ListingDTO {
|
func (row listingRow) toDTO() ListingDTO {
|
||||||
assetSummary := decodeAssetSummary(row.AssetSummary)
|
assetSummary := decodeAssetSummary(row.AssetSummary)
|
||||||
screenshotURLS := cleanScreenshotURLs(decodeScreenshots(row.ScreenshotURLS))
|
screenshotURLS := cleanScreenshotURLs(decodeScreenshots(row.ScreenshotURLS))
|
||||||
|
price, priceHourly, priceDaily, priceWeekly := listingDisplayPrices(row.Price, row.PriceHourly, row.PriceDaily, row.PriceWeekly)
|
||||||
return ListingDTO{
|
return ListingDTO{
|
||||||
ID: row.ID,
|
ID: row.ID,
|
||||||
AccountID: row.AccountID,
|
AccountID: row.AccountID,
|
||||||
@@ -517,11 +582,13 @@ func (row listingRow) toDTO() ListingDTO {
|
|||||||
AssetSummary: assetSummary,
|
AssetSummary: assetSummary,
|
||||||
ScreenshotURLS: screenshotURLS,
|
ScreenshotURLS: screenshotURLS,
|
||||||
CoverURL: publicCoverURL(row.ID, screenshotURLS, row.Status, row.ReviewStatus),
|
CoverURL: publicCoverURL(row.ID, screenshotURLS, row.Status, row.ReviewStatus),
|
||||||
PriceHourly: row.PriceHourly,
|
Price: price,
|
||||||
PriceDaily: row.PriceDaily,
|
PriceHourly: priceHourly,
|
||||||
PriceWeekly: row.PriceWeekly,
|
PriceDaily: priceDaily,
|
||||||
|
PriceWeekly: priceWeekly,
|
||||||
DepositAmount: row.DepositAmount,
|
DepositAmount: row.DepositAmount,
|
||||||
IsAccelerated: isAcceleratedSale(assetSummary),
|
IsAccelerated: isAcceleratedSale(assetSummary),
|
||||||
|
InTransaction: row.InTransaction,
|
||||||
Status: row.Status,
|
Status: row.Status,
|
||||||
ReviewStatus: row.ReviewStatus,
|
ReviewStatus: row.ReviewStatus,
|
||||||
ReviewReason: row.ReviewReason,
|
ReviewReason: row.ReviewReason,
|
||||||
@@ -534,6 +601,7 @@ func (row listingRow) toDTO() ListingDTO {
|
|||||||
func toDTO(account model.GameAccount, listing model.RentalListing) *ListingDTO {
|
func toDTO(account model.GameAccount, listing model.RentalListing) *ListingDTO {
|
||||||
assetSummary := decodeAssetSummary(account.AssetSummary)
|
assetSummary := decodeAssetSummary(account.AssetSummary)
|
||||||
screenshotURLS := cleanScreenshotURLs(decodeScreenshots(account.ScreenshotURLS))
|
screenshotURLS := cleanScreenshotURLs(decodeScreenshots(account.ScreenshotURLS))
|
||||||
|
price, priceHourly, priceDaily, priceWeekly := listingDisplayPrices(listing.Price, listing.PriceHourly, listing.PriceDaily, listing.PriceWeekly)
|
||||||
return &ListingDTO{
|
return &ListingDTO{
|
||||||
ID: listing.ID,
|
ID: listing.ID,
|
||||||
AccountID: account.ID,
|
AccountID: account.ID,
|
||||||
@@ -548,11 +616,13 @@ func toDTO(account model.GameAccount, listing model.RentalListing) *ListingDTO {
|
|||||||
AssetSummary: assetSummary,
|
AssetSummary: assetSummary,
|
||||||
ScreenshotURLS: screenshotURLS,
|
ScreenshotURLS: screenshotURLS,
|
||||||
CoverURL: publicCoverURL(listing.ID, screenshotURLS, listing.Status, listing.ReviewStatus),
|
CoverURL: publicCoverURL(listing.ID, screenshotURLS, listing.Status, listing.ReviewStatus),
|
||||||
PriceHourly: listing.PriceHourly,
|
Price: price,
|
||||||
PriceDaily: listing.PriceDaily,
|
PriceHourly: priceHourly,
|
||||||
PriceWeekly: listing.PriceWeekly,
|
PriceDaily: priceDaily,
|
||||||
|
PriceWeekly: priceWeekly,
|
||||||
DepositAmount: listing.DepositAmount,
|
DepositAmount: listing.DepositAmount,
|
||||||
IsAccelerated: isAcceleratedSale(assetSummary),
|
IsAccelerated: isAcceleratedSale(assetSummary),
|
||||||
|
InTransaction: listing.InTransaction,
|
||||||
Status: listing.Status,
|
Status: listing.Status,
|
||||||
ReviewStatus: listing.ReviewStatus,
|
ReviewStatus: listing.ReviewStatus,
|
||||||
ReviewReason: listing.ReviewReason,
|
ReviewReason: listing.ReviewReason,
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ func validateRequest(req CreateRequest, rules publishRules) error {
|
|||||||
if strings.TrimSpace(req.ServerRegion) == "" {
|
if strings.TrimSpace(req.ServerRegion) == "" {
|
||||||
return ErrMissingServerRegion
|
return ErrMissingServerRegion
|
||||||
}
|
}
|
||||||
if req.PriceHourly <= 0 {
|
if normalizedListingPrice(req) <= 0 {
|
||||||
return ErrInvalidPrice
|
return ErrInvalidPrice
|
||||||
}
|
}
|
||||||
if req.DepositAmount < 0 {
|
if req.DepositAmount < 0 {
|
||||||
|
|||||||
@@ -28,6 +28,21 @@ func NewRepository(db *gorm.DB) *Repository {
|
|||||||
return &Repository{db: db}
|
return &Repository{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func listingOrderPrice(listing model.RentalListing) float64 {
|
||||||
|
switch {
|
||||||
|
case listing.Price > 0:
|
||||||
|
return listing.Price
|
||||||
|
case listing.PriceDaily > 0:
|
||||||
|
return listing.PriceDaily
|
||||||
|
case listing.PriceHourly > 0:
|
||||||
|
return listing.PriceHourly * float64(internalOrderHours)
|
||||||
|
case listing.PriceWeekly > 0:
|
||||||
|
return listing.PriceWeekly / 7
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) Create(renterID uint64, req CreateRequest) (*OrderDTO, error) {
|
func (r *Repository) Create(renterID uint64, req CreateRequest) (*OrderDTO, error) {
|
||||||
var createdID uint64
|
var createdID uint64
|
||||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||||
@@ -62,7 +77,7 @@ func (r *Repository) Create(renterID uint64, req CreateRequest) (*OrderDTO, erro
|
|||||||
OwnerID: listing.OwnerID,
|
OwnerID: listing.OwnerID,
|
||||||
RenterID: renterID,
|
RenterID: renterID,
|
||||||
RentHours: rentHours,
|
RentHours: rentHours,
|
||||||
RentAmount: listing.PriceHourly * float64(rentHours),
|
RentAmount: listingOrderPrice(listing),
|
||||||
DepositAmount: listing.DepositAmount,
|
DepositAmount: listing.DepositAmount,
|
||||||
PlatformFee: 0,
|
PlatformFee: 0,
|
||||||
AccountSnapshot: snapshot,
|
AccountSnapshot: snapshot,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ CREATE TABLE rental_listings (
|
|||||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||||
account_id BIGINT UNSIGNED NOT NULL,
|
account_id BIGINT UNSIGNED NOT NULL,
|
||||||
owner_id BIGINT UNSIGNED NOT NULL,
|
owner_id BIGINT UNSIGNED NOT NULL,
|
||||||
|
price DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
price_hourly DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
price_hourly DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
price_daily DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
price_daily DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
price_weekly DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
price_weekly DECIMAL(12,2) NOT NULL DEFAULT 0.00,
|
||||||
@@ -66,7 +67,8 @@ CREATE TABLE rental_listings (
|
|||||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
KEY idx_rental_listings_account_id (account_id),
|
KEY idx_rental_listings_account_id (account_id),
|
||||||
KEY idx_rental_listings_owner_id (owner_id),
|
KEY idx_rental_listings_owner_id (owner_id),
|
||||||
KEY idx_rental_listings_filter (status, review_status, price_hourly)
|
KEY idx_rental_listings_filter (status, review_status, price),
|
||||||
|
KEY idx_rental_listings_legacy_filter (status, review_status, price_hourly)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|
||||||
CREATE TABLE rental_orders (
|
CREATE TABLE rental_orders (
|
||||||
|
|||||||
@@ -15,6 +15,32 @@ PREPARE add_listing_in_transaction_stmt FROM @add_listing_in_transaction_sql;
|
|||||||
EXECUTE add_listing_in_transaction_stmt;
|
EXECUTE add_listing_in_transaction_stmt;
|
||||||
DEALLOCATE PREPARE add_listing_in_transaction_stmt;
|
DEALLOCATE PREPARE add_listing_in_transaction_stmt;
|
||||||
|
|
||||||
|
SET @listing_price_exists := (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'rental_listings'
|
||||||
|
AND column_name = 'price'
|
||||||
|
);
|
||||||
|
|
||||||
|
SET @add_listing_price_sql := IF(
|
||||||
|
@listing_price_exists = 0,
|
||||||
|
'ALTER TABLE rental_listings ADD COLUMN price DECIMAL(12,2) NOT NULL DEFAULT 0.00 AFTER owner_id',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE add_listing_price_stmt FROM @add_listing_price_sql;
|
||||||
|
EXECUTE add_listing_price_stmt;
|
||||||
|
DEALLOCATE PREPARE add_listing_price_stmt;
|
||||||
|
|
||||||
|
UPDATE rental_listings
|
||||||
|
SET price = CASE
|
||||||
|
WHEN price_daily > 0 THEN price_daily
|
||||||
|
WHEN price_hourly > 0 THEN price_hourly * 24
|
||||||
|
WHEN price_weekly > 0 THEN price_weekly / 7
|
||||||
|
ELSE price
|
||||||
|
END
|
||||||
|
WHERE price <= 0;
|
||||||
|
|
||||||
INSERT INTO system_configs (`key`, `value`, description)
|
INSERT INTO system_configs (`key`, `value`, description)
|
||||||
VALUES ('order.pending_payment_timeout_minutes', '15', '订单待支付超时取消分钟数')
|
VALUES ('order.pending_payment_timeout_minutes', '15', '订单待支付超时取消分钟数')
|
||||||
ON DUPLICATE KEY UPDATE `key` = VALUES(`key`);
|
ON DUPLICATE KEY UPDATE `key` = VALUES(`key`);
|
||||||
|
|||||||
@@ -16,11 +16,13 @@ export interface Listing {
|
|||||||
asset_summary?: Record<string, unknown>
|
asset_summary?: Record<string, unknown>
|
||||||
screenshot_urls: string[]
|
screenshot_urls: string[]
|
||||||
cover_url: string
|
cover_url: string
|
||||||
|
price: number
|
||||||
price_hourly: number
|
price_hourly: number
|
||||||
price_daily: number
|
price_daily: number
|
||||||
price_weekly: number
|
price_weekly: number
|
||||||
deposit_amount: number
|
deposit_amount: number
|
||||||
is_accelerated_sale?: boolean
|
is_accelerated_sale?: boolean
|
||||||
|
in_transaction: boolean
|
||||||
status: string
|
status: string
|
||||||
review_status: string
|
review_status: string
|
||||||
review_reason: string
|
review_reason: string
|
||||||
@@ -38,6 +40,7 @@ export interface ListingPayload {
|
|||||||
haf_coin_amount: number
|
haf_coin_amount: number
|
||||||
asset_summary?: Record<string, unknown>
|
asset_summary?: Record<string, unknown>
|
||||||
screenshot_urls: string[]
|
screenshot_urls: string[]
|
||||||
|
price: number
|
||||||
price_hourly: number
|
price_hourly: number
|
||||||
price_daily: number
|
price_daily: number
|
||||||
price_weekly: number
|
price_weekly: number
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ function money(value: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listingPrice(row: Listing) {
|
function listingPrice(row: Listing) {
|
||||||
return money(row.price_daily || row.price_hourly)
|
return money(row.price || row.price_daily || row.price_hourly)
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractObjectKey(url: string) {
|
function extractObjectKey(url: string) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ function openEvidence(row: Listing) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listingPrice(row: Listing) {
|
function listingPrice(row: Listing) {
|
||||||
return `¥${Number(row.price_daily || row.price_hourly || 0).toFixed(2)}`
|
return `¥${Number(row.price || row.price_daily || row.price_hourly || 0).toFixed(2)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractObjectKey(url: string) {
|
function extractObjectKey(url: string) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function money(value: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listingPrice(row: Listing) {
|
function listingPrice(row: Listing) {
|
||||||
return money(row.price_daily || row.price_hourly)
|
return money(row.price || row.price_daily || row.price_hourly)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ownerName(row: Listing) {
|
function ownerName(row: Listing) {
|
||||||
|
|||||||
@@ -439,6 +439,7 @@ async function handleSubmit() {
|
|||||||
haf_coin_amount: coinMAmount.value * 1000000,
|
haf_coin_amount: coinMAmount.value * 1000000,
|
||||||
asset_summary: buildAssetSummary(),
|
asset_summary: buildAssetSummary(),
|
||||||
screenshot_urls: screenshotUrls.value,
|
screenshot_urls: screenshotUrls.value,
|
||||||
|
price: dailyPrice,
|
||||||
price_hourly: hourlyPrice,
|
price_hourly: hourlyPrice,
|
||||||
price_daily: dailyPrice,
|
price_daily: dailyPrice,
|
||||||
price_weekly: roundMoney(dailyPrice * 7),
|
price_weekly: roundMoney(dailyPrice * 7),
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function readError(error: unknown, fallback: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listingPrice(item: Listing) {
|
function listingPrice(item: Listing) {
|
||||||
return Number(item.price_daily || item.price_hourly || 0).toFixed(2);
|
return Number(item.price || item.price_daily || item.price_hourly || 0).toFixed(2);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -104,10 +104,11 @@ function listingPrice(item: Listing) {
|
|||||||
type="warning"
|
type="warning"
|
||||||
size="large"
|
size="large"
|
||||||
:loading="ordering"
|
:loading="ordering"
|
||||||
|
:disabled="listing.in_transaction"
|
||||||
class="full-control"
|
class="full-control"
|
||||||
@click="handleCreateOrder"
|
@click="handleCreateOrder"
|
||||||
>
|
>
|
||||||
立即下单
|
{{ listing.in_transaction ? "交易中" : "立即下单" }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form>
|
</el-form>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -17,18 +17,17 @@ const form = reactive({
|
|||||||
login_platform: 'QQ',
|
login_platform: 'QQ',
|
||||||
rank_level: '',
|
rank_level: '',
|
||||||
haf_coin_amount: 0,
|
haf_coin_amount: 0,
|
||||||
price_hourly: 5,
|
price: 50,
|
||||||
price_daily: 50,
|
|
||||||
price_weekly: 300,
|
|
||||||
deposit_amount: 100,
|
deposit_amount: 100,
|
||||||
})
|
})
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const price = Number(form.price_daily || 0)
|
const price = Number(form.price || 0)
|
||||||
const listing = await createListing({
|
const listing = await createListing({
|
||||||
...form,
|
...form,
|
||||||
|
price,
|
||||||
price_hourly: Math.max(Math.round((price / 24) * 100) / 100, 0.01),
|
price_hourly: Math.max(Math.round((price / 24) * 100) / 100, 0.01),
|
||||||
price_daily: price,
|
price_daily: price,
|
||||||
price_weekly: Math.round(price * 7 * 100) / 100,
|
price_weekly: Math.round(price * 7 * 100) / 100,
|
||||||
@@ -125,7 +124,7 @@ function readError(error: unknown, fallback: string) {
|
|||||||
<el-input-number v-model="form.haf_coin_amount" :min="0" />
|
<el-input-number v-model="form.haf_coin_amount" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="价格">
|
<el-form-item label="价格">
|
||||||
<el-input-number v-model="form.price_daily" :min="0" />
|
<el-input-number v-model="form.price" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="押金">
|
<el-form-item label="押金">
|
||||||
<el-input-number v-model="form.deposit_amount" :min="0" />
|
<el-input-number v-model="form.deposit_amount" :min="0" />
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function readSellerPrice(row: Listing) {
|
|||||||
const price = Number((breakdown as Record<string, unknown>).seller_total_price)
|
const price = Number((breakdown as Record<string, unknown>).seller_total_price)
|
||||||
if (Number.isFinite(price) && price > 0) return price
|
if (Number.isFinite(price) && price > 0) return price
|
||||||
}
|
}
|
||||||
return Number(row.price_daily || row.price_hourly || 0)
|
return Number(row.price || row.price_daily || row.price_hourly || 0)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user