import { useEffect, useState } from 'react' import { Card, Table, Typography, Space, Tag, Button, Modal, Form, Input, InputNumber, Select, Switch, message, Divider, Descriptions, } from 'antd' import { PlusOutlined, ShopOutlined, CopyOutlined } from '@ant-design/icons' import { listSites, onboardSite, fetchDistributionSiteDefaults, type Site, type OnboardSitePayload, type OnboardSiteResult } from '../api' export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean }) { const [items, setItems] = useState([]) const [loading, setLoading] = useState(false) const [modalOpen, setModalOpen] = useState(false) const [submitting, setSubmitting] = useState(false) const [successResult, setSuccessResult] = useState(null) const [defaultSettlementHoldDays, setDefaultSettlementHoldDays] = useState(7) const [form] = Form.useForm() const loadData = () => { setLoading(true) listSites() .then(setItems) .catch(() => message.error('站点加载失败')) .finally(() => setLoading(false)) } useEffect(() => { loadData() fetchDistributionSiteDefaults() .then((res) => { const days = res?.default_settlement_hold_days if (typeof days === 'number' && days >= 0 && days <= 365) { setDefaultSettlementHoldDays(days) } }) .catch(() => { // 拉取失败时保持内置默认值 7 }) }, []) const handleOpenModal = () => { form.resetFields() form.setFieldsValue({ member_type: 'operator', display_account_enabled: true, tax_enabled: false, tax_rate_bps: 100, settlement_hold_days: defaultSettlementHoldDays, }) setModalOpen(true) } const handleOnboardSubmit = async (values: any) => { setSubmitting(true) try { const payload: OnboardSitePayload = { site_code: values.site_code.trim(), site_name: values.site_name.trim(), domain: values.domain.trim(), admin_username: values.admin_username.trim(), admin_password: values.admin_password, admin_nickname: values.admin_nickname?.trim() || undefined, member_type: values.member_type, display_account_enabled: values.display_account_enabled, tax_enabled: values.tax_enabled, tax_rate_bps: values.tax_enabled ? values.tax_rate_bps : 0, settlement_hold_days: Number(values.settlement_hold_days ?? defaultSettlementHoldDays), } const res = await onboardSite(payload) message.success('分销站点及分销商管理员开通成功!') setModalOpen(false) setSuccessResult(res) loadData() } catch (err: any) { const msg = err?.response?.data?.message || '开通分销商失败,请检查站点标识或管理员用户名是否重复' message.error(msg) } finally { setSubmitting(false) } } return (
分销网站管理 管理全平台合作分销站点、域名配置与分销商管理员账号
{isSuperadmin && ( )}
( {v} ), }, { title: '站点标识', dataIndex: 'site_code', width: 140, render: (v: string) => {v}, }, { title: '绑定域名', dataIndex: 'domain', width: 220, render: (v: string) => ( {v} ), }, { title: '运行状态', dataIndex: 'status', width: 110, render: (v: string) => ( {v === 'active' ? '正常运营' : v} ), }, { title: '账号展示', dataIndex: 'display_account_enabled', width: 100, render: (v: boolean) => (v ? 开启 : 关闭), }, { title: '税费设定', width: 110, render: (_: unknown, row: Site) => row.tax_enabled ? {row.tax_rate_bps / 100}% : 不征税, }, { title: '收号下调', width: 120, render: (_: unknown, row: Site) => Number(row.receive_ratio_delta || 0) > 0 ? ( -{Number(row.receive_ratio_delta).toFixed(1)} 点 ) : ( 与主站一致 ), }, { title: '创建时间', dataIndex: 'created_at', width: 140, render: (v: string) => (v ? new Date(v).toLocaleDateString() : '-'), }, ]} /> {/* 开通分销商 Modal */} setModalOpen(false)} footer={null} width={680} destroyOnClose >
1. 站点基础信息 2. 分销商管理员账号