实现内置虎牙扫码登录与绑定 Connector
This commit is contained in:
@@ -124,7 +124,7 @@ export default function AdminDevMockPage() {
|
||||
<section className="page-stack">
|
||||
<PageHeader
|
||||
title="开发 Mock"
|
||||
description="一键造单、测领取页与 91 查单,无需真实 91 / affiliate-dash 环境。"
|
||||
description="一键造单与测试数据;半自动履约可选择只 Mock 订单,登录、绑定走真实 Connector。"
|
||||
extra={
|
||||
<Typography.Text type="secondary">NODE_ENV={status?.nodeEnv || '-'}</Typography.Text>
|
||||
}
|
||||
@@ -134,8 +134,8 @@ export default function AdminDevMockPage() {
|
||||
type="info"
|
||||
showIcon
|
||||
icon={<BugOutlined />}
|
||||
message="Mock 会写入开发库真实订单/任务;当前仅保留 affiliate-dash / 电子凭证 / 91 查单。"
|
||||
description="affiliate-dash 可用默认 UID 测试绑定与提交发货。"
|
||||
message="Mock 会写入开发库真实订单/任务;除订单外,登录、绑定、票据注入和完成确认都可以走真实流程。"
|
||||
description="默认使用 order_site 内置真实 Connector,不依赖 live-hub-py;只有显式选择内置 Mock 时才会 Mock 登录和绑定。"
|
||||
/>
|
||||
|
||||
<Row gutter={[16, 16]}>
|
||||
@@ -149,10 +149,12 @@ export default function AdminDevMockPage() {
|
||||
</Col>
|
||||
|
||||
<Col xs={24} xl={12}>
|
||||
<Card title="2. 半自动履约测试单(Mock Connector)" bordered={false}>
|
||||
<Card title="2. 半自动履约测试单(可选 Mock 范围)" bordered={false}>
|
||||
<SemiAutoMockForm
|
||||
loading={semiAutoMutation.isPending}
|
||||
connectorMode={status?.semiAuto?.connectorMode}
|
||||
defaultConnectorMode={status?.semiAuto?.defaultConnectorMode}
|
||||
externalConnectorConfigured={status?.semiAuto?.externalConnectorConfigured}
|
||||
mockConnectorAvailable={status?.semiAuto?.mockConnectorAvailable}
|
||||
onSubmit={(values) => semiAutoMutation.mutate(values)}
|
||||
/>
|
||||
</Card>
|
||||
@@ -340,12 +342,22 @@ export default function AdminDevMockPage() {
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Alert
|
||||
type={lastSemiAuto.connectorMode === 'mock' ? 'success' : 'warning'}
|
||||
type={
|
||||
lastSemiAuto.connectorMode === 'mock'
|
||||
? 'warning'
|
||||
: lastSemiAuto.connectorConfigured
|
||||
? 'success'
|
||||
: 'error'
|
||||
}
|
||||
showIcon
|
||||
message={
|
||||
lastSemiAuto.connectorMode === 'mock'
|
||||
? '当前使用内置 Mock Connector'
|
||||
: '当前使用外部 Connector'
|
||||
: lastSemiAuto.connectorConfigured
|
||||
? lastSemiAuto.connectorMode === 'external'
|
||||
? '当前使用远程真实 Connector'
|
||||
: '当前使用 order_site 内置真实 Connector'
|
||||
: '当前选择远程真实 Connector,但尚未配置'
|
||||
}
|
||||
description={
|
||||
<ul style={{ margin: 0, paddingLeft: 18 }}>
|
||||
@@ -503,29 +515,70 @@ function KuaishouIndustryVoucherMockForm({
|
||||
|
||||
function SemiAutoMockForm({
|
||||
loading,
|
||||
connectorMode,
|
||||
defaultConnectorMode,
|
||||
externalConnectorConfigured,
|
||||
mockConnectorAvailable,
|
||||
onSubmit,
|
||||
}: {
|
||||
loading: boolean
|
||||
connectorMode?: 'mock' | 'external'
|
||||
defaultConnectorMode?: 'embedded' | 'external' | 'mock'
|
||||
externalConnectorConfigured?: boolean
|
||||
mockConnectorAvailable?: boolean
|
||||
onSubmit: (values: {
|
||||
orderNo?: string
|
||||
skuName?: string
|
||||
quantity?: number
|
||||
pageTitle?: string
|
||||
browserTargetUrl?: string
|
||||
connectorMode?: 'embedded' | 'external' | 'mock'
|
||||
}) => void
|
||||
}) {
|
||||
const [form] = Form.useForm()
|
||||
const defaultMode =
|
||||
defaultConnectorMode === 'mock' && mockConnectorAvailable
|
||||
? 'mock'
|
||||
: defaultConnectorMode === 'external'
|
||||
? 'external'
|
||||
: 'embedded'
|
||||
const selectedMode =
|
||||
(Form.useWatch('connectorMode', form) as 'embedded' | 'external' | 'mock' | undefined) ||
|
||||
defaultMode
|
||||
|
||||
return (
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
initialValues={{
|
||||
quantity: 1,
|
||||
pageTitle: '虎牙账号授权测试',
|
||||
browserTargetUrl: 'https://www.huya.com/',
|
||||
connectorMode: defaultMode,
|
||||
}}
|
||||
onFinish={onSubmit}
|
||||
>
|
||||
<Form.Item
|
||||
label="Mock 范围"
|
||||
name="connectorMode"
|
||||
extra="只 Mock 订单时,登录、角色绑定和浏览器票据注入可走内置真实 Connector,也可显式使用远程 Connector。"
|
||||
>
|
||||
<Select
|
||||
options={[
|
||||
{
|
||||
value: 'embedded',
|
||||
label: '仅 Mock 订单(内置真实登录 / 绑定 / 注入)',
|
||||
},
|
||||
{
|
||||
value: 'external',
|
||||
label: '仅 Mock 订单(远程真实 Connector)',
|
||||
},
|
||||
{
|
||||
value: 'mock',
|
||||
label: '订单 + 登录绑定都 Mock(内置 Connector)',
|
||||
disabled: mockConnectorAvailable === false,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="内部 SKU 名称(可空)"
|
||||
name="skuName"
|
||||
@@ -552,15 +605,23 @@ function SemiAutoMockForm({
|
||||
<Input placeholder="https://www.huya.com/" />
|
||||
</Form.Item>
|
||||
<Alert
|
||||
type={connectorMode === 'mock' ? 'success' : 'warning'}
|
||||
type={
|
||||
selectedMode === 'mock'
|
||||
? 'warning'
|
||||
: selectedMode === 'external' && !externalConnectorConfigured
|
||||
? 'error'
|
||||
: 'success'
|
||||
}
|
||||
showIcon
|
||||
style={{ marginBottom: 12 }}
|
||||
message={
|
||||
connectorMode === 'mock'
|
||||
? '内置 Mock Connector 已启用,登录和绑定会自动推进。'
|
||||
: connectorMode === 'external'
|
||||
? '当前配置为外部 Connector,请先确认外部服务已启动。'
|
||||
: 'Connector 状态未知;生成后可在客户页验证。'
|
||||
selectedMode === 'mock'
|
||||
? '登录和绑定会使用内置 Mock Connector,仅用于联调页面。'
|
||||
: selectedMode === 'external'
|
||||
? externalConnectorConfigured
|
||||
? '远程真实 Connector 已配置;只有订单由 Mock 生成。'
|
||||
: '远程真实 Connector 未配置:请设置 SEMI_AUTO_CONNECTOR_BASE_URL 和 API_KEY。'
|
||||
: '使用 order_site 内置真实 Connector;无需启动 live-hub-py,只有订单由 Mock 生成。'
|
||||
}
|
||||
/>
|
||||
<Button type="primary" htmlType="submit" loading={loading} block>
|
||||
|
||||
@@ -268,6 +268,16 @@ export default function AdminSemiAutoTasksPage() {
|
||||
width: 90,
|
||||
render: (value: string) => <Tag color="purple">{PLATFORM_LABELS[value] || value}</Tag>,
|
||||
},
|
||||
{
|
||||
title: 'Connector',
|
||||
dataIndex: 'connectorMode',
|
||||
width: 110,
|
||||
render: (value: string) => (
|
||||
<Tag color={value === 'mock' ? 'orange' : 'green'}>
|
||||
{value === 'mock' ? '内置 Mock' : '真实'}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '客户登录',
|
||||
key: 'login',
|
||||
@@ -457,6 +467,15 @@ export default function AdminSemiAutoTasksPage() {
|
||||
<Descriptions.Item label="平台">
|
||||
{PLATFORM_LABELS[detail.task.platform] || detail.task.platform}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Connector">
|
||||
<Tag color={detail.task.connectorMode === 'mock' ? 'orange' : 'green'}>
|
||||
{detail.task.connectorMode === 'mock'
|
||||
? '内置 Mock'
|
||||
: detail.task.connectorMode === 'external'
|
||||
? '远程真实'
|
||||
: '内置真实'}
|
||||
</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="当前状态">
|
||||
<Tag color={STATUS_COLORS[detail.task.displayStatus.key] || 'default'}>
|
||||
{detail.task.displayStatus.label}
|
||||
|
||||
@@ -100,6 +100,10 @@ export default function CustomerFulfillmentPage() {
|
||||
}, [orderNo, selectedTask?.id])
|
||||
|
||||
useEffect(() => {
|
||||
if (loginInfo?.qrImage) {
|
||||
setLoginQrImage(loginInfo.qrImage)
|
||||
return
|
||||
}
|
||||
if (!loginInfo?.qrContent) {
|
||||
setLoginQrImage('')
|
||||
return
|
||||
@@ -109,7 +113,7 @@ export default function CustomerFulfillmentPage() {
|
||||
margin: 2,
|
||||
color: { dark: '#111827', light: '#ffffff' },
|
||||
}).then(setLoginQrImage)
|
||||
}, [loginInfo?.qrContent])
|
||||
}, [loginInfo?.qrContent, loginInfo?.qrImage])
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedTask || !orderNo) return
|
||||
|
||||
@@ -11,8 +11,9 @@ export type DevMockStatus = {
|
||||
steps: string[]
|
||||
}>
|
||||
semiAuto?: {
|
||||
connectorMode: 'mock' | 'external'
|
||||
connectorConfigured: boolean
|
||||
defaultConnectorMode: 'embedded' | 'external' | 'mock'
|
||||
externalConnectorConfigured: boolean
|
||||
mockConnectorAvailable: boolean
|
||||
platform: string
|
||||
}
|
||||
}
|
||||
@@ -59,7 +60,8 @@ export type DevMockSemiAutoResult = {
|
||||
configId: number
|
||||
taskId: number
|
||||
skuKey: string
|
||||
connectorMode: 'mock' | 'external'
|
||||
connectorMode: 'embedded' | 'external' | 'mock'
|
||||
connectorConfigured: boolean
|
||||
customerPath: string
|
||||
adminPath: string
|
||||
tips: string[]
|
||||
@@ -93,6 +95,7 @@ export function createSemiAutoDevMock(payload: {
|
||||
pageTitle?: string
|
||||
pageDescription?: string
|
||||
browserTargetUrl?: string
|
||||
connectorMode?: 'embedded' | 'external' | 'mock'
|
||||
}) {
|
||||
return apiPost<DevMockSemiAutoResult>('/api/v1/admin/dev-mock/semi-auto', payload)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export type SemiAutoTask = {
|
||||
loginStatus: string
|
||||
bindingStatus: string
|
||||
executionStatus: string
|
||||
connectorMode: 'embedded' | 'external' | 'mock'
|
||||
displayStatus: SemiAutoDisplayStatus
|
||||
connectorReady: boolean
|
||||
huyaUid: string
|
||||
|
||||
@@ -29,6 +29,7 @@ export type CustomerSemiAutoTask = {
|
||||
export type CustomerLoginInfo = {
|
||||
status: string
|
||||
qrContent: string
|
||||
qrImage?: string
|
||||
expiresAt: string
|
||||
message: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user