diff --git a/.umirc.ts b/.umirc.ts index 86cce20..0e17571 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -43,6 +43,18 @@ export default defineConfig({ }, ], }, + { + name: '站点管理', + path: '/site', + access: 'canSeeSite', + routes: [ + { + name: '站点列表', + path: '/site/list', + component: './Site/List', + }, + ], + }, { name: '商品管理', path: '/product', diff --git a/src/access.ts b/src/access.ts index 35a8b86..c6d252a 100644 --- a/src/access.ts +++ b/src/access.ts @@ -9,6 +9,7 @@ export default (initialState: any) => { const canSeeCustomer = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('customer') ?? false); const canSeeLogistics = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('logistics') ?? false); const canSeeStatistics = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('statistics') ?? false); + const canSeeSite = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('site') ?? false); return { canSeeOrganiza, @@ -18,5 +19,6 @@ export default (initialState: any) => { canSeeCustomer, canSeeLogistics, canSeeStatistics, + canSeeSite, }; }; diff --git a/src/pages/Site/List/index.tsx b/src/pages/Site/List/index.tsx new file mode 100644 index 0000000..1803241 --- /dev/null +++ b/src/pages/Site/List/index.tsx @@ -0,0 +1,254 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { ActionType, ProColumns, ProTable, ProFormInstance } from '@ant-design/pro-components'; +import { DrawerForm, ProFormText, ProFormSelect, ProFormSwitch } from '@ant-design/pro-components'; +import { Button, message, Popconfirm, Space, Tag } from 'antd'; +import { request } from '@umijs/max'; + +// 中文注释:站点数据项类型(前端不包含密钥字段,后端列表不返回密钥) +interface SiteItem { + id: number; + siteName: string; + apiUrl?: string; + type?: 'woocommerce' | 'shopyy'; + skuPrefix?: string; + isDisabled: number; +} + +// 中文注释:创建/更新表单的值类型,包含可选的密钥字段 +interface SiteFormValues { + siteName: string; + apiUrl?: string; + type?: 'woocommerce' | 'shopyy'; + isDisabled?: boolean; + consumerKey?: string; // 中文注释:WooCommerce REST API 的 consumer key + consumerSecret?: string; // 中文注释:WooCommerce REST API 的 consumer secret + skuPrefix?: string; +} + +const SiteList: React.FC = () => { + const actionRef = useRef(); + const formRef = useRef(); + const [open, setOpen] = useState(false); + const [editing, setEditing] = useState(null); + + useEffect(() => { + if (!open) return; + if (editing) { + formRef.current?.setFieldsValue({ + siteName: editing.siteName, + apiUrl: editing.apiUrl, + type: editing.type, + skuPrefix: editing.skuPrefix, + isDisabled: !!editing.isDisabled, + consumerKey: undefined, + consumerSecret: undefined, + }); + } else { + formRef.current?.setFieldsValue({ + siteName: undefined, + apiUrl: undefined, + type: 'woocommerce', + skuPrefix: undefined, + isDisabled: false, + consumerKey: undefined, + consumerSecret: undefined, + }); + } + }, [open, editing]); + + // 中文注释:表格列定义 + const columns: ProColumns[] = [ + { title: 'ID', dataIndex: 'id', width: 80, sorter: true, hideInSearch: true }, + { title: '站点名称', dataIndex: 'siteName', width: 220 }, + { title: 'API 地址', dataIndex: 'apiUrl', width: 280, hideInSearch: true }, + { title: 'SKU 前缀', dataIndex: 'skuPrefix', width: 160, hideInSearch: true }, + { + title: '平台', + dataIndex: 'type', + width: 140, + valueType: 'select', + request: async () => [ + { label: 'WooCommerce', value: 'woocommerce' }, + { label: 'Shopyy', value: 'shopyy' }, + ], + }, + { + title: '状态', + dataIndex: 'isDisabled', + width: 120, + hideInSearch: true, + render: (_, row) => ( + + {row.isDisabled ? '已禁用' : '启用中'} + + ), + }, + { + title: '操作', + dataIndex: 'actions', + width: 240, + hideInSearch: true, + render: (_, row) => ( + + + { + try { + await request(`/site/disable/${row.id}`, { + method: 'PUT', + data: { disabled: !row.isDisabled }, + }); + message.success('更新成功'); + actionRef.current?.reload(); + } catch (e: any) { + message.error(e?.message || '更新失败'); + } + }} + > + + + + ), + }, + ]; + + // 中文注释:表格数据请求 + const tableRequest = async (params: Record) => { + try { + const { current = 1, pageSize = 10, siteName, type } = params; + const resp = await request('/site/list', { + method: 'GET', + params: { + current, + pageSize, + keyword: siteName || undefined, + type: type || undefined, + }, + }); + const { success, data, message: errMsg } = resp as any; + if (!success) throw new Error(errMsg || '获取失败'); + return { + data: (data?.items ?? []) as SiteItem[], + total: data?.total ?? 0, + success: true, + }; + } catch (e: any) { + message.error(e?.message || '获取失败'); + return { data: [], total: 0, success: false }; + } + }; + + // 中文注释:提交创建/更新逻辑;编辑时未填写密钥则不提交(保持原值) + const handleSubmit = async (values: SiteFormValues) => { + try { + if (editing) { + const payload: Record = { + // 中文注释:仅提交存在的字段,避免覆盖为 null/空 + ...(values.siteName ? { siteName: values.siteName } : {}), + ...(values.apiUrl ? { apiUrl: values.apiUrl } : {}), + ...(values.type ? { type: values.type } : {}), + ...(typeof values.isDisabled === 'boolean' ? { isDisabled: values.isDisabled } : {}), + ...(values.skuPrefix ? { skuPrefix: values.skuPrefix } : {}), + }; + // 中文注释:仅当输入了新密钥时才提交,未输入则保持原本值 + if (values.consumerKey && values.consumerKey.trim()) { + payload.consumerKey = values.consumerKey.trim(); + } + if (values.consumerSecret && values.consumerSecret.trim()) { + payload.consumerSecret = values.consumerSecret.trim(); + } + await request(`/site/update/${editing.id}`, { method: 'PUT', data: payload }); + } else { + // 中文注释:新增站点时要求填写 consumerKey 和 consumerSecret + if (!values.consumerKey || !values.consumerSecret) { + throw new Error('Consumer Key and Secret are required'); + } + await request('/site/create', { + method: 'POST', + data: { + siteName: values.siteName, + apiUrl: values.apiUrl, + type: values.type || 'woocommerce', + consumerKey: values.consumerKey, + consumerSecret: values.consumerSecret, + skuPrefix: values.skuPrefix, + }, + }); + } + message.success('提交成功'); + setOpen(false); + setEditing(null); + actionRef.current?.reload(); + return true; + } catch (e: any) { + message.error(e?.message || '提交失败'); + return false; + } + }; + + return ( + <> + + actionRef={actionRef} + rowKey="id" + columns={columns} + request={tableRequest} + toolBarRender={() => [ + , + ]} + /> + + + title={editing ? '编辑站点' : '新增站点'} + open={open} + onOpenChange={setOpen} + formRef={formRef} + onFinish={handleSubmit} + > + {/* 中文注释:站点名称,必填 */} + + {/* 中文注释:API 地址,可选 */} + + {/* 中文注释:平台类型选择 */} + + {/* 中文注释:是否禁用 */} + + + {/* 中文注释:WooCommerce REST consumer key;新增必填,编辑不填则保持原值 */} + + {/* 中文注释:WooCommerce REST consumer secret;新增必填,编辑不填则保持原值 */} + + + + ); +}; + +export default SiteList; \ No newline at end of file