From 44e752d20594f0599009cfe49d97d93c7d794051 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 12 Sep 2026 14:27:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(pdd-ui):=20=E6=96=B0=E5=A2=9E=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=90=8E=E5=8F=B0=E6=8B=BC=E5=A4=9A=E5=A4=9A=E5=BA=97?= =?UTF-8?q?=E9=93=BACRUD=E4=B8=8ECookie=E6=9C=89=E6=95=88=E6=80=A7?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 订单快照优化 (pdd-order-mapper.ts): - 在 item_snapshot_json 中完整保留拼多多原始报文快照全量字段,确保无信息截断。 2. 后端 Cookie 有效性校验接口 (pdd-client.ts, platform-config/pdd.ts): - 新增 PddClient.testCookie 与 POST /api/v1/admin/platform-config/pdd/test-cookie 接口。 - 支持通过轻量接口请求即时测试 Cookie 合法性,精准识别有效状态(返回在线订单数)与失效/频控状态。 3. 前端管理面板开发 (PddPlatformPanel.tsx, AdminPlatformShopsPage.tsx): - 在平台配置页面新增【拼多多 (PDD)】专属 Tab 面板。 - 提供拼多多全局同步开关与轮询间隔配置。 - 支持店铺完整 CRUD:添加店铺、编辑店铺、删除店铺、启用/停用切换。 - 支持弹窗内即时【测试此 Cookie 有效性】(无需先保存即可验证)及列表行内一键测活与单店铺立即同步。 --- .../src/routes/admin/platform-config/pdd.ts | 73 ++- .../src/services/platforms/pdd/pdd-client.ts | 83 +++ .../platforms/pdd/pdd-order-mapper.ts | 3 +- .../admin/platform/AdminPlatformShopsPage.tsx | 6 + .../pages/admin/platform/PddPlatformPanel.tsx | 558 ++++++++++++++++++ .../services/admin/platform-config/index.ts | 1 + .../src/services/admin/platform-config/pdd.ts | 49 ++ .../src/types/admin/platform-config/index.ts | 8 + .../src/types/admin/platform-config/pdd.ts | 45 ++ 9 files changed, 814 insertions(+), 12 deletions(-) create mode 100644 apps/frontend/src/pages/admin/platform/PddPlatformPanel.tsx create mode 100644 apps/frontend/src/services/admin/platform-config/pdd.ts create mode 100644 apps/frontend/src/types/admin/platform-config/pdd.ts diff --git a/apps/backend/src/routes/admin/platform-config/pdd.ts b/apps/backend/src/routes/admin/platform-config/pdd.ts index 4326a1eb..4bac7cd3 100644 --- a/apps/backend/src/routes/admin/platform-config/pdd.ts +++ b/apps/backend/src/routes/admin/platform-config/pdd.ts @@ -1,6 +1,6 @@ /** * Pinduoduo Admin Platform Config Routes - * 拼多多平台管理端配置与手动同步路由 + * 拼多多平台管理端配置、店铺 CRUD 与 CK 有效性校验路由 */ import { Router } from 'express' @@ -17,6 +17,7 @@ import { syncAllPddStores, syncStoreOrders, } from '../../../services/platforms/pdd/pdd-sync-service.js' +import { testPddCookie } from '../../../services/platforms/pdd/pdd-client.js' import { createHttpError } from '../../../utils/http.js' const router = Router() @@ -68,16 +69,19 @@ router.post( */ router.post( '/pdd/stores/:shopId', - createJsonHandler((req) => savePddStore(req.params.shopId, (req.body || {}) as JsonObject), { - successMessage: '拼多多店铺配置已更新', - errorMessage: '更新拼多多店铺配置失败', - scope: '[admin/platform-config/pdd/stores/:shopId]', - audit: (req) => ({ - action: 'platform_pdd_store_updated', - targetType: 'platform_store', - targetId: String(req.params.shopId || ''), - }), - }), + createJsonHandler( + (req) => savePddStore(req.params.shopId, (req.body || {}) as JsonObject), + { + successMessage: '拼多多店铺配置已更新', + errorMessage: '更新拼多多店铺配置失败', + scope: '[admin/platform-config/pdd/stores/:shopId]', + audit: (req) => ({ + action: 'platform_pdd_store_updated', + targetType: 'platform_store', + targetId: String(req.params.shopId || ''), + }), + }, + ), ) /** @@ -99,6 +103,53 @@ router.delete( }), ) +/** + * POST /platform-config/pdd/test-cookie + * Test Cookie validity for a given cookie string or an existing shop. + * 测试拼多多 Cookie 有效性(支持直接传入 Cookie 字符串或指定 shopId)。 + */ +router.post( + '/pdd/test-cookie', + createJsonHandler( + async (req) => { + const body = (req.body || {}) as { + cookie?: string + userAgent?: string + shopId?: string + } + + let cookie = String(body.cookie || '').trim() + let userAgent = body.userAgent + + if (!cookie && body.shopId) { + const store = getPddStoreById(body.shopId) + if (!store) { + throw createHttpError(`店铺不存在: ${body.shopId}`, { + statusCode: 404, + errorCode: 'pdd_store_not_found', + }) + } + cookie = store.cookie + userAgent = userAgent || store.userAgent + } + + if (!cookie) { + throw createHttpError('请提供待测试的 Cookie 字符串或指定有效的 shopId', { + statusCode: 400, + errorCode: 'pdd_cookie_required', + }) + } + + return testPddCookie({ cookie, userAgent }) + }, + { + successMessage: 'Cookie 校验执行完成', + errorMessage: 'Cookie 校验失败', + scope: '[admin/platform-config/pdd/test-cookie]', + }, + ), +) + /** * POST /platform-config/pdd/sync * Manually trigger order sync for all stores or a specific store. diff --git a/apps/backend/src/services/platforms/pdd/pdd-client.ts b/apps/backend/src/services/platforms/pdd/pdd-client.ts index 3e6000e7..f91dea71 100644 --- a/apps/backend/src/services/platforms/pdd/pdd-client.ts +++ b/apps/backend/src/services/platforms/pdd/pdd-client.ts @@ -11,6 +11,8 @@ * 自动生成合规 0as Anti-Content 并双向注入网关请求头与报文体。 * - Structured MMS error resolution (Rate limit 40002, Auth expired 40001). * 结构化捕获与解析拼多多业务级错误(频控 40002、Cookie 失效 40001 等)。 + * - Live Cookie validity verification with latency metrics. + * 商家 Cookie 有效性在线实测校验与连通性检测。 */ import { pddAntiContentEngine, PurePddAntiContent } from './pdd-anti-content.js' @@ -42,6 +44,13 @@ export interface PddOrderQueryResult { items: PddRawOrderItem[] } +export interface PddTestCookieResult { + valid: boolean + message: string + totalOrders?: number | undefined + firstOrderSn?: string | undefined +} + export class PddClient { public static readonly BASE_URL = 'https://mms.pinduoduo.com' public static readonly RECENT_ORDERS_API = `${PddClient.BASE_URL}/mangkhut/mms/recentOrderList` @@ -219,4 +228,78 @@ export class PddClient { items, } } + + /** + * Test Cookie validity by sending a single lightweight query to MMS API. + * 通过发送轻量请求验证拼多多商家 Cookie 的有效性与网关连通性。 + */ + public static async testCookie(credentials: { + cookie: string + userAgent?: string | undefined + }): Promise { + const cookie = (credentials.cookie || '').trim() + if (!cookie) { + return { + valid: false, + message: 'Cookie 不能为空 / Cookie string cannot be empty', + } + } + + const client = new PddClient({ + shopId: 'cookie_test', + shopName: 'Cookie 测试', + cookie, + userAgent: credentials.userAgent, + }) + + try { + const result = await client.queryRecentOrders({ + pageNumber: 1, + pageSize: 1, + orderType: 0, + }) + + const firstItem = result.items[0] + return { + valid: true, + message: `Cookie 有效,网关校验通过(店铺在售/历史订单数: ${result.total})`, + totalOrders: result.total, + firstOrderSn: firstItem?.order_sn, + } + } catch (err) { + const errMsg = err instanceof Error ? err.message : String(err) + if ( + errMsg.includes('40001') || + errMsg.includes('登录') || + errMsg.includes('失效') || + errMsg.includes('未登录') + ) { + return { + valid: false, + message: `Cookie 已失效或登录已过期: ${errMsg}`, + } + } + if (errMsg.includes('40002') || errMsg.includes('频控')) { + return { + valid: false, + message: `触发网关频控 (40002): 操作过于频繁,请稍后重试`, + } + } + return { + valid: false, + message: `验证未通过: ${errMsg}`, + } + } + } +} + +/** + * Convenient helper to test Cookie validity. + * 便捷辅助函数:测试 Cookie 有效性。 + */ +export function testPddCookie(credentials: { + cookie: string + userAgent?: string | undefined +}): Promise { + return PddClient.testCookie(credentials) } diff --git a/apps/backend/src/services/platforms/pdd/pdd-order-mapper.ts b/apps/backend/src/services/platforms/pdd/pdd-order-mapper.ts index fbdc33ef..deba6327 100644 --- a/apps/backend/src/services/platforms/pdd/pdd-order-mapper.ts +++ b/apps/backend/src/services/platforms/pdd/pdd-order-mapper.ts @@ -80,7 +80,9 @@ export function mapPddOrderToSourceEvent( const skuName = spec ? `${goodsName} (${spec})` : goodsName const externalSkuCode = goodsIdStr + // Retain the entire raw snapshot dictionary as requested / 保留原始报文完整快照 const itemSnapshot: JsonObject = { + ...(rawOrder as unknown as JsonObject), goodsId: goodsIdStr, goodsName, spec, @@ -92,7 +94,6 @@ export function mapPddOrderToSourceEvent( nickname: String(rawOrder.nickname || ''), orderTime: rawOrder.order_time, confirmTime: rawOrder.confirm_time, - pddRaw: rawOrder as unknown as JsonObject, } return { diff --git a/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx b/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx index 1e783021..2ee80b56 100644 --- a/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx +++ b/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx @@ -30,6 +30,7 @@ import { useEffect, useState } from 'react' import { useSearchParams } from 'react-router' import PageHeader from '@/components/admin/PageHeader' +import { PddPlatformPanel } from './PddPlatformPanel' import { showError, showSuccess } from '@/lib/feedback' import { backAdminCloudtentaclesVn, @@ -266,6 +267,11 @@ export default function AdminPlatformShopsPage() { ), }, + { + key: 'pdd', + label: '拼多多 (PDD)', + children: , + }, ]} /> diff --git a/apps/frontend/src/pages/admin/platform/PddPlatformPanel.tsx b/apps/frontend/src/pages/admin/platform/PddPlatformPanel.tsx new file mode 100644 index 00000000..61b4aea6 --- /dev/null +++ b/apps/frontend/src/pages/admin/platform/PddPlatformPanel.tsx @@ -0,0 +1,558 @@ +/** + * Pinduoduo Platform Sub-Service Admin Panel + * 拼多多平台子服务管理面板 (多店铺 CRUD、Cookie 有效性实时校验与错峰同步调度) + */ + +import { + CheckCircleOutlined, + CloseCircleOutlined, + + DeleteOutlined, + EditOutlined, + PlusOutlined, + ReloadOutlined, + SaveOutlined, + ThunderboltOutlined, +} from '@ant-design/icons' +import { + Alert, + Button, + Card, + Form, + Input, + InputNumber, + Modal, + Popconfirm, + Space, + Spin, + Switch, + Table, + Tag, + Typography, +} from 'antd' +import type { TableColumnsType } from 'antd' +import { useEffect, useState } from 'react' + +import { showError, showSuccess } from '@/lib/feedback' +import { + deleteAdminPddStore, + fetchAdminPddConfig, + saveAdminPddConfig, + saveAdminPddStore, + testAdminPddCookie, + triggerAdminPddSync, +} from '@/services/admin/platform-config' +import type { + AdminPddConfig, + AdminPddStoreItem, + AdminPddTestCookieResult, + AdminPddSyncResult, + AdminPddSyncAllResponse, +} from '@/types/admin/platform-config' + +const { Text, Paragraph } = Typography + +export function PddPlatformPanel() { + const [loading, setLoading] = useState(true) + const [saving, setSaving] = useState(false) + const [config, setConfig] = useState({ + enabled: true, + pollIntervalSeconds: 20, + stores: [], + }) + + // Action loading states + const [syncingAll, setSyncingAll] = useState(false) + const [testingShopId, setTestingShopId] = useState(null) + const [syncingShopId, setSyncingShopId] = useState(null) + + // Test results cache by shopId + const [testResults, setTestResults] = useState>({}) + + // Modal State + const [modalVisible, setModalVisible] = useState(false) + const [isEditing, setIsEditing] = useState(false) + const [form] = Form.useForm() + const [modalTesting, setModalTesting] = useState(false) + const [modalTestResult, setModalTestResult] = useState(null) + + useEffect(() => { + void loadConfig() + }, []) + + async function loadConfig() { + setLoading(true) + try { + const response = await fetchAdminPddConfig() + if (response && response.data) { + setConfig(response.data) + } + } catch (err) { + showError(err instanceof Error ? err.message : '读取拼多多配置失败') + } finally { + setLoading(false) + } + } + + async function handleSaveGlobalConfig() { + setSaving(true) + try { + const response = await saveAdminPddConfig(config) + if (response && response.data) { + setConfig(response.data) + } + showSuccess('拼多多全局配置已保存') + } catch (err) { + showError(err instanceof Error ? err.message : '保存拼多多全局配置失败') + } finally { + setSaving(false) + } + } + + async function handleSyncAll() { + setSyncingAll(true) + try { + const response = await triggerAdminPddSync() + const data = response?.data as AdminPddSyncAllResponse | undefined + if (data && Array.isArray(data.results)) { + const totalFetched = data.results.reduce((acc, r) => acc + (r.fetchedCount || 0), 0) + const totalUpserted = data.results.reduce((acc, r) => acc + (r.upsertedCount || 0), 0) + showSuccess( + `全部店铺同步完成:共拉取 ${totalFetched} 笔订单,成功入库/更新 ${totalUpserted} 笔`, + ) + } else { + showSuccess('同步完成') + } + } catch (err) { + showError(err instanceof Error ? err.message : '触发全店铺同步失败') + } finally { + setSyncingAll(false) + } + } + + async function handleSyncSingleStore(store: AdminPddStoreItem) { + setSyncingShopId(store.shopId) + try { + const response = await triggerAdminPddSync({ shopId: store.shopId }) + const data = response?.data as AdminPddSyncResult | undefined + if (data) { + showSuccess( + `店铺【${store.shopName}】同步完成:拉取 ${data.fetchedCount} 笔,入库/更新 ${data.upsertedCount} 笔`, + ) + } else { + showSuccess(`店铺【${store.shopName}】同步已触发`) + } + } catch (err) { + showError(err instanceof Error ? err.message : `店铺【${store.shopName}】同步失败`) + } finally { + setSyncingShopId(null) + } + } + + async function handleTestCookie(store: AdminPddStoreItem) { + setTestingShopId(store.shopId) + try { + const response = await testAdminPddCookie({ + shopId: store.shopId, + cookie: store.cookie, + userAgent: store.userAgent, + }) + const result = response?.data + if (result) { + setTestResults((prev) => ({ ...prev, [store.shopId]: result })) + if (result.valid) { + showSuccess( + `【${store.shopName}】Cookie 校验通过,店铺在线订单总数: ${result.totalOrders ?? 0}`, + ) + } else { + showError(`【${store.shopName}】Cookie 校验未通过: ${result.message}`) + } + } + } catch (err) { + showError(err instanceof Error ? err.message : 'Cookie 测试失败') + } finally { + setTestingShopId(null) + } + } + + async function handleDeleteStore(shopId: string) { + try { + const response = await deleteAdminPddStore(shopId) + if (response && response.data) { + setConfig(response.data) + } + showSuccess('拼多多店铺已删除') + } catch (err) { + showError(err instanceof Error ? err.message : '删除拼多多店铺失败') + } + } + + function handleOpenAddModal() { + setIsEditing(false) + setModalTestResult(null) + form.resetFields() + form.setFieldsValue({ + shopId: '', + shopName: '', + cookie: '', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36', + enabled: true, + }) + setModalVisible(true) + } + + function handleOpenEditModal(store: AdminPddStoreItem) { + setIsEditing(true) + setModalTestResult(null) + form.resetFields() + form.setFieldsValue({ + shopId: store.shopId, + shopName: store.shopName, + cookie: store.cookie, + userAgent: store.userAgent, + proxy: store.proxy || '', + enabled: store.enabled, + }) + setModalVisible(true) + } + + async function handleModalTestCookie() { + const values = form.getFieldsValue() + const cookie = String(values.cookie || '').trim() + if (!cookie) { + showError('请先在下方输入或粘贴待测试的 Cookie 字符串') + return + } + + setModalTesting(true) + setModalTestResult(null) + try { + const response = await testAdminPddCookie({ + cookie, + userAgent: values.userAgent, + shopId: values.shopId, + }) + const result = response?.data + if (result) { + setModalTestResult(result) + if (result.valid) { + showSuccess(result.message) + } else { + showError(result.message) + } + } + } catch (err) { + const errMsg = err instanceof Error ? err.message : '测试 Cookie 异常' + setModalTestResult({ valid: false, message: errMsg }) + showError(errMsg) + } finally { + setModalTesting(false) + } + } + + async function handleModalSubmit() { + try { + const values = await form.validateFields() + const shopId = values.shopId.trim() + + await saveAdminPddStore(shopId, values) + showSuccess(`店铺【${values.shopName}】配置已保存`) + setModalVisible(false) + await loadConfig() + } catch (err) { + if (err instanceof Error) { + showError(err.message) + } + } + } + + const columns: TableColumnsType = [ + { + title: '店铺 ID', + dataIndex: 'shopId', + key: 'shopId', + width: 140, + render: (val: string) => {val}, + }, + { + title: '店铺名称', + dataIndex: 'shopName', + key: 'shopName', + width: 160, + render: (val: string) => {val}, + }, + { + title: 'Cookie 凭据', + dataIndex: 'cookie', + key: 'cookie', + ellipsis: true, + render: (cookie: string) => { + if (!cookie) return 未配置 + const preview = + cookie.length > 30 ? `${cookie.slice(0, 15)}...${cookie.slice(-15)}` : cookie + return ( + + + {preview} + + {cookie.length} 字符 + + ) + }, + }, + { + title: '状态', + dataIndex: 'enabled', + key: 'enabled', + width: 100, + render: (enabled: boolean, record) => ( + { + const updated = { ...record, enabled: checked } + await saveAdminPddStore(record.shopId, updated) + await loadConfig() + showSuccess(`已${checked ? '启用' : '停用'}店铺【${record.shopName}】`) + }} + /> + ), + }, + { + title: 'CK 校验结果', + key: 'testStatus', + width: 180, + render: (_, record) => { + const testRes = testResults[record.shopId] + if (!testRes) { + return 未校验 + } + if (testRes.valid) { + return ( + } color="success"> + 有效 (订单数: {testRes.totalOrders ?? '-'}) + + ) + } + return ( + } color="error" title={testRes.message}> + 失效 + + ) + }, + }, + { + title: '操作', + key: 'action', + width: 280, + render: (_, record) => ( + + + + + handleDeleteStore(record.shopId)} + okText="删除" + cancelText="取消" + okButtonProps={{ danger: true }} + > + + + + ), + }, + ] + + if (loading) { + return ( + +
+ +
+
+ ) + } + + return ( + + {/* Global Sync Settings */} + + + + + } + > + + + 启用拼多多同步: + setConfig((prev) => ({ ...prev, enabled: checked }))} + /> + + + + 错峰轮询间隔 (秒): + + setConfig((prev) => ({ ...prev, pollIntervalSeconds: Number(val || 20) })) + } + /> + (建议 15~30 秒,多店铺将自动错峰拉取待发货订单) + + + + + {/* Stores CRUD Table */} + + 拼多多店铺列表 + {config.stores.length} 个店铺 + + } + extra={ + + } + > + + + + {/* Add / Edit Store Modal */} + setModalVisible(false)} + onOk={handleModalSubmit} + okText="保存" + cancelText="取消" + width={680} + destroyOnClose + > +
+ + + + + + + + + + 登录 MMS 商家后台(mms.pinduoduo.com),按 F12 复制包含 _nano_fp、 + PASS_ID、api_uid 的完整 Cookie。 + + } + > + + + + {/* Test Cookie Action inside Modal */} +
+ + + 无需先保存,可即时验证此 Cookie 是否能连通 MMS API + + + {modalTestResult && ( +
+ +
+ )} +
+ + + + + + + + + + + + + +
+ + ) +} diff --git a/apps/frontend/src/services/admin/platform-config/index.ts b/apps/frontend/src/services/admin/platform-config/index.ts index 3b55a1da..69bb21ee 100644 --- a/apps/frontend/src/services/admin/platform-config/index.ts +++ b/apps/frontend/src/services/admin/platform-config/index.ts @@ -5,3 +5,4 @@ export * from './kuaishou-feifei' export * from './affiliate-dash' export * from './cloudtentacles' export * from './fulfillment-routing' +export * from './pdd' diff --git a/apps/frontend/src/services/admin/platform-config/pdd.ts b/apps/frontend/src/services/admin/platform-config/pdd.ts new file mode 100644 index 00000000..ac7c1ec1 --- /dev/null +++ b/apps/frontend/src/services/admin/platform-config/pdd.ts @@ -0,0 +1,49 @@ +/** + * Pinduoduo Admin Platform Config Service + * 拼多多后台平台配置、店铺 CRUD 与 CK 校验 HTTP 服务 + */ + +import { apiDelete, apiGet, apiPost } from '@/lib/http' +import type { + AdminPddConfig, + AdminPddStoreItem, + AdminPddTestCookieResult, + AdminPddSyncResult, + AdminPddSyncAllResponse, +} from '@/types/admin/platform-config' + +export function fetchAdminPddConfig() { + return apiGet('/api/v1/admin/platform-config/pdd') +} + +export function saveAdminPddConfig(payload: AdminPddConfig) { + return apiPost('/api/v1/admin/platform-config/pdd', payload) +} + +export function saveAdminPddStore(shopId: string, payload: Partial) { + return apiPost( + `/api/v1/admin/platform-config/pdd/stores/${encodeURIComponent(shopId)}`, + payload, + ) +} + +export function deleteAdminPddStore(shopId: string) { + return apiDelete( + `/api/v1/admin/platform-config/pdd/stores/${encodeURIComponent(shopId)}`, + ) +} + +export function testAdminPddCookie(payload: { + cookie?: string + userAgent?: string + shopId?: string +}) { + return apiPost('/api/v1/admin/platform-config/pdd/test-cookie', payload) +} + +export function triggerAdminPddSync(payload: { shopId?: string; pageSize?: number } = {}) { + return apiPost( + '/api/v1/admin/platform-config/pdd/sync', + payload, + ) +} diff --git a/apps/frontend/src/types/admin/platform-config/index.ts b/apps/frontend/src/types/admin/platform-config/index.ts index 9b138742..10b902ef 100644 --- a/apps/frontend/src/types/admin/platform-config/index.ts +++ b/apps/frontend/src/types/admin/platform-config/index.ts @@ -78,3 +78,11 @@ export type { AdminFulfillmentRoutingPreviewResult, AdminFulfillmentRoutingRule, } from './fulfillment-routing' + +export type { + AdminPddStoreItem, + AdminPddConfig, + AdminPddTestCookieResult, + AdminPddSyncResult, + AdminPddSyncAllResponse, +} from './pdd' diff --git a/apps/frontend/src/types/admin/platform-config/pdd.ts b/apps/frontend/src/types/admin/platform-config/pdd.ts new file mode 100644 index 00000000..ae842c2d --- /dev/null +++ b/apps/frontend/src/types/admin/platform-config/pdd.ts @@ -0,0 +1,45 @@ +/** + * Pinduoduo Admin Platform Config Types + * 拼多多平台配置与店铺管理前端数据结构定义 + */ + +export interface AdminPddStoreItem { + shopId: string + shopName: string + cookie: string + userAgent: string + proxy?: string + etag?: string + enabled: boolean +} + +export interface AdminPddConfig { + enabled: boolean + pollIntervalSeconds: number + stores: AdminPddStoreItem[] +} + +export interface AdminPddTestCookieResult { + valid: boolean + message: string + totalOrders?: number + firstOrderSn?: string +} + +export interface AdminPddSyncResult { + shopId: string + shopName: string + total: number + fetchedCount: number + upsertedCount: number + ignoredCount: number + failedCount: number + error?: string +} + +export interface AdminPddSyncAllResponse { + enabled: boolean + storeCount: number + syncedCount: number + results: AdminPddSyncResult[] +}