优化退款
This commit is contained in:
@@ -11,6 +11,11 @@ import { getTaskById } from '../../repositories/task-repo.js'
|
|||||||
import { createHttpError } from '../../utils/http.js'
|
import { createHttpError } from '../../utils/http.js'
|
||||||
import { maskSecret } from '../../utils/masking.js'
|
import { maskSecret } from '../../utils/masking.js'
|
||||||
import { checkKuaishouIndustryEticketAvailable } from '../platforms/kuaishou-industry/check-available-service.js'
|
import { checkKuaishouIndustryEticketAvailable } from '../platforms/kuaishou-industry/check-available-service.js'
|
||||||
|
import {
|
||||||
|
getKuaishouIndustrySourceConfig,
|
||||||
|
listKuaishouIndustryShopConfigs,
|
||||||
|
type KuaishouIndustrySourceConfig,
|
||||||
|
} from '../platforms/kuaishou-industry/source-config-service.js'
|
||||||
import { resendKuaishouIndustryVoucherSendCallback } from '../platforms/kuaishou-industry/send-code-service.js'
|
import { resendKuaishouIndustryVoucherSendCallback } from '../platforms/kuaishou-industry/send-code-service.js'
|
||||||
import { consumeKuaishouIndustryVoucher } from '../platforms/kuaishou-industry/voucher-service.js'
|
import { consumeKuaishouIndustryVoucher } from '../platforms/kuaishou-industry/voucher-service.js'
|
||||||
import {
|
import {
|
||||||
@@ -43,14 +48,18 @@ export async function listAdminKuaishouIndustryRefunds(input: JsonObject = {}) {
|
|||||||
assertRequired(input.beginTime, '开始时间未填写')
|
assertRequired(input.beginTime, '开始时间未填写')
|
||||||
assertRequired(input.endTime, '结束时间未填写')
|
assertRequired(input.endTime, '结束时间未填写')
|
||||||
|
|
||||||
return mapOpenApiResult(await listKuaishouIndustryRefunds(input))
|
const payload = await buildRefundOpenApiPayload(input)
|
||||||
|
|
||||||
|
return mapOpenApiResult(await listKuaishouIndustryRefunds(payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function approveAdminKuaishouIndustryRefund(input: JsonObject = {}) {
|
export async function approveAdminKuaishouIndustryRefund(input: JsonObject = {}) {
|
||||||
assertRequired(input.refundId, '退款单编号未填写')
|
assertRequired(input.refundId, '退款单编号未填写')
|
||||||
assertRequired(input.refundAmount, '退款金额未填写')
|
assertRequired(input.refundAmount, '退款金额未填写')
|
||||||
|
|
||||||
return mapOpenApiResult(await approveKuaishouIndustryRefund(input))
|
const payload = await buildRefundOpenApiPayload(input)
|
||||||
|
|
||||||
|
return mapOpenApiResult(await approveKuaishouIndustryRefund(payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function disagreeAdminKuaishouIndustryRefund(input: JsonObject = {}) {
|
export async function disagreeAdminKuaishouIndustryRefund(input: JsonObject = {}) {
|
||||||
@@ -60,7 +69,9 @@ export async function disagreeAdminKuaishouIndustryRefund(input: JsonObject = {}
|
|||||||
assertRequired(input.status, '退款单当前状态未填写')
|
assertRequired(input.status, '退款单当前状态未填写')
|
||||||
assertRequired(input.negotiateStatus, '协商状态未填写')
|
assertRequired(input.negotiateStatus, '协商状态未填写')
|
||||||
|
|
||||||
return mapOpenApiResult(await disagreeKuaishouIndustryRefund(input))
|
const payload = await buildRefundOpenApiPayload(input)
|
||||||
|
|
||||||
|
return mapOpenApiResult(await disagreeKuaishouIndustryRefund(payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkAdminKuaishouIndustryVoucherAvailable(input: JsonObject = {}) {
|
export async function checkAdminKuaishouIndustryVoucherAvailable(input: JsonObject = {}) {
|
||||||
@@ -167,21 +178,111 @@ function buildVoucherOpenApiPayload(
|
|||||||
orderId: String(input.orderId || input.oid || voucher?.oid || '').trim(),
|
orderId: String(input.orderId || input.oid || voucher?.oid || '').trim(),
|
||||||
token: String(input.token || voucher?.token || '').trim(),
|
token: String(input.token || voucher?.token || '').trim(),
|
||||||
serialNum: String(input.serialNum || voucher?.consume_serial_num || '').trim(),
|
serialNum: String(input.serialNum || voucher?.consume_serial_num || '').trim(),
|
||||||
etickets: etickets.length > 0
|
etickets:
|
||||||
? etickets
|
etickets.length > 0
|
||||||
: voucherCode
|
? etickets
|
||||||
? [{ id: voucherCode, code: voucherCode, num: 1 }]
|
: voucherCode
|
||||||
: [],
|
? [{ id: voucherCode, code: voucherCode, num: 1 }]
|
||||||
|
: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveOptionalVoucher(input: JsonObject): Promise<KuaishouIndustryVoucherRow | null> {
|
async function buildRefundOpenApiPayload(input: JsonObject): Promise<JsonObject> {
|
||||||
|
const source = getKuaishouIndustrySourceConfig()
|
||||||
|
const sellerId =
|
||||||
|
String(input.sellerId || '').trim() ||
|
||||||
|
(await resolveRefundSellerIdFromLocalVoucher(input)) ||
|
||||||
|
resolveSingleEnabledKuaishouIndustrySellerId(source)
|
||||||
|
|
||||||
|
if (!sellerId && hasMultipleEnabledKuaishouIndustryShops(source)) {
|
||||||
|
throw createHttpError('存在多个快手售后退款店铺授权,请先选择 sellerId', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'admin_kuaishou_industry_refund_seller_id_required',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...input,
|
||||||
|
...(sellerId ? { sellerId } : {}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resolveRefundSellerIdFromLocalVoucher(input: JsonObject): Promise<string> {
|
||||||
|
const voucherCode = String(input.voucherCode || '').trim()
|
||||||
|
const oid = String(input.oid || input.orderId || '').trim()
|
||||||
|
if (voucherCode) {
|
||||||
|
const voucher = await findKuaishouIndustryVoucherByCode(voucherCode, oid)
|
||||||
|
return String(voucher?.seller_id || '').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskId = Number(input.taskId || 0)
|
||||||
|
if (Number.isFinite(taskId) && taskId > 0) {
|
||||||
|
return resolveSingleSellerIdFromVouchers(
|
||||||
|
await listKuaishouIndustryVouchersByTaskId(Math.trunc(taskId)),
|
||||||
|
'当前任务关联多个卖家,请指定 sellerId',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oid) {
|
||||||
|
return resolveSingleSellerIdFromVouchers(
|
||||||
|
await listKuaishouIndustryVouchersByOid(oid),
|
||||||
|
'当前订单关联多个卖家,请指定 sellerId',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveSingleSellerIdFromVouchers(
|
||||||
|
vouchers: KuaishouIndustryVoucherRow[],
|
||||||
|
multipleMessage: string,
|
||||||
|
): string {
|
||||||
|
const sellerIds = Array.from(
|
||||||
|
new Set(vouchers.map((voucher) => String(voucher.seller_id || '').trim()).filter(Boolean)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (sellerIds.length > 1) {
|
||||||
|
throw createHttpError(multipleMessage, {
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: 'admin_kuaishou_industry_refund_seller_id_ambiguous',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return sellerIds[0] || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveSingleEnabledKuaishouIndustrySellerId(
|
||||||
|
source: KuaishouIndustrySourceConfig,
|
||||||
|
): string {
|
||||||
|
const enabledShops = listEnabledKuaishouIndustryShops(source)
|
||||||
|
|
||||||
|
return enabledShops.length === 1
|
||||||
|
? String(enabledShops[0]?.sellerId || enabledShops[0]?.shopId || '').trim()
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMultipleEnabledKuaishouIndustryShops(source: KuaishouIndustrySourceConfig): boolean {
|
||||||
|
return listEnabledKuaishouIndustryShops(source).length > 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function listEnabledKuaishouIndustryShops(source: KuaishouIndustrySourceConfig) {
|
||||||
|
return listKuaishouIndustryShopConfigs(source).filter(
|
||||||
|
(shop) => shop.enabled !== false && String(shop.sellerId || shop.shopId || '').trim(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resolveOptionalVoucher(
|
||||||
|
input: JsonObject,
|
||||||
|
): Promise<KuaishouIndustryVoucherRow | null> {
|
||||||
const voucherCode = String(input.voucherCode || '').trim()
|
const voucherCode = String(input.voucherCode || '').trim()
|
||||||
if (!voucherCode) {
|
if (!voucherCode) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const voucher = await findKuaishouIndustryVoucherByCode(voucherCode, String(input.oid || input.orderId || '').trim())
|
const voucher = await findKuaishouIndustryVoucherByCode(
|
||||||
|
voucherCode,
|
||||||
|
String(input.oid || input.orderId || '').trim(),
|
||||||
|
)
|
||||||
if (!voucher) {
|
if (!voucher) {
|
||||||
throw createHttpError('电子凭证不存在', {
|
throw createHttpError('电子凭证不存在', {
|
||||||
statusCode: 404,
|
statusCode: 404,
|
||||||
@@ -201,13 +302,21 @@ async function resolveRequiredVoucher(input: JsonObject): Promise<KuaishouIndust
|
|||||||
const taskId = Number(input.taskId || 0)
|
const taskId = Number(input.taskId || 0)
|
||||||
if (Number.isFinite(taskId) && taskId > 0) {
|
if (Number.isFinite(taskId) && taskId > 0) {
|
||||||
const vouchers = await listKuaishouIndustryVouchersByTaskId(Math.trunc(taskId))
|
const vouchers = await listKuaishouIndustryVouchersByTaskId(Math.trunc(taskId))
|
||||||
return resolveSingleVoucher(vouchers, '当前任务没有关联电子凭证', '当前任务关联多个电子凭证,请指定券码')
|
return resolveSingleVoucher(
|
||||||
|
vouchers,
|
||||||
|
'当前任务没有关联电子凭证',
|
||||||
|
'当前任务关联多个电子凭证,请指定券码',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const oid = String(input.oid || input.orderId || '').trim()
|
const oid = String(input.oid || input.orderId || '').trim()
|
||||||
if (oid) {
|
if (oid) {
|
||||||
const vouchers = await listKuaishouIndustryVouchersByOid(oid)
|
const vouchers = await listKuaishouIndustryVouchersByOid(oid)
|
||||||
return resolveSingleVoucher(vouchers, '当前订单没有关联电子凭证', '当前订单关联多个电子凭证,请指定券码')
|
return resolveSingleVoucher(
|
||||||
|
vouchers,
|
||||||
|
'当前订单没有关联电子凭证',
|
||||||
|
'当前订单关联多个电子凭证,请指定券码',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw createHttpError('请填写券码、任务 ID 或订单号', {
|
throw createHttpError('请填写券码、任务 ID 或订单号', {
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ export type AdminKuaishouIndustryRefundListInput = {
|
|||||||
|
|
||||||
export type AdminKuaishouIndustryRefundApproveInput = {
|
export type AdminKuaishouIndustryRefundApproveInput = {
|
||||||
sellerId?: string
|
sellerId?: string
|
||||||
|
orderId?: string
|
||||||
refundId?: number | string
|
refundId?: number | string
|
||||||
desc?: string
|
desc?: string
|
||||||
refundAmount?: number | string
|
refundAmount?: number | string
|
||||||
@@ -272,6 +273,7 @@ export type AdminKuaishouIndustryRefundApproveInput = {
|
|||||||
|
|
||||||
export type AdminKuaishouIndustryRefundDisagreeInput = {
|
export type AdminKuaishouIndustryRefundDisagreeInput = {
|
||||||
sellerId?: string
|
sellerId?: string
|
||||||
|
orderId?: string
|
||||||
refundId?: number | string
|
refundId?: number | string
|
||||||
sellerDisagreeReason?: number | string
|
sellerDisagreeReason?: number | string
|
||||||
sellerDisagreeDesc?: string
|
sellerDisagreeDesc?: string
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
checkAdminKuaishouIndustryVoucherAvailable,
|
checkAdminKuaishouIndustryVoucherAvailable,
|
||||||
consumeAdminKuaishouIndustryVoucher,
|
consumeAdminKuaishouIndustryVoucher,
|
||||||
disagreeAdminKuaishouIndustryRefund,
|
disagreeAdminKuaishouIndustryRefund,
|
||||||
|
fetchAdminKuaishouIndustrySourceConfig,
|
||||||
fetchAdminKuaishouIndustryVouchers,
|
fetchAdminKuaishouIndustryVouchers,
|
||||||
listAdminKuaishouIndustryRefunds,
|
listAdminKuaishouIndustryRefunds,
|
||||||
resendAdminKuaishouIndustryVoucherCode,
|
resendAdminKuaishouIndustryVoucherCode,
|
||||||
@@ -42,6 +43,7 @@ import type {
|
|||||||
AdminKuaishouIndustryRefundApprovePayload,
|
AdminKuaishouIndustryRefundApprovePayload,
|
||||||
AdminKuaishouIndustryRefundDisagreePayload,
|
AdminKuaishouIndustryRefundDisagreePayload,
|
||||||
AdminKuaishouIndustryRefundListPayload,
|
AdminKuaishouIndustryRefundListPayload,
|
||||||
|
AdminKuaishouIndustryShopConfig,
|
||||||
AdminKuaishouIndustryVoucher,
|
AdminKuaishouIndustryVoucher,
|
||||||
AdminKuaishouIndustryVoucherToolPayload,
|
AdminKuaishouIndustryVoucherToolPayload,
|
||||||
} from '@/types/admin'
|
} from '@/types/admin'
|
||||||
@@ -124,6 +126,17 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
const [lastResultTitle, setLastResultTitle] = useState('接口结果')
|
const [lastResultTitle, setLastResultTitle] = useState('接口结果')
|
||||||
const [lastResult, setLastResult] = useState<unknown>(null)
|
const [lastResult, setLastResult] = useState<unknown>(null)
|
||||||
const [refundRows, setRefundRows] = useState<Array<Record<string, unknown>>>([])
|
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>>(
|
const columns = useMemo<TableColumnsType<AdminKuaishouIndustryVoucher>>(
|
||||||
() => [
|
() => [
|
||||||
@@ -206,6 +219,7 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
() => [
|
() => [
|
||||||
{ title: '售后单', dataIndex: 'refundId', minWidth: 160 },
|
{ title: '售后单', dataIndex: 'refundId', minWidth: 160 },
|
||||||
{ title: '订单', dataIndex: 'oid', minWidth: 160 },
|
{ title: '订单', dataIndex: 'oid', minWidth: 160 },
|
||||||
|
{ title: '卖家', dataIndex: 'sellerId', minWidth: 140 },
|
||||||
{ title: '状态', dataIndex: 'status', width: 100 },
|
{ title: '状态', dataIndex: 'status', width: 100 },
|
||||||
{ title: '协商', dataIndex: 'negotiateStatus', width: 100 },
|
{ title: '协商', dataIndex: 'negotiateStatus', width: 100 },
|
||||||
{ title: '金额', dataIndex: 'refundFee', width: 100 },
|
{ title: '金额', dataIndex: 'refundFee', width: 100 },
|
||||||
@@ -230,8 +244,26 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void loadVouchers()
|
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> = {}) {
|
async function loadVouchers(nextFilters: Partial<VoucherFilterState> = {}) {
|
||||||
const filters = { ...voucherFilters, ...nextFilters }
|
const filters = { ...voucherFilters, ...nextFilters }
|
||||||
setVoucherFilters(filters)
|
setVoucherFilters(filters)
|
||||||
@@ -323,12 +355,22 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
|
|
||||||
async function runRefundList() {
|
async function runRefundList() {
|
||||||
const [begin, end] = refundDateRange || []
|
const [begin, end] = refundDateRange || []
|
||||||
await runOpenApiAction('售后单列表', 'refund-list', () =>
|
const sellerId = resolveRefundSellerId(refundListForm.sellerId)
|
||||||
listAdminKuaishouIndustryRefunds({
|
if (!sellerId && refundShopOptions.length > 1) {
|
||||||
...refundListForm,
|
showError('请先选择快手售后退款店铺 sellerId')
|
||||||
beginTime: begin?.valueOf(),
|
return
|
||||||
endTime: end?.valueOf(),
|
}
|
||||||
} satisfies AdminKuaishouIndustryRefundListPayload),
|
|
||||||
|
await runOpenApiAction(
|
||||||
|
'售后单列表',
|
||||||
|
'refund-list',
|
||||||
|
() =>
|
||||||
|
listAdminKuaishouIndustryRefunds({
|
||||||
|
...refundListForm,
|
||||||
|
sellerId,
|
||||||
|
beginTime: begin?.valueOf(),
|
||||||
|
endTime: end?.valueOf(),
|
||||||
|
} satisfies AdminKuaishouIndustryRefundListPayload),
|
||||||
(result) => {
|
(result) => {
|
||||||
const rows = extractRefundRows(result.response)
|
const rows = extractRefundRows(result.response)
|
||||||
setRefundRows(rows)
|
setRefundRows(rows)
|
||||||
@@ -337,19 +379,33 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function runApproveRefund() {
|
async function runApproveRefund() {
|
||||||
|
const sellerId = resolveRefundSellerId(approveForm.sellerId)
|
||||||
|
if (!sellerId && refundShopOptions.length > 1) {
|
||||||
|
showError('请先选择快手售后退款店铺 sellerId')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await runOpenApiAction('同意退款', 'refund-approve', () =>
|
await runOpenApiAction('同意退款', 'refund-approve', () =>
|
||||||
approveAdminKuaishouIndustryRefund({
|
approveAdminKuaishouIndustryRefund({
|
||||||
...approveForm,
|
...approveForm,
|
||||||
sellerId: approveForm.sellerId || refundListForm.sellerId,
|
sellerId,
|
||||||
|
orderId: approveForm.orderId || refundListForm.orderId,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runDisagreeRefund() {
|
async function runDisagreeRefund() {
|
||||||
|
const sellerId = resolveRefundSellerId(disagreeForm.sellerId)
|
||||||
|
if (!sellerId && refundShopOptions.length > 1) {
|
||||||
|
showError('请先选择快手售后退款店铺 sellerId')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await runOpenApiAction('不同意退款', 'refund-disagree', () =>
|
await runOpenApiAction('不同意退款', 'refund-disagree', () =>
|
||||||
disagreeAdminKuaishouIndustryRefund({
|
disagreeAdminKuaishouIndustryRefund({
|
||||||
...disagreeForm,
|
...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>) {
|
function fillRefundAction(row: Record<string, unknown>) {
|
||||||
const refundId = String(row.refundId || '').trim()
|
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 status = String(row.status || '').trim()
|
||||||
const negotiateStatus = String(row.negotiateStatus || '').trim()
|
const negotiateStatus = String(row.negotiateStatus || '').trim()
|
||||||
setApproveForm((current) => ({
|
setApproveForm((current) => ({
|
||||||
...current,
|
...current,
|
||||||
|
sellerId: sellerId || current.sellerId,
|
||||||
|
orderId: orderId || current.orderId,
|
||||||
refundId,
|
refundId,
|
||||||
status,
|
status,
|
||||||
negotiateStatus,
|
negotiateStatus,
|
||||||
refundAmount: String(row.refundFee || current.refundAmount || ''),
|
refundAmount: String(row.refundFee || current.refundAmount || ''),
|
||||||
|
refundHandingWay: String(row.handlingWay || current.refundHandingWay || ''),
|
||||||
}))
|
}))
|
||||||
setDisagreeForm((current) => ({
|
setDisagreeForm((current) => ({
|
||||||
...current,
|
...current,
|
||||||
|
sellerId: sellerId || current.sellerId,
|
||||||
|
orderId: orderId || current.orderId,
|
||||||
refundId,
|
refundId,
|
||||||
status,
|
status,
|
||||||
negotiateStatus: negotiateStatus || current.negotiateStatus,
|
negotiateStatus: negotiateStatus || current.negotiateStatus,
|
||||||
}))
|
}))
|
||||||
|
setRefundListForm((current) => ({
|
||||||
|
...current,
|
||||||
|
sellerId: sellerId || current.sellerId,
|
||||||
|
orderId: orderId || current.orderId,
|
||||||
|
}))
|
||||||
showSuccess('已填入退款操作区')
|
showSuccess('已填入退款操作区')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,14 +512,22 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
allowClear
|
allowClear
|
||||||
placeholder="订单号 oid"
|
placeholder="订单号 oid"
|
||||||
value={voucherFilters.oid}
|
value={voucherFilters.oid}
|
||||||
onChange={(event) => setVoucherFilters({ ...voucherFilters, oid: event.target.value })}
|
onChange={(event) =>
|
||||||
|
setVoucherFilters({
|
||||||
|
...voucherFilters,
|
||||||
|
oid: event.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
allowClear
|
allowClear
|
||||||
placeholder="券码"
|
placeholder="券码"
|
||||||
value={voucherFilters.voucherCode}
|
value={voucherFilters.voucherCode}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setVoucherFilters({ ...voucherFilters, voucherCode: event.target.value })
|
setVoucherFilters({
|
||||||
|
...voucherFilters,
|
||||||
|
voucherCode: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@@ -459,7 +535,10 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
placeholder="任务 ID"
|
placeholder="任务 ID"
|
||||||
value={voucherFilters.taskId}
|
value={voucherFilters.taskId}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setVoucherFilters({ ...voucherFilters, taskId: event.target.value })
|
setVoucherFilters({
|
||||||
|
...voucherFilters,
|
||||||
|
taskId: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@@ -467,7 +546,10 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
placeholder="卖家 ID"
|
placeholder="卖家 ID"
|
||||||
value={voucherFilters.sellerId}
|
value={voucherFilters.sellerId}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setVoucherFilters({ ...voucherFilters, sellerId: event.target.value })
|
setVoucherFilters({
|
||||||
|
...voucherFilters,
|
||||||
|
sellerId: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
@@ -522,7 +604,10 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
placeholder="订单号 oid"
|
placeholder="订单号 oid"
|
||||||
value={toolForm.oid}
|
value={toolForm.oid}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
updateToolForm({ oid: event.target.value, orderId: event.target.value })
|
updateToolForm({
|
||||||
|
oid: event.target.value,
|
||||||
|
orderId: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@@ -609,11 +694,9 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
<div className="page-stack">
|
<div className="page-stack">
|
||||||
<Card title="售后单列表">
|
<Card title="售后单列表">
|
||||||
<Space wrap className="filter-form">
|
<Space wrap className="filter-form">
|
||||||
<Input
|
{renderSellerIdControl(refundListForm.sellerId, (sellerId) =>
|
||||||
placeholder="卖家 ID"
|
updateRefundListForm({ sellerId }),
|
||||||
value={refundListForm.sellerId}
|
)}
|
||||||
onChange={(event) => updateRefundListForm({ sellerId: event.target.value })}
|
|
||||||
/>
|
|
||||||
<Input
|
<Input
|
||||||
placeholder="订单号"
|
placeholder="订单号"
|
||||||
value={refundListForm.orderId}
|
value={refundListForm.orderId}
|
||||||
@@ -633,8 +716,16 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
]}
|
]}
|
||||||
onChange={(value) => updateRefundListForm({ type: value })}
|
onChange={(value) => updateRefundListForm({ type: value })}
|
||||||
/>
|
/>
|
||||||
<Input placeholder="状态" value={refundListForm.status} onChange={(event) => updateRefundListForm({ status: event.target.value })} />
|
<Input
|
||||||
<Input placeholder="游标" value={refundListForm.pcursor} onChange={(event) => updateRefundListForm({ pcursor: event.target.value })} />
|
placeholder="状态"
|
||||||
|
value={refundListForm.status}
|
||||||
|
onChange={(event) => updateRefundListForm({ status: event.target.value })}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
placeholder="游标"
|
||||||
|
value={refundListForm.pcursor}
|
||||||
|
onChange={(event) => updateRefundListForm({ pcursor: event.target.value })}
|
||||||
|
/>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={1}
|
min={1}
|
||||||
max={100}
|
max={100}
|
||||||
@@ -654,7 +745,7 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
rowKey={(row) => String(row.refundId || row.oid || JSON.stringify(row))}
|
rowKey={(row) => String(row.refundId || row.oid || JSON.stringify(row))}
|
||||||
columns={refundColumns}
|
columns={refundColumns}
|
||||||
dataSource={refundRows}
|
dataSource={refundRows}
|
||||||
scroll={{ x: 980 }}
|
scroll={{ x: 1120 }}
|
||||||
pagination={{ pageSize: 10 }}
|
pagination={{ pageSize: 10 }}
|
||||||
style={{ marginTop: 16 }}
|
style={{ marginTop: 16 }}
|
||||||
/>
|
/>
|
||||||
@@ -663,21 +754,27 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
<div className="kuaishou-industry-split">
|
<div className="kuaishou-industry-split">
|
||||||
<Card title="同意退款">
|
<Card title="同意退款">
|
||||||
<div className="kuaishou-industry-tool-grid">
|
<div className="kuaishou-industry-tool-grid">
|
||||||
<Input
|
{renderSellerIdControl(approveForm.sellerId || refundListForm.sellerId, (sellerId) =>
|
||||||
placeholder="卖家 ID"
|
setApproveForm({ ...approveForm, sellerId }),
|
||||||
value={approveForm.sellerId || refundListForm.sellerId}
|
)}
|
||||||
onChange={(event) => setApproveForm({ ...approveForm, sellerId: event.target.value })}
|
|
||||||
/>
|
|
||||||
<Input
|
<Input
|
||||||
placeholder="退款单编号"
|
placeholder="退款单编号"
|
||||||
value={String(approveForm.refundId || '')}
|
value={String(approveForm.refundId || '')}
|
||||||
onChange={(event) => setApproveForm({ ...approveForm, refundId: event.target.value })}
|
onChange={(event) =>
|
||||||
|
setApproveForm({
|
||||||
|
...approveForm,
|
||||||
|
refundId: event.target.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="退款金额(分)"
|
placeholder="退款金额(分)"
|
||||||
value={String(approveForm.refundAmount || '')}
|
value={String(approveForm.refundAmount || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setApproveForm({ ...approveForm, refundAmount: event.target.value })
|
setApproveForm({
|
||||||
|
...approveForm,
|
||||||
|
refundAmount: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@@ -689,14 +786,20 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
placeholder="协商状态"
|
placeholder="协商状态"
|
||||||
value={String(approveForm.negotiateStatus || '')}
|
value={String(approveForm.negotiateStatus || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setApproveForm({ ...approveForm, negotiateStatus: event.target.value })
|
setApproveForm({
|
||||||
|
...approveForm,
|
||||||
|
negotiateStatus: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="退款方式"
|
placeholder="退款方式"
|
||||||
value={String(approveForm.refundHandingWay || '')}
|
value={String(approveForm.refundHandingWay || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setApproveForm({ ...approveForm, refundHandingWay: event.target.value })
|
setApproveForm({
|
||||||
|
...approveForm,
|
||||||
|
refundHandingWay: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@@ -717,46 +820,57 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
|
|
||||||
<Card title="不同意退款">
|
<Card title="不同意退款">
|
||||||
<div className="kuaishou-industry-tool-grid">
|
<div className="kuaishou-industry-tool-grid">
|
||||||
<Input
|
{renderSellerIdControl(disagreeForm.sellerId || refundListForm.sellerId, (sellerId) =>
|
||||||
placeholder="卖家 ID"
|
setDisagreeForm({ ...disagreeForm, sellerId }),
|
||||||
value={disagreeForm.sellerId || refundListForm.sellerId}
|
)}
|
||||||
onChange={(event) =>
|
|
||||||
setDisagreeForm({ ...disagreeForm, sellerId: event.target.value })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
<Input
|
||||||
placeholder="退款单编号"
|
placeholder="退款单编号"
|
||||||
value={String(disagreeForm.refundId || '')}
|
value={String(disagreeForm.refundId || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setDisagreeForm({ ...disagreeForm, refundId: event.target.value })
|
setDisagreeForm({
|
||||||
|
...disagreeForm,
|
||||||
|
refundId: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="拒绝原因枚举"
|
placeholder="拒绝原因枚举"
|
||||||
value={String(disagreeForm.sellerDisagreeReason || '')}
|
value={String(disagreeForm.sellerDisagreeReason || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setDisagreeForm({ ...disagreeForm, sellerDisagreeReason: event.target.value })
|
setDisagreeForm({
|
||||||
|
...disagreeForm,
|
||||||
|
sellerDisagreeReason: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="拒绝说明"
|
placeholder="拒绝说明"
|
||||||
value={disagreeForm.sellerDisagreeDesc}
|
value={disagreeForm.sellerDisagreeDesc}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setDisagreeForm({ ...disagreeForm, sellerDisagreeDesc: event.target.value })
|
setDisagreeForm({
|
||||||
|
...disagreeForm,
|
||||||
|
sellerDisagreeDesc: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="退款单状态"
|
placeholder="退款单状态"
|
||||||
value={String(disagreeForm.status || '')}
|
value={String(disagreeForm.status || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setDisagreeForm({ ...disagreeForm, status: event.target.value })
|
setDisagreeForm({
|
||||||
|
...disagreeForm,
|
||||||
|
status: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="协商状态"
|
placeholder="协商状态"
|
||||||
value={String(disagreeForm.negotiateStatus || '')}
|
value={String(disagreeForm.negotiateStatus || '')}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setDisagreeForm({ ...disagreeForm, negotiateStatus: event.target.value })
|
setDisagreeForm({
|
||||||
|
...disagreeForm,
|
||||||
|
negotiateStatus: event.target.value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -810,9 +924,52 @@ export default function AdminKuaishouIndustryPage() {
|
|||||||
function updateRefundListForm(patch: Partial<RefundListState>) {
|
function updateRefundListForm(patch: Partial<RefundListState>) {
|
||||||
setRefundListForm((current) => ({ ...current, ...patch }))
|
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
|
const data = response?.data
|
||||||
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
||||||
return []
|
return []
|
||||||
@@ -827,12 +984,14 @@ function extractRefundRows(response: Record<string, unknown> | null): Array<Reco
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveOpenApiResultSummary(value: unknown) {
|
function resolveOpenApiResultSummary(value: unknown) {
|
||||||
const result = value && typeof value === 'object' && !Array.isArray(value)
|
const result =
|
||||||
? value as Record<string, unknown>
|
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>
|
const response =
|
||||||
: null
|
result.response && typeof result.response === 'object' && !Array.isArray(result.response)
|
||||||
|
? (result.response as Record<string, unknown>)
|
||||||
|
: null
|
||||||
const success = Boolean(result.success)
|
const success = Boolean(result.success)
|
||||||
const code = String(response?.code || response?.sub_code || '').trim()
|
const code = String(response?.code || response?.sub_code || '').trim()
|
||||||
const resultCode = String(response?.result || '').trim()
|
const resultCode = String(response?.result || '').trim()
|
||||||
@@ -856,7 +1015,8 @@ function resolveOpenApiResultSummary(value: unknown) {
|
|||||||
return {
|
return {
|
||||||
success,
|
success,
|
||||||
title: 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 || '-'
|
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) {
|
function formatTimestamp(value: unknown) {
|
||||||
const timestamp = Number(value || 0)
|
const timestamp = Number(value || 0)
|
||||||
if (!Number.isFinite(timestamp) || timestamp <= 0) {
|
if (!Number.isFinite(timestamp) || timestamp <= 0) {
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ export interface AdminKuaishouIndustryRefundListPayload {
|
|||||||
|
|
||||||
export interface AdminKuaishouIndustryRefundApprovePayload {
|
export interface AdminKuaishouIndustryRefundApprovePayload {
|
||||||
sellerId?: string
|
sellerId?: string
|
||||||
|
orderId?: string
|
||||||
refundId?: number | string
|
refundId?: number | string
|
||||||
desc?: string
|
desc?: string
|
||||||
refundAmount?: number | string
|
refundAmount?: number | string
|
||||||
@@ -86,6 +87,7 @@ export interface AdminKuaishouIndustryRefundApprovePayload {
|
|||||||
|
|
||||||
export interface AdminKuaishouIndustryRefundDisagreePayload {
|
export interface AdminKuaishouIndustryRefundDisagreePayload {
|
||||||
sellerId?: string
|
sellerId?: string
|
||||||
|
orderId?: string
|
||||||
refundId?: number | string
|
refundId?: number | string
|
||||||
sellerDisagreeReason?: number | string
|
sellerDisagreeReason?: number | string
|
||||||
sellerDisagreeDesc?: string
|
sellerDisagreeDesc?: string
|
||||||
|
|||||||
Reference in New Issue
Block a user