优化退款
This commit is contained in:
@@ -32,6 +32,7 @@ import {
|
||||
checkAdminKuaishouIndustryVoucherAvailable,
|
||||
consumeAdminKuaishouIndustryVoucher,
|
||||
disagreeAdminKuaishouIndustryRefund,
|
||||
fetchAdminKuaishouIndustrySourceConfig,
|
||||
fetchAdminKuaishouIndustryVouchers,
|
||||
listAdminKuaishouIndustryRefunds,
|
||||
resendAdminKuaishouIndustryVoucherCode,
|
||||
@@ -42,6 +43,7 @@ import type {
|
||||
AdminKuaishouIndustryRefundApprovePayload,
|
||||
AdminKuaishouIndustryRefundDisagreePayload,
|
||||
AdminKuaishouIndustryRefundListPayload,
|
||||
AdminKuaishouIndustryShopConfig,
|
||||
AdminKuaishouIndustryVoucher,
|
||||
AdminKuaishouIndustryVoucherToolPayload,
|
||||
} from '@/types/admin'
|
||||
@@ -124,6 +126,17 @@ export default function AdminKuaishouIndustryPage() {
|
||||
const [lastResultTitle, setLastResultTitle] = useState('接口结果')
|
||||
const [lastResult, setLastResult] = useState<unknown>(null)
|
||||
const [refundRows, setRefundRows] = useState<Array<Record<string, unknown>>>([])
|
||||
const [industryShops, setIndustryShops] = useState<AdminKuaishouIndustryShopConfig[]>([])
|
||||
const refundShopOptions = useMemo(
|
||||
() =>
|
||||
industryShops
|
||||
.filter((shop) => shop.enabled !== false && shop.sellerId)
|
||||
.map((shop) => ({
|
||||
label: formatShopOptionLabel(shop),
|
||||
value: shop.sellerId,
|
||||
})),
|
||||
[industryShops],
|
||||
)
|
||||
|
||||
const columns = useMemo<TableColumnsType<AdminKuaishouIndustryVoucher>>(
|
||||
() => [
|
||||
@@ -206,6 +219,7 @@ export default function AdminKuaishouIndustryPage() {
|
||||
() => [
|
||||
{ title: '售后单', dataIndex: 'refundId', minWidth: 160 },
|
||||
{ title: '订单', dataIndex: 'oid', minWidth: 160 },
|
||||
{ title: '卖家', dataIndex: 'sellerId', minWidth: 140 },
|
||||
{ title: '状态', dataIndex: 'status', width: 100 },
|
||||
{ title: '协商', dataIndex: 'negotiateStatus', width: 100 },
|
||||
{ title: '金额', dataIndex: 'refundFee', width: 100 },
|
||||
@@ -230,8 +244,26 @@ export default function AdminKuaishouIndustryPage() {
|
||||
|
||||
useEffect(() => {
|
||||
void loadVouchers()
|
||||
void loadIndustryShops()
|
||||
}, [])
|
||||
|
||||
async function loadIndustryShops() {
|
||||
try {
|
||||
const response = await fetchAdminKuaishouIndustrySourceConfig()
|
||||
const shops = response.data.source.shops || []
|
||||
setIndustryShops(shops)
|
||||
|
||||
const enabledSellerIds = shops
|
||||
.filter((shop) => shop.enabled !== false && shop.sellerId)
|
||||
.map((shop) => shop.sellerId)
|
||||
if (enabledSellerIds.length === 1) {
|
||||
applyDefaultSellerId(enabledSellerIds[0] as string)
|
||||
}
|
||||
} catch (error) {
|
||||
showError(error instanceof Error ? error.message : '读取快手授权店铺失败')
|
||||
}
|
||||
}
|
||||
|
||||
async function loadVouchers(nextFilters: Partial<VoucherFilterState> = {}) {
|
||||
const filters = { ...voucherFilters, ...nextFilters }
|
||||
setVoucherFilters(filters)
|
||||
@@ -323,12 +355,22 @@ export default function AdminKuaishouIndustryPage() {
|
||||
|
||||
async function runRefundList() {
|
||||
const [begin, end] = refundDateRange || []
|
||||
await runOpenApiAction('售后单列表', 'refund-list', () =>
|
||||
listAdminKuaishouIndustryRefunds({
|
||||
...refundListForm,
|
||||
beginTime: begin?.valueOf(),
|
||||
endTime: end?.valueOf(),
|
||||
} satisfies AdminKuaishouIndustryRefundListPayload),
|
||||
const sellerId = resolveRefundSellerId(refundListForm.sellerId)
|
||||
if (!sellerId && refundShopOptions.length > 1) {
|
||||
showError('请先选择快手售后退款店铺 sellerId')
|
||||
return
|
||||
}
|
||||
|
||||
await runOpenApiAction(
|
||||
'售后单列表',
|
||||
'refund-list',
|
||||
() =>
|
||||
listAdminKuaishouIndustryRefunds({
|
||||
...refundListForm,
|
||||
sellerId,
|
||||
beginTime: begin?.valueOf(),
|
||||
endTime: end?.valueOf(),
|
||||
} satisfies AdminKuaishouIndustryRefundListPayload),
|
||||
(result) => {
|
||||
const rows = extractRefundRows(result.response)
|
||||
setRefundRows(rows)
|
||||
@@ -337,19 +379,33 @@ export default function AdminKuaishouIndustryPage() {
|
||||
}
|
||||
|
||||
async function runApproveRefund() {
|
||||
const sellerId = resolveRefundSellerId(approveForm.sellerId)
|
||||
if (!sellerId && refundShopOptions.length > 1) {
|
||||
showError('请先选择快手售后退款店铺 sellerId')
|
||||
return
|
||||
}
|
||||
|
||||
await runOpenApiAction('同意退款', 'refund-approve', () =>
|
||||
approveAdminKuaishouIndustryRefund({
|
||||
...approveForm,
|
||||
sellerId: approveForm.sellerId || refundListForm.sellerId,
|
||||
sellerId,
|
||||
orderId: approveForm.orderId || refundListForm.orderId,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
async function runDisagreeRefund() {
|
||||
const sellerId = resolveRefundSellerId(disagreeForm.sellerId)
|
||||
if (!sellerId && refundShopOptions.length > 1) {
|
||||
showError('请先选择快手售后退款店铺 sellerId')
|
||||
return
|
||||
}
|
||||
|
||||
await runOpenApiAction('不同意退款', 'refund-disagree', () =>
|
||||
disagreeAdminKuaishouIndustryRefund({
|
||||
...disagreeForm,
|
||||
sellerId: disagreeForm.sellerId || refundListForm.sellerId,
|
||||
sellerId,
|
||||
orderId: disagreeForm.orderId || refundListForm.orderId,
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -389,21 +445,33 @@ export default function AdminKuaishouIndustryPage() {
|
||||
|
||||
function fillRefundAction(row: Record<string, unknown>) {
|
||||
const refundId = String(row.refundId || '').trim()
|
||||
const sellerId = String(row.sellerId || refundListForm.sellerId || '').trim()
|
||||
const orderId = String(row.oid || row.orderId || refundListForm.orderId || '').trim()
|
||||
const status = String(row.status || '').trim()
|
||||
const negotiateStatus = String(row.negotiateStatus || '').trim()
|
||||
setApproveForm((current) => ({
|
||||
...current,
|
||||
sellerId: sellerId || current.sellerId,
|
||||
orderId: orderId || current.orderId,
|
||||
refundId,
|
||||
status,
|
||||
negotiateStatus,
|
||||
refundAmount: String(row.refundFee || current.refundAmount || ''),
|
||||
refundHandingWay: String(row.handlingWay || current.refundHandingWay || ''),
|
||||
}))
|
||||
setDisagreeForm((current) => ({
|
||||
...current,
|
||||
sellerId: sellerId || current.sellerId,
|
||||
orderId: orderId || current.orderId,
|
||||
refundId,
|
||||
status,
|
||||
negotiateStatus: negotiateStatus || current.negotiateStatus,
|
||||
}))
|
||||
setRefundListForm((current) => ({
|
||||
...current,
|
||||
sellerId: sellerId || current.sellerId,
|
||||
orderId: orderId || current.orderId,
|
||||
}))
|
||||
showSuccess('已填入退款操作区')
|
||||
}
|
||||
|
||||
@@ -444,14 +512,22 @@ export default function AdminKuaishouIndustryPage() {
|
||||
allowClear
|
||||
placeholder="订单号 oid"
|
||||
value={voucherFilters.oid}
|
||||
onChange={(event) => setVoucherFilters({ ...voucherFilters, oid: event.target.value })}
|
||||
onChange={(event) =>
|
||||
setVoucherFilters({
|
||||
...voucherFilters,
|
||||
oid: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
allowClear
|
||||
placeholder="券码"
|
||||
value={voucherFilters.voucherCode}
|
||||
onChange={(event) =>
|
||||
setVoucherFilters({ ...voucherFilters, voucherCode: event.target.value })
|
||||
setVoucherFilters({
|
||||
...voucherFilters,
|
||||
voucherCode: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
@@ -459,7 +535,10 @@ export default function AdminKuaishouIndustryPage() {
|
||||
placeholder="任务 ID"
|
||||
value={voucherFilters.taskId}
|
||||
onChange={(event) =>
|
||||
setVoucherFilters({ ...voucherFilters, taskId: event.target.value })
|
||||
setVoucherFilters({
|
||||
...voucherFilters,
|
||||
taskId: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
@@ -467,7 +546,10 @@ export default function AdminKuaishouIndustryPage() {
|
||||
placeholder="卖家 ID"
|
||||
value={voucherFilters.sellerId}
|
||||
onChange={(event) =>
|
||||
setVoucherFilters({ ...voucherFilters, sellerId: event.target.value })
|
||||
setVoucherFilters({
|
||||
...voucherFilters,
|
||||
sellerId: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
@@ -522,7 +604,10 @@ export default function AdminKuaishouIndustryPage() {
|
||||
placeholder="订单号 oid"
|
||||
value={toolForm.oid}
|
||||
onChange={(event) =>
|
||||
updateToolForm({ oid: event.target.value, orderId: event.target.value })
|
||||
updateToolForm({
|
||||
oid: event.target.value,
|
||||
orderId: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
@@ -609,11 +694,9 @@ export default function AdminKuaishouIndustryPage() {
|
||||
<div className="page-stack">
|
||||
<Card title="售后单列表">
|
||||
<Space wrap className="filter-form">
|
||||
<Input
|
||||
placeholder="卖家 ID"
|
||||
value={refundListForm.sellerId}
|
||||
onChange={(event) => updateRefundListForm({ sellerId: event.target.value })}
|
||||
/>
|
||||
{renderSellerIdControl(refundListForm.sellerId, (sellerId) =>
|
||||
updateRefundListForm({ sellerId }),
|
||||
)}
|
||||
<Input
|
||||
placeholder="订单号"
|
||||
value={refundListForm.orderId}
|
||||
@@ -633,8 +716,16 @@ export default function AdminKuaishouIndustryPage() {
|
||||
]}
|
||||
onChange={(value) => updateRefundListForm({ type: value })}
|
||||
/>
|
||||
<Input placeholder="状态" value={refundListForm.status} onChange={(event) => updateRefundListForm({ status: event.target.value })} />
|
||||
<Input placeholder="游标" value={refundListForm.pcursor} onChange={(event) => updateRefundListForm({ pcursor: event.target.value })} />
|
||||
<Input
|
||||
placeholder="状态"
|
||||
value={refundListForm.status}
|
||||
onChange={(event) => updateRefundListForm({ status: event.target.value })}
|
||||
/>
|
||||
<Input
|
||||
placeholder="游标"
|
||||
value={refundListForm.pcursor}
|
||||
onChange={(event) => updateRefundListForm({ pcursor: event.target.value })}
|
||||
/>
|
||||
<InputNumber
|
||||
min={1}
|
||||
max={100}
|
||||
@@ -654,7 +745,7 @@ export default function AdminKuaishouIndustryPage() {
|
||||
rowKey={(row) => String(row.refundId || row.oid || JSON.stringify(row))}
|
||||
columns={refundColumns}
|
||||
dataSource={refundRows}
|
||||
scroll={{ x: 980 }}
|
||||
scroll={{ x: 1120 }}
|
||||
pagination={{ pageSize: 10 }}
|
||||
style={{ marginTop: 16 }}
|
||||
/>
|
||||
@@ -663,21 +754,27 @@ export default function AdminKuaishouIndustryPage() {
|
||||
<div className="kuaishou-industry-split">
|
||||
<Card title="同意退款">
|
||||
<div className="kuaishou-industry-tool-grid">
|
||||
<Input
|
||||
placeholder="卖家 ID"
|
||||
value={approveForm.sellerId || refundListForm.sellerId}
|
||||
onChange={(event) => setApproveForm({ ...approveForm, sellerId: event.target.value })}
|
||||
/>
|
||||
{renderSellerIdControl(approveForm.sellerId || refundListForm.sellerId, (sellerId) =>
|
||||
setApproveForm({ ...approveForm, sellerId }),
|
||||
)}
|
||||
<Input
|
||||
placeholder="退款单编号"
|
||||
value={String(approveForm.refundId || '')}
|
||||
onChange={(event) => setApproveForm({ ...approveForm, refundId: event.target.value })}
|
||||
onChange={(event) =>
|
||||
setApproveForm({
|
||||
...approveForm,
|
||||
refundId: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
placeholder="退款金额(分)"
|
||||
value={String(approveForm.refundAmount || '')}
|
||||
onChange={(event) =>
|
||||
setApproveForm({ ...approveForm, refundAmount: event.target.value })
|
||||
setApproveForm({
|
||||
...approveForm,
|
||||
refundAmount: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
@@ -689,14 +786,20 @@ export default function AdminKuaishouIndustryPage() {
|
||||
placeholder="协商状态"
|
||||
value={String(approveForm.negotiateStatus || '')}
|
||||
onChange={(event) =>
|
||||
setApproveForm({ ...approveForm, negotiateStatus: event.target.value })
|
||||
setApproveForm({
|
||||
...approveForm,
|
||||
negotiateStatus: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
placeholder="退款方式"
|
||||
value={String(approveForm.refundHandingWay || '')}
|
||||
onChange={(event) =>
|
||||
setApproveForm({ ...approveForm, refundHandingWay: event.target.value })
|
||||
setApproveForm({
|
||||
...approveForm,
|
||||
refundHandingWay: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
@@ -717,46 +820,57 @@ export default function AdminKuaishouIndustryPage() {
|
||||
|
||||
<Card title="不同意退款">
|
||||
<div className="kuaishou-industry-tool-grid">
|
||||
<Input
|
||||
placeholder="卖家 ID"
|
||||
value={disagreeForm.sellerId || refundListForm.sellerId}
|
||||
onChange={(event) =>
|
||||
setDisagreeForm({ ...disagreeForm, sellerId: event.target.value })
|
||||
}
|
||||
/>
|
||||
{renderSellerIdControl(disagreeForm.sellerId || refundListForm.sellerId, (sellerId) =>
|
||||
setDisagreeForm({ ...disagreeForm, sellerId }),
|
||||
)}
|
||||
<Input
|
||||
placeholder="退款单编号"
|
||||
value={String(disagreeForm.refundId || '')}
|
||||
onChange={(event) =>
|
||||
setDisagreeForm({ ...disagreeForm, refundId: event.target.value })
|
||||
setDisagreeForm({
|
||||
...disagreeForm,
|
||||
refundId: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
placeholder="拒绝原因枚举"
|
||||
value={String(disagreeForm.sellerDisagreeReason || '')}
|
||||
onChange={(event) =>
|
||||
setDisagreeForm({ ...disagreeForm, sellerDisagreeReason: event.target.value })
|
||||
setDisagreeForm({
|
||||
...disagreeForm,
|
||||
sellerDisagreeReason: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
placeholder="拒绝说明"
|
||||
value={disagreeForm.sellerDisagreeDesc}
|
||||
onChange={(event) =>
|
||||
setDisagreeForm({ ...disagreeForm, sellerDisagreeDesc: event.target.value })
|
||||
setDisagreeForm({
|
||||
...disagreeForm,
|
||||
sellerDisagreeDesc: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
placeholder="退款单状态"
|
||||
value={String(disagreeForm.status || '')}
|
||||
onChange={(event) =>
|
||||
setDisagreeForm({ ...disagreeForm, status: event.target.value })
|
||||
setDisagreeForm({
|
||||
...disagreeForm,
|
||||
status: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
placeholder="协商状态"
|
||||
value={String(disagreeForm.negotiateStatus || '')}
|
||||
onChange={(event) =>
|
||||
setDisagreeForm({ ...disagreeForm, negotiateStatus: event.target.value })
|
||||
setDisagreeForm({
|
||||
...disagreeForm,
|
||||
negotiateStatus: event.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
@@ -810,9 +924,52 @@ export default function AdminKuaishouIndustryPage() {
|
||||
function updateRefundListForm(patch: Partial<RefundListState>) {
|
||||
setRefundListForm((current) => ({ ...current, ...patch }))
|
||||
}
|
||||
|
||||
function applyDefaultSellerId(sellerId: string) {
|
||||
setRefundListForm((current) => (current.sellerId ? current : { ...current, sellerId }))
|
||||
setApproveForm((current) => (current.sellerId ? current : { ...current, sellerId }))
|
||||
setDisagreeForm((current) => (current.sellerId ? current : { ...current, sellerId }))
|
||||
setToolForm((current) => (current.sellerId ? current : { ...current, sellerId }))
|
||||
}
|
||||
|
||||
function resolveRefundSellerId(value?: unknown): string {
|
||||
return (
|
||||
String(value || refundListForm.sellerId || '').trim() ||
|
||||
(refundShopOptions.length === 1 ? refundShopOptions[0]?.value || '' : '')
|
||||
)
|
||||
}
|
||||
|
||||
function renderSellerIdControl(value: string | undefined, onChange: (sellerId: string) => void) {
|
||||
const normalizedValue = String(value || '').trim()
|
||||
if (refundShopOptions.length > 0) {
|
||||
return (
|
||||
<Select
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
placeholder="授权店铺"
|
||||
style={{ minWidth: 220 }}
|
||||
value={normalizedValue || undefined}
|
||||
options={refundShopOptions}
|
||||
onChange={(nextValue) => onChange(String(nextValue || '').trim())}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Input
|
||||
allowClear
|
||||
placeholder="卖家 ID"
|
||||
value={normalizedValue}
|
||||
onChange={(event) => onChange(event.target.value)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function extractRefundRows(response: Record<string, unknown> | null): Array<Record<string, unknown>> {
|
||||
function extractRefundRows(
|
||||
response: Record<string, unknown> | null,
|
||||
): Array<Record<string, unknown>> {
|
||||
const data = response?.data
|
||||
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
||||
return []
|
||||
@@ -827,12 +984,14 @@ function extractRefundRows(response: Record<string, unknown> | null): Array<Reco
|
||||
}
|
||||
|
||||
function resolveOpenApiResultSummary(value: unknown) {
|
||||
const result = value && typeof value === 'object' && !Array.isArray(value)
|
||||
? value as Record<string, unknown>
|
||||
: {}
|
||||
const response = result.response && typeof result.response === 'object' && !Array.isArray(result.response)
|
||||
? result.response as Record<string, unknown>
|
||||
: null
|
||||
const result =
|
||||
value && typeof value === 'object' && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: {}
|
||||
const response =
|
||||
result.response && typeof result.response === 'object' && !Array.isArray(result.response)
|
||||
? (result.response as Record<string, unknown>)
|
||||
: null
|
||||
const success = Boolean(result.success)
|
||||
const code = String(response?.code || response?.sub_code || '').trim()
|
||||
const resultCode = String(response?.result || '').trim()
|
||||
@@ -856,7 +1015,8 @@ function resolveOpenApiResultSummary(value: unknown) {
|
||||
return {
|
||||
success,
|
||||
title: success ? '接口返回成功' : '接口返回失败',
|
||||
description: [markers.join(' / '), message].filter(Boolean).join(',') || '请查看下方原始响应。',
|
||||
description:
|
||||
[markers.join(' / '), message].filter(Boolean).join(',') || '请查看下方原始响应。',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,6 +1035,13 @@ function getVoucherStatusLabel(status: string) {
|
||||
return status || '-'
|
||||
}
|
||||
|
||||
function formatShopOptionLabel(shop: AdminKuaishouIndustryShopConfig) {
|
||||
const name = shop.customShopName || shop.shopName || '未命名店铺'
|
||||
const tokenStatus = shop.hasAccessToken ? '' : ' / 未授权'
|
||||
|
||||
return `${name} / ${shop.sellerId}${tokenStatus}`
|
||||
}
|
||||
|
||||
function formatTimestamp(value: unknown) {
|
||||
const timestamp = Number(value || 0)
|
||||
if (!Number.isFinite(timestamp) || timestamp <= 0) {
|
||||
|
||||
@@ -76,6 +76,7 @@ export interface AdminKuaishouIndustryRefundListPayload {
|
||||
|
||||
export interface AdminKuaishouIndustryRefundApprovePayload {
|
||||
sellerId?: string
|
||||
orderId?: string
|
||||
refundId?: number | string
|
||||
desc?: string
|
||||
refundAmount?: number | string
|
||||
@@ -86,6 +87,7 @@ export interface AdminKuaishouIndustryRefundApprovePayload {
|
||||
|
||||
export interface AdminKuaishouIndustryRefundDisagreePayload {
|
||||
sellerId?: string
|
||||
orderId?: string
|
||||
refundId?: number | string
|
||||
sellerDisagreeReason?: number | string
|
||||
sellerDisagreeDesc?: string
|
||||
|
||||
Reference in New Issue
Block a user