增加线下提号店铺管理
This commit is contained in:
@@ -17,6 +17,7 @@ type AdminPickup struct {
|
|||||||
OwnerID uint64 `gorm:"not null;index" json:"owner_id"`
|
OwnerID uint64 `gorm:"not null;index" json:"owner_id"`
|
||||||
AdminID uint64 `gorm:"not null" json:"admin_id"`
|
AdminID uint64 `gorm:"not null" json:"admin_id"`
|
||||||
Platform string `gorm:"size:32;not null;default:''" json:"platform"`
|
Platform string `gorm:"size:32;not null;default:''" json:"platform"`
|
||||||
|
ShopName string `gorm:"size:100;not null;default:'';index" json:"shop_name"`
|
||||||
ListingPriceCent int64 `gorm:"not null;default:0" json:"listing_price_cent"`
|
ListingPriceCent int64 `gorm:"not null;default:0" json:"listing_price_cent"`
|
||||||
OwnerPriceCent int64 `gorm:"not null;default:0" json:"owner_price_cent"`
|
OwnerPriceCent int64 `gorm:"not null;default:0" json:"owner_price_cent"`
|
||||||
WebsiteProfitCent int64 `gorm:"not null;default:0" json:"website_profit_cent"`
|
WebsiteProfitCent int64 `gorm:"not null;default:0" json:"website_profit_cent"`
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ type PickupDTO struct {
|
|||||||
OwnerPhone string `json:"owner_phone"`
|
OwnerPhone string `json:"owner_phone"`
|
||||||
AdminID uint64 `json:"admin_id"`
|
AdminID uint64 `json:"admin_id"`
|
||||||
Platform string `json:"platform"`
|
Platform string `json:"platform"`
|
||||||
|
ShopName string `json:"shop_name"`
|
||||||
ListingPriceCent int64 `json:"listing_price_cent"`
|
ListingPriceCent int64 `json:"listing_price_cent"`
|
||||||
OwnerPriceCent int64 `json:"owner_price_cent"`
|
OwnerPriceCent int64 `json:"owner_price_cent"`
|
||||||
WebsiteProfitCent int64 `json:"website_profit_cent"`
|
WebsiteProfitCent int64 `json:"website_profit_cent"`
|
||||||
@@ -56,6 +57,7 @@ type PickupDTO struct {
|
|||||||
type CreateRequest struct {
|
type CreateRequest struct {
|
||||||
ListingID uint64 `json:"listing_id" binding:"required"`
|
ListingID uint64 `json:"listing_id" binding:"required"`
|
||||||
Platform string `json:"platform"`
|
Platform string `json:"platform"`
|
||||||
|
ShopName string `json:"shop_name" binding:"max=100"`
|
||||||
ProfitAmountCent int64 `json:"profit_amount_cent"`
|
ProfitAmountCent int64 `json:"profit_amount_cent"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
}
|
}
|
||||||
@@ -80,6 +82,7 @@ type AdminPickupQuery struct {
|
|||||||
PageSize int
|
PageSize int
|
||||||
Keyword string
|
Keyword string
|
||||||
Status string
|
Status string
|
||||||
|
ShopName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SellerPickupQuery struct {
|
type SellerPickupQuery struct {
|
||||||
|
|||||||
@@ -122,6 +122,16 @@ func (h *Handler) List(c *gin.Context) {
|
|||||||
response.OK(c, result)
|
response.OK(c, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShopOptions 返回后台提号已使用的店铺名称。
|
||||||
|
func (h *Handler) ShopOptions(c *gin.Context) {
|
||||||
|
items, err := h.service.ListShopNames(c.Request.Context(), c.Query("platform"))
|
||||||
|
if err != nil {
|
||||||
|
writePickupError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OK(c, items)
|
||||||
|
}
|
||||||
|
|
||||||
// Detail 提号订单详情(管理员)
|
// Detail 提号订单详情(管理员)
|
||||||
func (h *Handler) Detail(c *gin.Context) {
|
func (h *Handler) Detail(c *gin.Context) {
|
||||||
id, ok := parseID(c)
|
id, ok := parseID(c)
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func parseAdminQuery(c *gin.Context) AdminPickupQuery {
|
|||||||
PageSize: pageSize,
|
PageSize: pageSize,
|
||||||
Keyword: c.Query("keyword"),
|
Keyword: c.Query("keyword"),
|
||||||
Status: c.Query("status"),
|
Status: c.Query("status"),
|
||||||
|
ShopName: c.Query("shop_name"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ func (r *Repository) Create(ctx context.Context, req CreateRequest, adminID uint
|
|||||||
OwnerID: listing.OwnerID,
|
OwnerID: listing.OwnerID,
|
||||||
AdminID: adminID,
|
AdminID: adminID,
|
||||||
Platform: strings.TrimSpace(req.Platform),
|
Platform: strings.TrimSpace(req.Platform),
|
||||||
|
ShopName: strings.TrimSpace(req.ShopName),
|
||||||
ListingPriceCent: priceSnapshot.ListingPriceCent,
|
ListingPriceCent: priceSnapshot.ListingPriceCent,
|
||||||
OwnerPriceCent: priceSnapshot.OwnerPriceCent,
|
OwnerPriceCent: priceSnapshot.OwnerPriceCent,
|
||||||
WebsiteProfitCent: priceSnapshot.WebsiteProfitCent,
|
WebsiteProfitCent: priceSnapshot.WebsiteProfitCent,
|
||||||
@@ -145,6 +146,7 @@ func (r *Repository) Create(ctx context.Context, req CreateRequest, adminID uint
|
|||||||
"pickup_no": pickupNo,
|
"pickup_no": pickupNo,
|
||||||
"listing_id": listing.ID,
|
"listing_id": listing.ID,
|
||||||
"platform": pickup.Platform,
|
"platform": pickup.Platform,
|
||||||
|
"shop_name": pickup.ShopName,
|
||||||
"profit_cent": pickup.ProfitAmountCent,
|
"profit_cent": pickup.ProfitAmountCent,
|
||||||
},
|
},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -417,6 +419,9 @@ func (r *Repository) ListAdmin(ctx context.Context, query AdminPickupQuery) (*Pa
|
|||||||
if status := strings.TrimSpace(query.Status); status != "" {
|
if status := strings.TrimSpace(query.Status); status != "" {
|
||||||
db = db.Where("p.status = ?", status)
|
db = db.Where("p.status = ?", status)
|
||||||
}
|
}
|
||||||
|
if shopName := strings.TrimSpace(query.ShopName); shopName != "" {
|
||||||
|
db = db.Where("p.shop_name = ?", shopName)
|
||||||
|
}
|
||||||
if kw := strings.TrimSpace(query.Keyword); kw != "" {
|
if kw := strings.TrimSpace(query.Keyword); kw != "" {
|
||||||
like := "%" + kw + "%"
|
like := "%" + kw + "%"
|
||||||
db = db.Where("p.pickup_no LIKE ? OR l.listing_no LIKE ? OR a.title LIKE ?", like, like, like)
|
db = db.Where("p.pickup_no LIKE ? OR l.listing_no LIKE ? OR a.title LIKE ?", like, like, like)
|
||||||
@@ -424,6 +429,23 @@ func (r *Repository) ListAdmin(ctx context.Context, query AdminPickupQuery) (*Pa
|
|||||||
return r.paginatePickups(db, query.Page, query.PageSize, false)
|
return r.paginatePickups(db, query.Page, query.PageSize, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListShopNames 返回历史提号中已使用的店铺名称,供后台选择和筛选。
|
||||||
|
func (r *Repository) ListShopNames(ctx context.Context, platform string) ([]string, error) {
|
||||||
|
if r == nil || r.db == nil {
|
||||||
|
return nil, ErrDependencyUnavailable
|
||||||
|
}
|
||||||
|
db := r.db.WithContext(ctx).Model(&model.AdminPickup{}).
|
||||||
|
Where("shop_name <> ''")
|
||||||
|
if value := strings.TrimSpace(platform); value != "" {
|
||||||
|
db = db.Where("platform = ?", value)
|
||||||
|
}
|
||||||
|
names := make([]string, 0)
|
||||||
|
if err := db.Distinct("shop_name").Order("shop_name ASC").Limit(200).Pluck("shop_name", &names).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return names, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) ListForSeller(ctx context.Context, ownerID uint64, query SellerPickupQuery) (*PaginatedResult, error) {
|
func (r *Repository) ListForSeller(ctx context.Context, ownerID uint64, query SellerPickupQuery) (*PaginatedResult, error) {
|
||||||
if r == nil || r.db == nil {
|
if r == nil || r.db == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
@@ -453,6 +475,7 @@ func (r *Repository) paginatePickups(db *gorm.DB, page, pageSize int, sellerView
|
|||||||
item.WebsiteProfitCent = 0
|
item.WebsiteProfitCent = 0
|
||||||
item.ProfitAmountCent = 0
|
item.ProfitAmountCent = 0
|
||||||
item.BuyerRatio = 0
|
item.BuyerRatio = 0
|
||||||
|
item.ShopName = ""
|
||||||
}
|
}
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
}
|
}
|
||||||
@@ -521,6 +544,7 @@ func (row pickupRow) toDTO() PickupDTO {
|
|||||||
OwnerPhone: row.OwnerPhone,
|
OwnerPhone: row.OwnerPhone,
|
||||||
AdminID: row.AdminID,
|
AdminID: row.AdminID,
|
||||||
Platform: row.Platform,
|
Platform: row.Platform,
|
||||||
|
ShopName: row.ShopName,
|
||||||
ListingPriceCent: row.ListingPriceCent,
|
ListingPriceCent: row.ListingPriceCent,
|
||||||
OwnerPriceCent: row.OwnerPriceCent,
|
OwnerPriceCent: row.OwnerPriceCent,
|
||||||
WebsiteProfitCent: row.WebsiteProfitCent,
|
WebsiteProfitCent: row.WebsiteProfitCent,
|
||||||
|
|||||||
@@ -125,6 +125,62 @@ func TestRepositoryUpdateProfitRejectsCompleted(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRepositoryListAdminFiltersShopName(t *testing.T) {
|
||||||
|
repo, db := newPickupTestRepo(t)
|
||||||
|
first := seedPickup(t, db, StatusPickingUp)
|
||||||
|
if err := db.Model(&first).Updates(map[string]any{
|
||||||
|
"platform": "淘宝",
|
||||||
|
"shop_name": "大锤一店",
|
||||||
|
}).Error; err != nil {
|
||||||
|
t.Fatalf("设置第一条提号店铺失败: %v", err)
|
||||||
|
}
|
||||||
|
second := first
|
||||||
|
second.ID = 0
|
||||||
|
second.PickupNo = "PK-PROFIT-002"
|
||||||
|
second.ShopName = "大锤二店"
|
||||||
|
if err := db.Create(&second).Error; err != nil {
|
||||||
|
t.Fatalf("创建第二条提号记录失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := repo.ListAdmin(t.Context(), AdminPickupQuery{ShopName: " 大锤一店 "})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ListAdmin() error = %v", err)
|
||||||
|
}
|
||||||
|
if result.Total != 1 || len(result.Items) != 1 {
|
||||||
|
t.Fatalf("店铺筛选结果 = total %d, items %d, want 1", result.Total, len(result.Items))
|
||||||
|
}
|
||||||
|
if result.Items[0].ShopName != "大锤一店" {
|
||||||
|
t.Fatalf("店铺名称 = %q, want 大锤一店", result.Items[0].ShopName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepositoryListShopNamesReturnsDistinctPlatformOptions(t *testing.T) {
|
||||||
|
repo, db := newPickupTestRepo(t)
|
||||||
|
first := seedPickup(t, db, StatusPickingUp)
|
||||||
|
if err := db.Model(&first).Updates(map[string]any{
|
||||||
|
"platform": "淘宝",
|
||||||
|
"shop_name": "大锤一店",
|
||||||
|
}).Error; err != nil {
|
||||||
|
t.Fatalf("设置第一条提号店铺失败: %v", err)
|
||||||
|
}
|
||||||
|
for index, row := range []model.AdminPickup{
|
||||||
|
{PickupNo: "PK-SHOP-002", ListingID: first.ListingID, AccountID: first.AccountID, OwnerID: first.OwnerID, AdminID: 1, Platform: "淘宝", ShopName: "大锤一店", Status: StatusPickingUp},
|
||||||
|
{PickupNo: "PK-SHOP-003", ListingID: first.ListingID, AccountID: first.AccountID, OwnerID: first.OwnerID, AdminID: 1, Platform: "拼多多", ShopName: "大锤二店", Status: StatusPickingUp},
|
||||||
|
} {
|
||||||
|
if err := db.Create(&row).Error; err != nil {
|
||||||
|
t.Fatalf("创建第 %d 条店铺选项失败: %v", index+2, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
names, err := repo.ListShopNames(t.Context(), "淘宝")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ListShopNames() error = %v", err)
|
||||||
|
}
|
||||||
|
if len(names) != 1 || names[0] != "大锤一店" {
|
||||||
|
t.Fatalf("淘宝店铺选项 = %v, want [大锤一店]", names)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func assertInt64(t *testing.T, name string, got, want int64) {
|
func assertInt64(t *testing.T, name string, got, want int64) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if got != want {
|
if got != want {
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ func (s *Service) ListAdmin(ctx context.Context, query AdminPickupQuery) (*Pagin
|
|||||||
return s.repo.ListAdmin(ctx, query)
|
return s.repo.ListAdmin(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) ListShopNames(ctx context.Context, platform string) ([]string, error) {
|
||||||
|
if s.repo == nil {
|
||||||
|
return nil, ErrDependencyUnavailable
|
||||||
|
}
|
||||||
|
return s.repo.ListShopNames(ctx, platform)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) ListForSeller(ctx context.Context, ownerID uint64, query SellerPickupQuery) (*PaginatedResult, error) {
|
func (s *Service) ListForSeller(ctx context.Context, ownerID uint64, query SellerPickupQuery) (*PaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
|
|||||||
@@ -594,6 +594,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
|||||||
// 管理员线下提号(独立于正常订单流程)
|
// 管理员线下提号(独立于正常订单流程)
|
||||||
adminRoutes.POST("/pickups", requirePerm("order:pickup"), pickupHandler.Create)
|
adminRoutes.POST("/pickups", requirePerm("order:pickup"), pickupHandler.Create)
|
||||||
adminRoutes.GET("/pickups", requirePerm("order:pickup"), pickupHandler.List)
|
adminRoutes.GET("/pickups", requirePerm("order:pickup"), pickupHandler.List)
|
||||||
|
adminRoutes.GET("/pickups/shop-options", requirePerm("order:pickup"), pickupHandler.ShopOptions)
|
||||||
adminRoutes.GET("/pickups/available-listings", requirePerm("order:pickup"), pickupHandler.AvailableListings)
|
adminRoutes.GET("/pickups/available-listings", requirePerm("order:pickup"), pickupHandler.AvailableListings)
|
||||||
adminRoutes.GET("/pickups/:id", requirePerm("order:pickup"), pickupHandler.Detail)
|
adminRoutes.GET("/pickups/:id", requirePerm("order:pickup"), pickupHandler.Detail)
|
||||||
adminRoutes.POST("/pickups/:id/complete", requirePerm("order:pickup"), pickupHandler.Complete)
|
adminRoutes.POST("/pickups/:id/complete", requirePerm("order:pickup"), pickupHandler.Complete)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- +goose Up
|
||||||
|
|
||||||
|
ALTER TABLE admin_pickups
|
||||||
|
ADD COLUMN shop_name VARCHAR(100) NOT NULL DEFAULT '' COMMENT '线下成交店铺名称' AFTER platform,
|
||||||
|
ADD KEY idx_admin_pickups_shop_name (shop_name);
|
||||||
|
|
||||||
|
-- +goose Down
|
||||||
|
|
||||||
|
ALTER TABLE admin_pickups
|
||||||
|
DROP KEY idx_admin_pickups_shop_name,
|
||||||
|
DROP COLUMN shop_name;
|
||||||
@@ -14,6 +14,7 @@ export interface AdminPickup {
|
|||||||
owner_phone: string
|
owner_phone: string
|
||||||
admin_id: number
|
admin_id: number
|
||||||
platform: string
|
platform: string
|
||||||
|
shop_name: string
|
||||||
listing_price_cent: number
|
listing_price_cent: number
|
||||||
owner_price_cent: number
|
owner_price_cent: number
|
||||||
website_profit_cent: number
|
website_profit_cent: number
|
||||||
@@ -52,6 +53,7 @@ export interface AvailableListing {
|
|||||||
export interface AdminPickupCreateRequest {
|
export interface AdminPickupCreateRequest {
|
||||||
listing_id: number
|
listing_id: number
|
||||||
platform?: string
|
platform?: string
|
||||||
|
shop_name?: string
|
||||||
profit_amount_cent?: number
|
profit_amount_cent?: number
|
||||||
remark?: string
|
remark?: string
|
||||||
}
|
}
|
||||||
@@ -72,6 +74,7 @@ export interface AdminPickupListQuery {
|
|||||||
page_size?: number
|
page_size?: number
|
||||||
keyword?: string
|
keyword?: string
|
||||||
status?: string
|
status?: string
|
||||||
|
shop_name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanParams(query: object) {
|
function cleanParams(query: object) {
|
||||||
@@ -99,6 +102,13 @@ export async function fetchAdminPickup(id: string | number) {
|
|||||||
return data.data
|
return data.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchAdminPickupShopOptions(platform = '') {
|
||||||
|
const { data } = await apiClient.get<ApiResponse<string[]>>('/admin/pickups/shop-options', {
|
||||||
|
params: cleanParams({ platform }),
|
||||||
|
})
|
||||||
|
return Array.isArray(data.data) ? data.data : []
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchAvailableListings(keyword: string, page = 1, page_size = 20) {
|
export async function fetchAvailableListings(keyword: string, page = 1, page_size = 20) {
|
||||||
const { data } = await apiClient.get<ApiResponse<PaginatedResult<AvailableListing>>>(
|
const { data } = await apiClient.get<ApiResponse<PaginatedResult<AvailableListing>>>(
|
||||||
'/admin/pickups/available-listings',
|
'/admin/pickups/available-listings',
|
||||||
|
|||||||
@@ -300,6 +300,10 @@ function readSnapshotResources(summary: Record<string, unknown> | null): Snapsho
|
|||||||
<dt>交易渠道</dt>
|
<dt>交易渠道</dt>
|
||||||
<dd>{{ pickup.platform || '-' }}</dd>
|
<dd>{{ pickup.platform || '-' }}</dd>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt>店铺名称</dt>
|
||||||
|
<dd>{{ pickup.shop_name || '-' }}</dd>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt>管理员ID</dt>
|
<dt>管理员ID</dt>
|
||||||
<dd>{{ pickup.admin_id }}</dd>
|
<dd>{{ pickup.admin_id }}</dd>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
completeAdminPickup,
|
completeAdminPickup,
|
||||||
createAdminPickup,
|
createAdminPickup,
|
||||||
fetchAdminPickups,
|
fetchAdminPickups,
|
||||||
|
fetchAdminPickupShopOptions,
|
||||||
fetchAvailableListings,
|
fetchAvailableListings,
|
||||||
updateAdminPickupProfit,
|
updateAdminPickupProfit,
|
||||||
type AdminPickup,
|
type AdminPickup,
|
||||||
@@ -20,7 +21,7 @@ import { adminPath } from '@/shared/utils/adminPath'
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const items = ref<AdminPickup[]>([])
|
const items = ref<AdminPickup[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const filters = reactive({ page: 1, page_size: 20, keyword: '', status: '' })
|
const filters = reactive({ page: 1, page_size: 20, keyword: '', status: '', shop_name: '' })
|
||||||
|
|
||||||
const createDialogVisible = ref(false)
|
const createDialogVisible = ref(false)
|
||||||
const completeDialogVisible = ref(false)
|
const completeDialogVisible = ref(false)
|
||||||
@@ -31,6 +32,7 @@ const profitSaving = ref(false)
|
|||||||
const createForm = reactive({
|
const createForm = reactive({
|
||||||
listing_id: null as number | null,
|
listing_id: null as number | null,
|
||||||
platform: '',
|
platform: '',
|
||||||
|
shop_name: '',
|
||||||
profit_amount: 0,
|
profit_amount: 0,
|
||||||
remark: '',
|
remark: '',
|
||||||
})
|
})
|
||||||
@@ -39,6 +41,8 @@ const profitForm = reactive({ profit_amount: 0, reason: '' })
|
|||||||
|
|
||||||
const listingOptions = ref<AvailableListing[]>([])
|
const listingOptions = ref<AvailableListing[]>([])
|
||||||
const listingLoading = ref(false)
|
const listingLoading = ref(false)
|
||||||
|
const shopOptions = ref<string[]>([])
|
||||||
|
const shopOptionsLoading = ref(false)
|
||||||
const selectedListing = computed(
|
const selectedListing = computed(
|
||||||
() => listingOptions.value.find(item => item.id === createForm.listing_id) || null
|
() => listingOptions.value.find(item => item.id === createForm.listing_id) || null
|
||||||
)
|
)
|
||||||
@@ -58,7 +62,10 @@ const selectedPriceSnapshot = computed(() => {
|
|||||||
return { pureCent, extraCent, totalCent }
|
return { pureCent, extraCent, totalCent }
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(loadList)
|
onMounted(() => {
|
||||||
|
loadList()
|
||||||
|
loadShopOptions()
|
||||||
|
})
|
||||||
|
|
||||||
async function loadList() {
|
async function loadList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -88,12 +95,22 @@ function handleSizeChange(s: number) {
|
|||||||
function openCreateDialog() {
|
function openCreateDialog() {
|
||||||
createForm.listing_id = null
|
createForm.listing_id = null
|
||||||
createForm.platform = ''
|
createForm.platform = ''
|
||||||
|
createForm.shop_name = ''
|
||||||
createForm.profit_amount = 0
|
createForm.profit_amount = 0
|
||||||
createForm.remark = ''
|
createForm.remark = ''
|
||||||
listingOptions.value = []
|
listingOptions.value = []
|
||||||
createDialogVisible.value = true
|
createDialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadShopOptions() {
|
||||||
|
shopOptionsLoading.value = true
|
||||||
|
try {
|
||||||
|
shopOptions.value = await fetchAdminPickupShopOptions()
|
||||||
|
} finally {
|
||||||
|
shopOptionsLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function searchListings(keyword: string) {
|
async function searchListings(keyword: string) {
|
||||||
if (!keyword) {
|
if (!keyword) {
|
||||||
listingOptions.value = []
|
listingOptions.value = []
|
||||||
@@ -122,11 +139,13 @@ async function handleCreate() {
|
|||||||
await createAdminPickup({
|
await createAdminPickup({
|
||||||
listing_id: createForm.listing_id,
|
listing_id: createForm.listing_id,
|
||||||
platform: createForm.platform,
|
platform: createForm.platform,
|
||||||
|
shop_name: createForm.shop_name,
|
||||||
profit_amount_cent: yuanToCent(createForm.profit_amount),
|
profit_amount_cent: yuanToCent(createForm.profit_amount),
|
||||||
remark: createForm.remark,
|
remark: createForm.remark,
|
||||||
})
|
})
|
||||||
ElMessage.success('提号订单已创建')
|
ElMessage.success('提号订单已创建')
|
||||||
createDialogVisible.value = false
|
createDialogVisible.value = false
|
||||||
|
loadShopOptions()
|
||||||
loadList()
|
loadList()
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
ElMessage.error(errorMessage(e) || '创建失败')
|
ElMessage.error(errorMessage(e) || '创建失败')
|
||||||
@@ -278,6 +297,15 @@ function listingOwnerTotalCent(item: AvailableListing) {
|
|||||||
<el-option label="已完成" value="completed" />
|
<el-option label="已完成" value="completed" />
|
||||||
<el-option label="已取消" value="cancelled" />
|
<el-option label="已取消" value="cancelled" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
<el-select
|
||||||
|
v-model="filters.shop_name"
|
||||||
|
placeholder="店铺名称"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
style="width: 160px"
|
||||||
|
>
|
||||||
|
<el-option v-for="name in shopOptions" :key="name" :label="name" :value="name" />
|
||||||
|
</el-select>
|
||||||
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
|
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
|
||||||
<el-button :icon="Refresh" @click="loadList">刷新</el-button>
|
<el-button :icon="Refresh" @click="loadList">刷新</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -299,6 +327,9 @@ function listingOwnerTotalCent(item: AvailableListing) {
|
|||||||
<el-table-column label="交易渠道" width="110">
|
<el-table-column label="交易渠道" width="110">
|
||||||
<template #default="{ row }">{{ row.platform || '-' }}</template>
|
<template #default="{ row }">{{ row.platform || '-' }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="店铺名称" min-width="130">
|
||||||
|
<template #default="{ row }">{{ row.shop_name || '-' }}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="结算金额" width="130">
|
<el-table-column label="结算金额" width="130">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row.status === 'completed'">{{
|
<span v-if="row.status === 'completed'">{{
|
||||||
@@ -407,6 +438,21 @@ function listingOwnerTotalCent(item: AvailableListing) {
|
|||||||
<el-form-item label="交易渠道">
|
<el-form-item label="交易渠道">
|
||||||
<el-input v-model="createForm.platform" placeholder="如 微信 / QQ / 闲鱼" />
|
<el-input v-model="createForm.platform" placeholder="如 微信 / QQ / 闲鱼" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺名称">
|
||||||
|
<el-select
|
||||||
|
v-model="createForm.shop_name"
|
||||||
|
filterable
|
||||||
|
allow-create
|
||||||
|
default-first-option
|
||||||
|
clearable
|
||||||
|
:loading="shopOptionsLoading"
|
||||||
|
placeholder="选择历史店铺或输入新店铺"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option v-for="name in shopOptions" :key="name" :label="name" :value="name" />
|
||||||
|
</el-select>
|
||||||
|
<div class="form-hint">首次使用的店铺可直接输入名称创建</div>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="线下利润(元)">
|
<el-form-item label="线下利润(元)">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="createForm.profit_amount"
|
v-model="createForm.profit_amount"
|
||||||
|
|||||||
Reference in New Issue
Block a user