增加线下提号店铺管理
This commit is contained in:
@@ -14,6 +14,7 @@ export interface AdminPickup {
|
||||
owner_phone: string
|
||||
admin_id: number
|
||||
platform: string
|
||||
shop_name: string
|
||||
listing_price_cent: number
|
||||
owner_price_cent: number
|
||||
website_profit_cent: number
|
||||
@@ -52,6 +53,7 @@ export interface AvailableListing {
|
||||
export interface AdminPickupCreateRequest {
|
||||
listing_id: number
|
||||
platform?: string
|
||||
shop_name?: string
|
||||
profit_amount_cent?: number
|
||||
remark?: string
|
||||
}
|
||||
@@ -72,6 +74,7 @@ export interface AdminPickupListQuery {
|
||||
page_size?: number
|
||||
keyword?: string
|
||||
status?: string
|
||||
shop_name?: string
|
||||
}
|
||||
|
||||
function cleanParams(query: object) {
|
||||
@@ -99,6 +102,13 @@ export async function fetchAdminPickup(id: string | number) {
|
||||
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) {
|
||||
const { data } = await apiClient.get<ApiResponse<PaginatedResult<AvailableListing>>>(
|
||||
'/admin/pickups/available-listings',
|
||||
|
||||
@@ -300,6 +300,10 @@ function readSnapshotResources(summary: Record<string, unknown> | null): Snapsho
|
||||
<dt>交易渠道</dt>
|
||||
<dd>{{ pickup.platform || '-' }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>店铺名称</dt>
|
||||
<dd>{{ pickup.shop_name || '-' }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>管理员ID</dt>
|
||||
<dd>{{ pickup.admin_id }}</dd>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
completeAdminPickup,
|
||||
createAdminPickup,
|
||||
fetchAdminPickups,
|
||||
fetchAdminPickupShopOptions,
|
||||
fetchAvailableListings,
|
||||
updateAdminPickupProfit,
|
||||
type AdminPickup,
|
||||
@@ -20,7 +21,7 @@ import { adminPath } from '@/shared/utils/adminPath'
|
||||
const loading = ref(false)
|
||||
const items = ref<AdminPickup[]>([])
|
||||
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 completeDialogVisible = ref(false)
|
||||
@@ -31,6 +32,7 @@ const profitSaving = ref(false)
|
||||
const createForm = reactive({
|
||||
listing_id: null as number | null,
|
||||
platform: '',
|
||||
shop_name: '',
|
||||
profit_amount: 0,
|
||||
remark: '',
|
||||
})
|
||||
@@ -39,6 +41,8 @@ const profitForm = reactive({ profit_amount: 0, reason: '' })
|
||||
|
||||
const listingOptions = ref<AvailableListing[]>([])
|
||||
const listingLoading = ref(false)
|
||||
const shopOptions = ref<string[]>([])
|
||||
const shopOptionsLoading = ref(false)
|
||||
const selectedListing = computed(
|
||||
() => listingOptions.value.find(item => item.id === createForm.listing_id) || null
|
||||
)
|
||||
@@ -58,7 +62,10 @@ const selectedPriceSnapshot = computed(() => {
|
||||
return { pureCent, extraCent, totalCent }
|
||||
})
|
||||
|
||||
onMounted(loadList)
|
||||
onMounted(() => {
|
||||
loadList()
|
||||
loadShopOptions()
|
||||
})
|
||||
|
||||
async function loadList() {
|
||||
loading.value = true
|
||||
@@ -88,12 +95,22 @@ function handleSizeChange(s: number) {
|
||||
function openCreateDialog() {
|
||||
createForm.listing_id = null
|
||||
createForm.platform = ''
|
||||
createForm.shop_name = ''
|
||||
createForm.profit_amount = 0
|
||||
createForm.remark = ''
|
||||
listingOptions.value = []
|
||||
createDialogVisible.value = true
|
||||
}
|
||||
|
||||
async function loadShopOptions() {
|
||||
shopOptionsLoading.value = true
|
||||
try {
|
||||
shopOptions.value = await fetchAdminPickupShopOptions()
|
||||
} finally {
|
||||
shopOptionsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function searchListings(keyword: string) {
|
||||
if (!keyword) {
|
||||
listingOptions.value = []
|
||||
@@ -122,11 +139,13 @@ async function handleCreate() {
|
||||
await createAdminPickup({
|
||||
listing_id: createForm.listing_id,
|
||||
platform: createForm.platform,
|
||||
shop_name: createForm.shop_name,
|
||||
profit_amount_cent: yuanToCent(createForm.profit_amount),
|
||||
remark: createForm.remark,
|
||||
})
|
||||
ElMessage.success('提号订单已创建')
|
||||
createDialogVisible.value = false
|
||||
loadShopOptions()
|
||||
loadList()
|
||||
} catch (e: unknown) {
|
||||
ElMessage.error(errorMessage(e) || '创建失败')
|
||||
@@ -278,6 +297,15 @@ function listingOwnerTotalCent(item: AvailableListing) {
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已取消" value="cancelled" />
|
||||
</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 :icon="Refresh" @click="loadList">刷新</el-button>
|
||||
</div>
|
||||
@@ -299,6 +327,9 @@ function listingOwnerTotalCent(item: AvailableListing) {
|
||||
<el-table-column label="交易渠道" width="110">
|
||||
<template #default="{ row }">{{ row.platform || '-' }}</template>
|
||||
</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">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.status === 'completed'">{{
|
||||
@@ -407,6 +438,21 @@ function listingOwnerTotalCent(item: AvailableListing) {
|
||||
<el-form-item label="交易渠道">
|
||||
<el-input v-model="createForm.platform" placeholder="如 微信 / QQ / 闲鱼" />
|
||||
</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-input-number
|
||||
v-model="createForm.profit_amount"
|
||||
|
||||
Reference in New Issue
Block a user