import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import {
Alert, Button, Card, Col, Descriptions, Form, Input, InputNumber, Row, Select, Space,
Tabs, Tag, Typography, message,
} from 'antd';
import { request } from '../lib/api';
type XfxConfig = {
provider: string;
activeProvider: string;
apiUrl: string;
appId: string | null;
mchId: string | null;
mchIdMasked: string | null;
hasApiKey: boolean;
signType: string;
ready: boolean;
source?: string;
hint?: string;
};
type ApiResult = {
ok: boolean;
elapsedMs: number;
data?: unknown;
error?: string;
code?: string;
provider?: string;
raw?: unknown;
};
const CREATE_DEFAULTS = {
outNumber: `TEST-${Date.now()}`,
fromName: '杜康仓库',
fromMobile: '13800000000',
fromAddress: '河南省郑州市金水区',
fromAddressDetail: '杜康酒业仓',
fromLng: 113.665,
fromLat: 34.757,
toName: '测试收货人',
toMobile: '13800000001',
toAddress: '河南省郑州市二七区',
toAddressDetail: '测试路 1 号',
toLng: 113.640,
toLat: 34.720,
goodsName: '杜康酒',
goodsNum: 2,
weight: 2,
payMode: '1',
remark: 'Admin 联调测试',
};
function ResultPanel({ result }: { result: ApiResult | null }) {
if (!result) return 点击「调用接口」后在此显示响应;
return (
{result.ok ? '成功' : '失败'}
{result.elapsedMs} ms
{result.code && code: {result.code}}
{JSON.stringify(result, null, 2)}
);
}
export default function XiaofeixiaTestPage() {
const [config, setConfig] = useState(null);
const [loading, setLoading] = useState(false);
const [result, setResult] = useState(null);
const [freightForm] = Form.useForm();
const [coverageForm] = Form.useForm();
const [createForm] = Form.useForm();
const [queryForm] = Form.useForm();
const [batchForm] = Form.useForm();
const [trackForm] = Form.useForm();
const [cancelForm] = Form.useForm();
useEffect(() => {
void request('/admin/courier/xiaofeixia/config').then(setConfig);
createForm.setFieldsValue(CREATE_DEFAULTS);
freightForm.setFieldsValue({ weight: 2 });
coverageForm.setFieldsValue({ toAddress: '河南省郑州市二七区测试路1号' });
}, [createForm, freightForm, coverageForm]);
async function invoke(path: string, body: unknown) {
setLoading(true);
setResult(null);
try {
const res = await request(path, {
method: 'POST',
body: JSON.stringify(body),
});
setResult(res);
if (res.ok) message.success('调用成功');
else message.warning(res.error || '调用失败');
} catch (e) {
const err = e instanceof Error ? e.message : String(e);
message.error(err);
setResult({ ok: false, elapsedMs: 0, error: err });
} finally {
setLoading(false);
}
}
function parseList(text?: string) {
return (text ?? '').split(/[,,\s]+/).map((s) => s.trim()).filter(Boolean);
}
return (
小飞侠接口联调
通过 HQ 后台直接调用后端封装的小飞侠 API(cmd 100101~100301)。凭证请在
仓配管理
中配置;联调会优先使用仓配管理里启用的小飞侠承运商。
{config && (
{config.activeProvider}
{config.apiUrl}
{config.mchIdMasked || '—'}
{config.signType}
{config.hasApiKey ? 已配置 : 未配置}
{config.ready ? 可调用 : 配置不完整}
{config.source === 'fulfillment_provider' ? '仓配管理' : '环境变量(兼容)'}
{config.hint ? ` · ${config.hint}` : ''}
{!config.ready && (
)}
)}
void invoke('/admin/courier/xiaofeixia/estimate-freight', v)}>
),
},
{
key: 'coverage',
label: '配送范围 (100301)',
children: (
),
},
{
key: 'create',
label: '创建订单 (100101)',
children: (
寄件人
收件人
),
},
{
key: 'query',
label: '查询订单 (100104)',
children: (
),
},
{
key: 'batch',
label: '批量查询 (100106)',
children: (
),
},
{
key: 'track',
label: '路由查询 (100102)',
children: (
),
},
{
key: 'cancel',
label: '取消订单 (100103)',
children: (
),
},
]}
/>
);
}