diff --git a/.umirc.ts b/.umirc.ts index 59f691d..d73bd6b 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -1,10 +1,10 @@ import { defineConfig } from '@umijs/max'; +import { codeInspectorPlugin } from 'code-inspector-plugin'; const isDev = process.env.NODE_ENV === 'development'; const UMI_APP_API_URL = isDev ? 'http://localhost:7001' : 'https://api.yoone.ca'; -import { codeInspectorPlugin } from 'code-inspector-plugin'; export default defineConfig({ hash: true, @@ -23,7 +23,7 @@ export default defineConfig({ config.plugin('code-inspector-plugin').use( codeInspectorPlugin({ bundler: 'webpack', - }) + }), ); }, routes: [ @@ -93,9 +93,9 @@ export default defineConfig({ component: './Product/List', }, { - name: '商品分类', - path: '/product/category', - component: './Product/Category', + name: '品牌', + path: '/product/brand', + component: './Product/Brand', }, { name: '强度', diff --git a/README.md b/README.md index 7c7ac02..0164b5e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ # WEB - diff --git a/src/access.ts b/src/access.ts index cda1792..965ae92 100644 --- a/src/access.ts +++ b/src/access.ts @@ -11,7 +11,7 @@ export default (initialState: any) => { const canSeeStatistics = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('statistics') ?? false); const canSeeSite = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('site') ?? false); const canSeeDict = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('dict') ?? false); - + const canSeeTemplate = (isSuper || isAdmin) || (initialState?.user?.permissions?.includes('template') ?? false); return { canSeeOrganiza, canSeeProduct, @@ -22,5 +22,6 @@ export default (initialState: any) => { canSeeStatistics, canSeeSite, canSeeDict, + canSeeTemplate, }; }; diff --git a/src/components/SyncForm.tsx b/src/components/SyncForm.tsx index edcf10f..997ecc8 100644 --- a/src/components/SyncForm.tsx +++ b/src/components/SyncForm.tsx @@ -1,4 +1,3 @@ - import { sitecontrollerAll } from '@/servers/api/site'; import { SyncOutlined } from '@ant-design/icons'; import { @@ -7,13 +6,13 @@ import { ProForm, ProFormSelect, } from '@ant-design/pro-components'; -import { App, Button } from 'antd'; +import { Button } from 'antd'; import React from 'react'; // 定义SyncForm组件的props类型 interface SyncFormProps { tableRef: React.MutableRefObject; - onFinish: (values:any) => Promise; + onFinish: (values: any) => Promise; } /** diff --git a/src/pages/Customer/List/index.tsx b/src/pages/Customer/List/index.tsx index e9c8b03..d0ca5e0 100644 --- a/src/pages/Customer/List/index.tsx +++ b/src/pages/Customer/List/index.tsx @@ -39,9 +39,9 @@ const ListPage: React.FC = () => { { title: '客户编号', dataIndex: 'customerId', - render: (_, record) => { - if(!record.customerId) return '-'; - return String(record.customerId).padStart(6,0) + render: (_, record) => { + if (!record.customerId) return '-'; + return String(record.customerId).padStart(6, 0); }, sorter: true, }, @@ -95,31 +95,37 @@ const ListPage: React.FC = () => { title: '等级', hideInSearch: true, render: (_, record) => { - if(!record.yoone_orders || !record.yoone_total) return '-' - if(Number(record.yoone_orders) === 1 && Number(record.yoone_total) > 0 ) return 'B' - return '-' - } + if (!record.yoone_orders || !record.yoone_total) return '-'; + if (Number(record.yoone_orders) === 1 && Number(record.yoone_total) > 0) + return 'B'; + return '-'; + }, }, { title: '评星', dataIndex: 'rate', width: 200, render: (_, record) => { - return { - try{ - const { success, message: msg } = await customercontrollerSetrate({ - id: record.customerId, - rate: val - }); - if (success) { - message.success(msg); - actionRef.current?.reload(); - } - }catch(e){ - message.error(e.message); - - } - }} value={record.rate} /> + return ( + { + try { + const { success, message: msg } = + await customercontrollerSetrate({ + id: record.customerId, + rate: val, + }); + if (success) { + message.success(msg); + actionRef.current?.reload(); + } + } catch (e) { + message.error(e.message); + } + }} + value={record.rate} + /> + ); }, }, { diff --git a/src/pages/Dict/List/index.tsx b/src/pages/Dict/List/index.tsx index dbe6f4f..e931673 100644 --- a/src/pages/Dict/List/index.tsx +++ b/src/pages/Dict/List/index.tsx @@ -1,8 +1,18 @@ -import { PageContainer } from '@ant-design/pro-components'; -import { Input, Button, Table, Layout, Space, Modal, message, Form, Upload } from 'antd'; -import React, { useState, useEffect } from 'react'; -import { request } from '@umijs/max'; import { UploadOutlined } from '@ant-design/icons'; +import { PageContainer } from '@ant-design/pro-components'; +import { request } from '@umijs/max'; +import { + Button, + Form, + Input, + Layout, + Modal, + Space, + Table, + Upload, + message, +} from 'antd'; +import React, { useEffect, useState } from 'react'; const { Sider, Content } = Layout; @@ -26,13 +36,17 @@ const DictPage: React.FC = () => { // 控制字典项模态框的显示 const [isDictItemModalVisible, setIsDictItemModalVisible] = useState(false); const [editingDictItem, setEditingDictItem] = useState(null); - const [dictItemForm, setDictItemForm] = useState({ name: '', title: '', value: '' }); + const [dictItemForm, setDictItemForm] = useState({ + name: '', + title: '', + value: '', + }); // 获取字典列表 const fetchDicts = async (title?: string) => { setLoadingDicts(true); try { - const res = await request('/dict/list', { params: { title } }); + const res = await request('/dict/list', { params: { title } }); if (res) { setDicts(res); } @@ -46,7 +60,7 @@ const DictPage: React.FC = () => { const fetchDictItems = async (dictId?: number) => { setLoadingDictItems(true); try { - const res = await request('/dict/items', { params: { dictId } }); + const res = await request('/dict/items', { params: { dictId } }); if (res) { setDictItems(res); } @@ -80,13 +94,13 @@ const DictPage: React.FC = () => { } try { if (editingDict) { - await request(`/dict/${editingDict.id}`, { + await request(`/dict/${editingDict.id}`, { method: 'PUT', data: { name: newDictName, title: newDictTitle }, }); message.success('更新成功'); } else { - await request('/dict', { + await request('/dict', { method: 'POST', data: { name: newDictName, title: newDictTitle }, }); @@ -132,14 +146,14 @@ const DictPage: React.FC = () => { try { if (editingDictItem) { // 编辑 - await request(`/dict/item/${editingDictItem.id}`, { + await request(`/dict/item/${editingDictItem.id}`, { method: 'PUT', data: dictItemForm, }); message.success('更新成功'); } else { // 添加 - await request('/dict/item', { + await request('/dict/item', { method: 'POST', data: { ...dictItemForm, dictId: selectedDict.id }, }); @@ -155,7 +169,7 @@ const DictPage: React.FC = () => { // 处理删除字典项 const handleDeleteDictItem = async (itemId: number) => { try { - await request(`/dict/item/${itemId}`, { method: 'DELETE' }); + await request(`/dict/item/${itemId}`, { method: 'DELETE' }); message.success('删除成功'); fetchDictItems(selectedDict.id); } catch (error) { @@ -166,7 +180,7 @@ const DictPage: React.FC = () => { // 处理删除字典 const handleDeleteDict = async (dictId: number) => { try { - await request(`/dict/${dictId}`, { method: 'DELETE' }); + await request(`/dict/${dictId}`, { method: 'DELETE' }); message.success('删除成功'); fetchDicts(); // 重新获取字典列表 // 如果删除的是当前选中的字典,则清空右侧列表 @@ -181,13 +195,12 @@ const DictPage: React.FC = () => { // 左侧字典列表的列定义 const dictColumns = [ - { title: '名称', dataIndex: 'name', key: 'name', }, - { + { title: '标题', dataIndex: 'title', key: 'title', @@ -197,10 +210,23 @@ const DictPage: React.FC = () => { key: 'action', render: (_: any, record: any) => ( - - @@ -225,8 +251,16 @@ const DictPage: React.FC = () => { key: 'action', render: (_: any, record: any) => ( - - + + ), }, @@ -235,18 +269,35 @@ const DictPage: React.FC = () => { return ( - + - setSearchText(e.target.value)} enterButton allowClear /> - { + onChange={(info) => { if (info.file.status === 'done') { message.success(`${info.file.name} 文件上传成功`); fetchDicts(); @@ -257,14 +308,16 @@ const DictPage: React.FC = () => { > - + ({ + onRow={(record) => ({ onClick: () => { // 如果点击的是当前已选中的行,则取消选择 if (selectedDict?.id === record.id) { @@ -274,24 +327,30 @@ const DictPage: React.FC = () => { } }, })} - rowClassName={record => (selectedDict?.id === record.id ? 'ant-table-row-selected' : '')} + rowClassName={(record) => + selectedDict?.id === record.id ? 'ant-table-row-selected' : '' + } pagination={false} /> - { + onChange={(info) => { if (info.file.status === 'done') { message.success(`${info.file.name} 文件上传成功`); fetchDictItems(selectedDict.id); @@ -300,11 +359,23 @@ const DictPage: React.FC = () => { } }} > - + - + -
+
@@ -317,13 +388,31 @@ const DictPage: React.FC = () => { > - setDictItemForm({ ...dictItemForm, name: e.target.value })} /> + + setDictItemForm({ ...dictItemForm, name: e.target.value }) + } + /> - setDictItemForm({ ...dictItemForm, title: e.target.value })} /> + + setDictItemForm({ ...dictItemForm, title: e.target.value }) + } + /> - setDictItemForm({ ...dictItemForm, value: e.target.value })} /> + + setDictItemForm({ ...dictItemForm, value: e.target.value }) + } + /> @@ -336,10 +425,18 @@ const DictPage: React.FC = () => { > - setNewDictName(e.target.value)} /> + setNewDictName(e.target.value)} + /> - setNewDictTitle(e.target.value)} /> + setNewDictTitle(e.target.value)} + /> diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx index 14f3722..e557530 100644 --- a/src/pages/Login/index.tsx +++ b/src/pages/Login/index.tsx @@ -1,3 +1,4 @@ +import { useDeviceFingerprint } from '@/hooks/useDeviceFingerprint'; import { usercontrollerGetuser, usercontrollerLogin } from '@/servers/api/user'; import { LockOutlined, UserOutlined } from '@ant-design/icons'; import { @@ -7,7 +8,6 @@ import { } from '@ant-design/pro-components'; import { history, useModel } from '@umijs/max'; import { App, theme } from 'antd'; -import {useDeviceFingerprint} from '@/hooks/useDeviceFingerprint'; import { useState } from 'react'; const Page = () => { @@ -15,28 +15,32 @@ const Page = () => { const { token } = theme.useToken(); const { message } = App.useApp(); const deviceId = useDeviceFingerprint(); - const [ isAuth, setIsAuth ] = useState(false) + const [isAuth, setIsAuth] = useState(false); - console.log(deviceId) ; + console.log(deviceId); const onFinish = async (values: { username: string; password: string }) => { try { - const { data, success, code, message: msg } = await usercontrollerLogin({...values, deviceId}); + const { + data, + success, + code, + message: msg, + } = await usercontrollerLogin({ ...values, deviceId }); if (success) { message.success('登录成功'); localStorage.setItem('token', data?.token as string); const { data: user } = await usercontrollerGetuser(); setInitialState({ user }); history.push('/'); - return + return; } - if(code === 10001){ - message.info("验证码已发送至管理邮箱") + if (code === 10001) { + message.info('验证码已发送至管理邮箱'); setIsAuth(true); return; } message.error(msg); - } catch { message.error('登录失败'); } @@ -100,16 +104,17 @@ const Page = () => { }, ]} /> - { - isAuth? + {isAuth ? ( :<> - } + /> + ) : ( + <> + )} {/*
{ const actionRef = useRef(); @@ -69,7 +71,9 @@ const ListPage: React.FC = () => { { try { - await navigator.clipboard.writeText(record.return_tracking_number); + await navigator.clipboard.writeText( + record.return_tracking_number, + ); message.success('复制成功!'); } catch (err) { message.error('复制失败!'); @@ -106,7 +110,9 @@ const ListPage: React.FC = () => { disabled={isLoading} onClick={async () => { setIsLoading(true); - const { data } = await logisticscontrollerGetshipmentlabel({shipmentId:record.id}); + const { data } = await logisticscontrollerGetshipmentlabel({ + shipmentId: record.id, + }); const content = data.content; printPDF([content]); setIsLoading(false); @@ -120,7 +126,9 @@ const ListPage: React.FC = () => { disabled={isLoading} onClick={async () => { setIsLoading(true); - const res = await logisticscontrollerUpdateshipmentstate({shipmentId:record.id}); + const res = await logisticscontrollerUpdateshipmentstate({ + shipmentId: record.id, + }); console.log('res', res); setIsLoading(false); @@ -137,7 +145,7 @@ const ListPage: React.FC = () => { try { setIsLoading(true); const { success, message: errMsg } = - await logisticscontrollerDeleteshipment({id:record.id}); + await logisticscontrollerDeleteshipment({ id: record.id }); if (!success) { throw new Error(errMsg); } diff --git a/src/pages/Logistics/Services/index.tsx b/src/pages/Logistics/Services/index.tsx index f88e995..db49b12 100644 --- a/src/pages/Logistics/Services/index.tsx +++ b/src/pages/Logistics/Services/index.tsx @@ -1,6 +1,5 @@ import { logisticscontrollerGetservicelist, - logisticscontrollerSyncservices, logisticscontrollerToggleactive, } from '@/servers/api/logistics'; import { @@ -10,7 +9,7 @@ import { ProFormSwitch, ProTable, } from '@ant-design/pro-components'; -import { App, Button } from 'antd'; +import { App } from 'antd'; import { useRef } from 'react'; const ListPage: React.FC = () => { diff --git a/src/pages/Order/Items/index.tsx b/src/pages/Order/Items/index.tsx index 945ddbf..0929852 100644 --- a/src/pages/Order/Items/index.tsx +++ b/src/pages/Order/Items/index.tsx @@ -1,11 +1,15 @@ -import React, { useRef } from 'react'; -import { PageContainer } from '@ant-design/pro-layout'; -import type { ProColumns, ActionType, ProTableProps } from '@ant-design/pro-components'; -import { ProTable } from '@ant-design/pro-components'; -import { App } from 'antd'; -import dayjs from 'dayjs'; import { ordercontrollerGetordersales } from '@/servers/api/order'; import { sitecontrollerAll } from '@/servers/api/site'; +import type { + ActionType, + ProColumns, + ProTableProps, +} from '@ant-design/pro-components'; +import { ProTable } from '@ant-design/pro-components'; +import { PageContainer } from '@ant-design/pro-layout'; +import { App } from 'antd'; +import dayjs from 'dayjs'; +import React, { useRef } from 'react'; // 列表行数据结构(订单商品聚合) interface OrderItemAggRow { @@ -87,7 +91,10 @@ const OrderItemsPage: React.FC = () => { request: async () => { // 拉取站点列表(后台 /site/all) const { data = [] } = await sitecontrollerAll(); - return (data || []).map((item: any) => ({ label: item.siteName, value: item.id })); + return (data || []).map((item: any) => ({ + label: item.siteName, + value: item.id, + })); }, }, { @@ -104,7 +111,9 @@ const OrderItemsPage: React.FC = () => { ]; // 表格请求方法:调用 /order/getOrderSales 接口并设置 isSource=true 获取订单项聚合 - const request: ProTableProps['request'] = async (params:any) => { + const request: ProTableProps['request'] = async ( + params: any, + ) => { try { const { current = 1, pageSize = 10, siteId, name } = params as any; const [startDate, endDate] = (params as any).dateRange || []; @@ -115,7 +124,9 @@ const OrderItemsPage: React.FC = () => { siteId, name, isSource: true as any, - startDate: startDate ? (dayjs(startDate).toISOString() as any) : undefined, + startDate: startDate + ? (dayjs(startDate).toISOString() as any) + : undefined, endDate: endDate ? (dayjs(endDate).toISOString() as any) : undefined, } as any); const { success, data, message: errMsg } = resp as any; @@ -132,10 +143,12 @@ const OrderItemsPage: React.FC = () => { }; return ( - + actionRef={actionRef} - rowKey={(r) => `${r.externalProductId}-${r.externalVariationId}-${r.name}`} + rowKey={(r) => + `${r.externalProductId}-${r.externalVariationId}-${r.name}` + } columns={columns} request={request} pagination={{ showSizeChanger: true }} @@ -146,4 +159,4 @@ const OrderItemsPage: React.FC = () => { ); }; -export default OrderItemsPage; \ No newline at end of file +export default OrderItemsPage; diff --git a/src/pages/Order/List/index.tsx b/src/pages/Order/List/index.tsx index b183d55..da46392 100644 --- a/src/pages/Order/List/index.tsx +++ b/src/pages/Order/List/index.tsx @@ -2,16 +2,13 @@ import styles from '../../../style/order-list.css'; import InternationalPhoneInput from '@/components/InternationalPhoneInput'; import SyncForm from '@/components/SyncForm'; -import { HistoryOrder } from '@/pages/Statistics/Order'; import { ORDER_STATUS_ENUM } from '@/constants'; +import { HistoryOrder } from '@/pages/Statistics/Order'; import { logisticscontrollerCreateshipment, - logisticscontrollerGetshipmentfee, logisticscontrollerDelshipment, - logisticscontrollerGetpaymentmethods, - logisticscontrollerGetratelist, + logisticscontrollerGetshipmentfee, logisticscontrollerGetshippingaddresslist, - // logisticscontrollerGetshipmentlabel, } from '@/servers/api/logistics'; import { ordercontrollerCancelorder, @@ -23,14 +20,13 @@ import { ordercontrollerGetorderdetail, ordercontrollerGetorders, ordercontrollerRefundorder, - ordercontrollerSyncorder, ordercontrollerSyncorderbyid, ordercontrollerUpdateorderitems, } from '@/servers/api/order'; import { productcontrollerSearchproducts } from '@/servers/api/product'; -import { wpproductcontrollerSearchproducts } from '@/servers/api/wpProduct'; import { sitecontrollerAll } from '@/servers/api/site'; import { stockcontrollerGetallstockpoints } from '@/servers/api/stock'; +import { wpproductcontrollerSearchproducts } from '@/servers/api/wpProduct'; import { formatShipmentState, formatSource } from '@/utils/format'; import { CodeSandboxOutlined, @@ -38,12 +34,10 @@ import { DeleteFilled, DownOutlined, FileDoneOutlined, - SyncOutlined, TagsOutlined, } from '@ant-design/icons'; import { ActionType, - DrawerForm, ModalForm, PageContainer, ProColumns, @@ -66,7 +60,6 @@ import { Button, Card, Col, - Descriptions, Divider, Drawer, Dropdown, @@ -80,10 +73,8 @@ import { TabsProps, Tag, } from 'antd'; -import Item from 'antd/es/list/Item'; -import RelatedOrders from '../../Subscription/Orders/RelatedOrders'; import React, { useMemo, useRef, useState } from 'react'; -import { printPDF } from '@/utils/util'; +import RelatedOrders from '../../Subscription/Orders/RelatedOrders'; const ListPage: React.FC = () => { const actionRef = useRef(); @@ -130,14 +121,13 @@ const ListPage: React.FC = () => { label: '已申请退款', }, { - key: 'refund_approved', - label: "已退款", + label: '已退款', // label: '退款申请已通过', }, { key: 'refund_cancelled', - label: "已完成" + label: '已完成', // label: '已取消退款', }, // { @@ -174,15 +164,22 @@ const ListPage: React.FC = () => { hideInTable: true, valueType: 'dateRange', }, - + { title: '订阅', dataIndex: 'isSubscription', hideInSearch: true, render: (_, record) => { - const related = Array.isArray((record as any)?.related) ? (record as any).related : []; - const isSub = related.some((it: any) => it?.externalSubscriptionId || it?.billing_period || it?.line_items); - return {isSub ? '是' : '否'}; + const related = Array.isArray((record as any)?.related) + ? (record as any).related + : []; + const isSub = related.some( + (it: any) => + it?.externalSubscriptionId || it?.billing_period || it?.line_items, + ); + return ( + {isSub ? '是' : '否'} + ); }, }, { @@ -236,7 +233,7 @@ const ListPage: React.FC = () => { dataIndex: 'billing_phone', render: (_, record) => record.shipping?.phone || record.billing?.phone, }, - { + { title: '换货次数', dataIndex: 'exchange_frequency', hideInSearch: true, @@ -307,7 +304,11 @@ const ListPage: React.FC = () => { record.orderStatus, ) ? ( <> - + ) : ( @@ -364,11 +365,12 @@ const ListPage: React.FC = () => { }, { key: 'history', - label: + label: ( , + /> + ), }, { key: 'note', @@ -445,23 +447,28 @@ const ListPage: React.FC = () => { actionRef={actionRef} rowKey="id" rowClassName={(record) => { - return record.id === activeLine ? styles['selected-line-order-protable'] : ''; + return record.id === activeLine + ? styles['selected-line-order-protable'] + : ''; }} toolBarRender={() => [ , - { - try { - const { success, message: errMsg } = - await ordercontrollerSyncorderbyid(values); - if (!success) { - throw new Error(errMsg); + { + try { + const { success, message: errMsg } = + await ordercontrollerSyncorderbyid(values); + if (!success) { + throw new Error(errMsg); + } + message.success('同步成功'); + actionRef.current?.reload(); + } catch (error: any) { + message.error(error?.message || '同步失败'); } - message.success('同步成功'); - actionRef.current?.reload(); - } catch (error: any) { - message.error(error?.message || '同步失败'); - } - }} tableRef={actionRef} />, + }} + tableRef={actionRef} + />, ]} request={async ({ date, ...param }: any) => { if (param.status === 'all') { @@ -494,7 +501,7 @@ const Detail: React.FC<{ tableRef: React.MutableRefObject; orderId: number; record: API.Order; - setActiveLine: Function + setActiveLine: Function; }> = ({ tableRef, orderId, record, setActiveLine }) => { const [visiable, setVisiable] = useState(false); const { message } = App.useApp(); @@ -526,10 +533,14 @@ const Detail: React.FC<{ return ( <> - @@ -546,33 +557,33 @@ const Detail: React.FC<{ ) ? [] : [ - , - , - ]), + }} + > + 同步订单 + , + ]), // ...(['processing', 'pending_reshipment'].includes(record.orderStatus) // ? [ // , @@ -591,152 +602,152 @@ const Detail: React.FC<{ 'pending_refund', ].includes(record.orderStatus) ? [ - , - { - try { - if (!record.id) { - message.error('订单ID不存在'); - return; + , + { + try { + if (!record.id) { + message.error('订单ID不存在'); + return; + } + const { success, message: errMsg } = + await ordercontrollerChangestatus( + { + id: record.id, + }, + { + status: 'after_sale_pending', + }, + ); + if (!success) { + throw new Error(errMsg); + } + tableRef.current?.reload(); + } catch (error: any) { + message.error(error.message); } - const { success, message: errMsg } = - await ordercontrollerChangestatus( - { - id: record.id, - }, - { - status: 'after_sale_pending', - }, - ); - if (!success) { - throw new Error(errMsg); - } - tableRef.current?.reload(); - } catch (error: any) { - message.error(error.message); - } - }} - > - - , - ] + }} + > + + , + ] : []), ...(record.orderStatus === 'after_sale_pending' ? [ - , - { - try { - if (!record.id) { - message.error('订单ID不存在'); - return; - } - const { success, message: errMsg } = - await ordercontrollerCancelorder({ - id: record.id, - }); - if (!success) { - throw new Error(errMsg); - } - tableRef.current?.reload(); - } catch (error: any) { - message.error(error.message); - } - }} - > - - , - , - { - try { - if (!record.id) { - message.error('订单ID不存在'); - return; - } - const { success, message: errMsg } = - await ordercontrollerRefundorder({ - id: record.id, - }); - if (!success) { - throw new Error(errMsg); - } - tableRef.current?.reload(); - } catch (error: any) { - message.error(error.message); - } - }} - > - - , - , - { - try { - if (!record.id) { - message.error('订单ID不存在'); - return; - } - const { success, message: errMsg } = - await ordercontrollerCompletedorder({ - id: record.id, - }); - if (!success) { - throw new Error(errMsg); - } - tableRef.current?.reload(); - } catch (error: any) { - message.error(error.message); - } - }} - > - - , - , - { - try { - const { success, message: errMsg } = - await ordercontrollerChangestatus( - { + , + { + try { + if (!record.id) { + message.error('订单ID不存在'); + return; + } + const { success, message: errMsg } = + await ordercontrollerCancelorder({ id: record.id, - }, - { - status: 'pending_reshipment', - }, - ); - if (!success) { - throw new Error(errMsg); + }); + if (!success) { + throw new Error(errMsg); + } + tableRef.current?.reload(); + } catch (error: any) { + message.error(error.message); } - tableRef.current?.reload(); - } catch (error: any) { - message.error(error.message); - } - }} - > - - , - ] + }} + > + + , + , + { + try { + if (!record.id) { + message.error('订单ID不存在'); + return; + } + const { success, message: errMsg } = + await ordercontrollerRefundorder({ + id: record.id, + }); + if (!success) { + throw new Error(errMsg); + } + tableRef.current?.reload(); + } catch (error: any) { + message.error(error.message); + } + }} + > + + , + , + { + try { + if (!record.id) { + message.error('订单ID不存在'); + return; + } + const { success, message: errMsg } = + await ordercontrollerCompletedorder({ + id: record.id, + }); + if (!success) { + throw new Error(errMsg); + } + tableRef.current?.reload(); + } catch (error: any) { + message.error(error.message); + } + }} + > + + , + , + { + try { + const { success, message: errMsg } = + await ordercontrollerChangestatus( + { + id: record.id, + }, + { + status: 'pending_reshipment', + }, + ); + if (!success) { + throw new Error(errMsg); + } + tableRef.current?.reload(); + } catch (error: any) { + message.error(error.message); + } + }} + > + + , + ] : []), ]} > @@ -770,7 +781,9 @@ const Detail: React.FC<{ /> - { return (
@@ -779,7 +792,8 @@ const Detail: React.FC<{
); - }} /> + }} + /> @@ -891,7 +905,7 @@ const Detail: React.FC<{
    {record?.items?.map((item: any) => (
  • - {item.name}:{item.quantity} + {item.name}:{item.quantity}
  • ))}
@@ -899,13 +913,13 @@ const Detail: React.FC<{ }} /> {/* 显示 related order */} - { - return ; - }} -/> + { + return ; + }} + /> {/* 订单内容 */} { - return ( - - ) + return ; }} /> { - try { - const { success, message: errMsg } = - await logisticscontrollerDelshipment({ - id: v.id, - }); - if (!success) { - throw new Error(errMsg); + { + try { + const { success, message: errMsg } = + await logisticscontrollerDelshipment({ + id: v.id, + }); + if (!success) { + throw new Error(errMsg); + } + tableRef.current?.reload(); + initRequest(); + } catch (error: any) { + message.error(error.message); } - tableRef.current?.reload(); - initRequest(); - } catch (error: any) { - message.error(error.message); - } - }} - > - - 取消运单 - , - ] + }} + > + + 取消运单 + , + ] : [] } > @@ -1183,7 +1192,8 @@ const Shipping: React.FC<{ }, }} trigger={ - @@ -1961,7 +1996,6 @@ const SalesChange: React.FC<{ }> = ({ id, detailRef }) => { const formRef = useRef(); - return ( { - let idx = acc.findIndex((v: any) => v.productId === cur.productId); - if (idx === -1) { - acc.push(cur); - } else { - acc[idx].quantity += cur.quantity; - } - return acc; - }, + data.sales = data.sales?.reduce( + (acc: API.OrderSale[], cur: API.OrderSale) => { + let idx = acc.findIndex((v: any) => v.productId === cur.productId); + if (idx === -1) { + acc.push(cur); + } else { + acc[idx].quantity += cur.quantity; + } + return acc; + }, [], ); - // setOptions( // data.sales?.map((item) => ({ // label: item.name, // value: item.sku, // })) || [], // ); - return { ...data}; + return { ...data }; }} onFinish={async (formData: any) => { const { sales } = formData; - const res = await ordercontrollerUpdateorderitems({ orderId: id }, sales); + const res = await ordercontrollerUpdateorderitems( + { orderId: id }, + sales, + ); if (!res.success) { message.error(`更新货物信息失败: ${res.message}`); return false; } - message.success('更新成功') + message.success('更新成功'); detailRef?.current?.reload(); return true; }} > - + - { try { const { data } = await wpproductcontrollerSearchproducts({ name: keyWords, }); - return ( - data?.map((item) => { - return { - label: `${item.name}`, - value: item?.sku, - }; - }) - ); + return data?.map((item) => { + return { + label: `${item.name}`, + value: item?.sku, + }; + }); } catch (error: any) { return []; } @@ -2065,17 +2096,11 @@ const SalesChange: React.FC<{ precision: 0, }} /> - - + - - { @@ -2083,14 +2108,12 @@ const SalesChange: React.FC<{ const { data } = await productcontrollerSearchproducts({ name: keyWords, }); - return ( - data?.map((item) => { - return { - label: `${item.name} - ${item.nameCn}`, - value: item?.sku, - }; - }) - ); + return data?.map((item) => { + return { + label: `${item.name} - ${item.nameCn}`, + value: item?.sku, + }; + }); } catch (error: any) { return []; } @@ -2120,7 +2143,7 @@ const SalesChange: React.FC<{ ); -} +}; const CreateOrder: React.FC<{ tableRef?: React.MutableRefObject; diff --git a/src/pages/Product/Category/index.tsx b/src/pages/Product/Brand/index.tsx similarity index 98% rename from src/pages/Product/Category/index.tsx rename to src/pages/Product/Brand/index.tsx index 59c987c..387643d 100644 --- a/src/pages/Product/Category/index.tsx +++ b/src/pages/Product/Brand/index.tsx @@ -86,15 +86,13 @@ const List: React.FC = () => { return ( - + headerTitle="查询表格" actionRef={actionRef} rowKey="id" toolBarRender={() => []} request={async (params) => { - const { data, success } = await productcontrollerGetbrands( - params, - ); + const { data, success } = await productcontrollerGetbrands(params); return { total: data?.total || 0, data: data?.items || [], diff --git a/src/pages/Product/List/index.tsx b/src/pages/Product/List/index.tsx index 47abece..7026ec5 100644 --- a/src/pages/Product/List/index.tsx +++ b/src/pages/Product/List/index.tsx @@ -26,24 +26,33 @@ const NameCn: React.FC<{ id: number; value: string | undefined; tableRef: React.MutableRefObject; -}> = ({value,tableRef, id}) => { +}> = ({ value, tableRef, id }) => { const { message } = App.useApp(); const [editable, setEditable] = React.useState(false); - if (!editable) return
setEditable(true)}>{value||'-'}
; - return ) => { - if(!e.target.value) return setEditable(false) - const { success, message: errMsg } = - await productcontrollerUpdateproductnamecn({ - id, - nameCn: e.target.value, - }) - setEditable(false) - if (!success) { - return message.error(errMsg) - } - tableRef?.current?.reload() - }}} /> -} + if (!editable) + return
setEditable(true)}>{value || '-'}
; + return ( + ) => { + if (!e.target.value) return setEditable(false); + const { success, message: errMsg } = + await productcontrollerUpdateproductnamecn({ + id, + nameCn: e.target.value, + }); + setEditable(false); + if (!success) { + return message.error(errMsg); + } + tableRef?.current?.reload(); + }, + }} + /> + ); +}; const List: React.FC = () => { const actionRef = useRef(); // 状态:存储当前选中的行 @@ -58,10 +67,10 @@ const List: React.FC = () => { { title: '中文名', dataIndex: 'nameCn', - render: (_, record) => { + render: (_, record) => { return ( - ) + ); }, }, { @@ -149,7 +158,7 @@ const List: React.FC = () => { success, }; }} - columns={columns} + columns={columns} editable={{ type: 'single', onSave: async (key, record, originRow) => { @@ -215,7 +224,7 @@ const CreateForm: React.FC<{ width="lg" label="产品品牌" placeholder="请选择产品品牌" - request={async () => { + request={async () => { const { data = [] } = await productcontrollerGetbrandall(); return data.map((item: API.Brand) => ({ label: item.name, diff --git a/src/pages/Product/WpList/index.tsx b/src/pages/Product/WpList/index.tsx index 17f304e..2b32c80 100644 --- a/src/pages/Product/WpList/index.tsx +++ b/src/pages/Product/WpList/index.tsx @@ -262,9 +262,9 @@ const UpdateStatus: React.FC<{ { id: initialValues.id, }, - { + { status, - stock_status + stock_status, }, ); if (!success) { @@ -285,7 +285,7 @@ const UpdateStatus: React.FC<{ name="status" valueEnum={PRODUCT_STATUS_ENUM} /> - ; values: API.WpProductDTO; diff --git a/src/pages/Product/WpTool/index.tsx b/src/pages/Product/WpTool/index.tsx index a31f180..b401748 100644 --- a/src/pages/Product/WpTool/index.tsx +++ b/src/pages/Product/WpTool/index.tsx @@ -1,12 +1,11 @@ - -import React, { useState } from 'react'; +import { UploadOutlined } from '@ant-design/icons'; import { PageContainer, ProForm, ProFormSelect, } from '@ant-design/pro-components'; import { Button, Card, Col, Input, message, Row, Upload } from 'antd'; -import { UploadOutlined } from '@ant-design/icons'; +import React, { useState } from 'react'; import * as XLSX from 'xlsx'; // 定义配置接口 @@ -22,7 +21,10 @@ interface TagConfig { /** * @description 从产品名称中解析出品牌、口味、毫克含量和干燥度 */ -const parseName = (name: string, brands: string[]): [string, string, string, string] => { +const parseName = ( + name: string, + brands: string[], +): [string, string, string, string] => { const nm = name.trim(); const dryMatch = nm.match(/\(([^)]*)\)/); const dryness = dryMatch ? dryMatch[1].trim() : ''; @@ -75,11 +77,18 @@ const splitFlavorTokens = (flavorPart: string): string[] => { /** * @description 根据口味分类额外的标签(如 Fruit, Mint) */ -const classifyExtraTags = (flavorPart: string, fruitKeys: string[], mintKeys: string[]): string[] => { +const classifyExtraTags = ( + flavorPart: string, + fruitKeys: string[], + mintKeys: string[], +): string[] => { const tokens = splitFlavorTokens(flavorPart); const fLower = flavorPart.toLowerCase(); - const isFruit = fruitKeys.some(key => fLower.includes(key)) || tokens.some(t => fruitKeys.includes(t)); - const isMint = mintKeys.some(key => fLower.includes(key)) || tokens.includes('mint'); + const isFruit = + fruitKeys.some((key) => fLower.includes(key)) || + tokens.some((t) => fruitKeys.includes(t)); + const isMint = + mintKeys.some((key) => fLower.includes(key)) || tokens.includes('mint'); const extras: string[] = []; if (isFruit) extras.push('Fruit'); @@ -94,8 +103,12 @@ const computeTags = (name: string, sku: string, config: TagConfig): string => { const [brand, flavorPart, mg, dryness] = parseName(name, config.brands); const tokens = splitFlavorTokens(flavorPart); - const tokensForFlavor = tokens.filter(t => !config.nonFlavorTokens.includes(t)); - const flavorTag = tokensForFlavor.map(t => t.charAt(0).toUpperCase() + t.slice(1)).join(''); + const tokensForFlavor = tokens.filter( + (t) => !config.nonFlavorTokens.includes(t), + ); + const flavorTag = tokensForFlavor + .map((t) => t.charAt(0).toUpperCase() + t.slice(1)) + .join(''); let tags: string[] = []; if (brand) tags.push(brand); @@ -133,11 +146,13 @@ const computeTags = (name: string, sku: string, config: TagConfig): string => { } } - tags.push(...classifyExtraTags(flavorPart, config.fruitKeys, config.mintKeys)); + tags.push( + ...classifyExtraTags(flavorPart, config.fruitKeys, config.mintKeys), + ); // 去重并保留顺序 const seen = new Set(); - const finalTags = tags.filter(t => { + const finalTags = tags.filter((t) => { if (t && !seen.has(t)) { seen.add(t); return true; @@ -152,9 +167,22 @@ const computeTags = (name: string, sku: string, config: TagConfig): string => { const DEFAULT_CONFIG = { brands: ['YOONE', 'ZYN', 'ZEX', 'JUX', 'WHITE FOX'], fruitKeys: [ - 'apple', 'blueberry', 'citrus', 'mango', 'peach', 'grape', 'cherry', - 'strawberry', 'watermelon', 'orange', 'lemon', 'lemonade', - 'razz', 'pineapple', 'berry', 'fruit', + 'apple', + 'blueberry', + 'citrus', + 'mango', + 'peach', + 'grape', + 'cherry', + 'strawberry', + 'watermelon', + 'orange', + 'lemon', + 'lemonade', + 'razz', + 'pineapple', + 'berry', + 'fruit', ], mintKeys: ['mint', 'wintergreen', 'peppermint', 'spearmint', 'menthol'], nonFlavorTokens: ['slim', 'pouches', 'pouch', 'mini', 'dry'], @@ -242,7 +270,7 @@ const WpToolPage: React.FC = () => { try { // 获取表单中的最新配置 const config = await form.validateFields(); - + const { brands, fruitKeys, mintKeys, nonFlavorTokens } = config; // 确保品牌按长度降序排序 @@ -266,10 +294,15 @@ const WpToolPage: React.FC = () => { }); setProcessedData(dataWithTags); - message.success({ content: 'Tags 生成成功!现在可以下载了。', key: 'processing' }); - + message.success({ + content: 'Tags 生成成功!现在可以下载了。', + key: 'processing', + }); } catch (error) { - message.error({ content: '处理失败,请检查配置或文件。', key: 'processing' }); + message.error({ + content: '处理失败,请检查配置或文件。', + key: 'processing', + }); console.error('Processing Error:', error); } finally { setIsProcessing(false); @@ -368,7 +401,9 @@ const WpToolPage: React.FC = () => {
- +
{ try { await request(`/site/disable/${row.id}`, { @@ -159,7 +180,9 @@ const SiteList: React.FC = () => { ...(values.siteName ? { siteName: values.siteName } : {}), ...(values.apiUrl ? { apiUrl: values.apiUrl } : {}), ...(values.type ? { type: values.type } : {}), - ...(typeof values.isDisabled === 'boolean' ? { isDisabled: values.isDisabled } : {}), + ...(typeof values.isDisabled === 'boolean' + ? { isDisabled: values.isDisabled } + : {}), ...(values.skuPrefix ? { skuPrefix: values.skuPrefix } : {}), }; // 仅当输入了新密钥时才提交,未输入则保持原本值 @@ -169,7 +192,10 @@ const SiteList: React.FC = () => { if (values.consumerSecret && values.consumerSecret.trim()) { payload.consumerSecret = values.consumerSecret.trim(); } - await request(`/site/update/${editing.id}`, { method: 'PUT', data: payload }); + await request(`/site/update/${editing.id}`, { + method: 'PUT', + data: payload, + }); } else { // 新增站点时要求填写 consumerKey 和 consumerSecret if (!values.consumerKey || !values.consumerSecret) { @@ -218,7 +244,7 @@ const SiteList: React.FC = () => { , // 同步包括 orders subscriptions 等等 // @@ -233,9 +259,18 @@ const SiteList: React.FC = () => { onFinish={handleSubmit} > {/* 站点名称,必填 */} - + {/* API 地址,可选 */} - + {/* 平台类型选择 */} { /> {/* 是否禁用 */} - + {/* WooCommerce REST consumer key;新增必填,编辑不填则保持原值 */} - + {/* WooCommerce REST consumer secret;新增必填,编辑不填则保持原值 */} - + ); }; -export default SiteList; \ No newline at end of file +export default SiteList; diff --git a/src/pages/Statistics/OrderSource/index.tsx b/src/pages/Statistics/OrderSource/index.tsx index 8274646..1f280c4 100644 --- a/src/pages/Statistics/OrderSource/index.tsx +++ b/src/pages/Statistics/OrderSource/index.tsx @@ -1,257 +1,279 @@ -import React, { useEffect, useState, useMemo, useRef } from "react" +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { - ActionType, - PageContainer, ProColumns, ProTable, - } from '@ant-design/pro-components'; -import { statisticscontrollerGetordersorce, statisticscontrollerGetinativeusersbymonth } from "@/servers/api/statistics"; -import ReactECharts from 'echarts-for-react'; -import { App, Button, Space, Tag } from 'antd'; -import { HistoryOrder } from "../Order"; + statisticscontrollerGetinativeusersbymonth, + statisticscontrollerGetordersorce, +} from '@/servers/api/statistics'; +import { + ActionType, + PageContainer, + ProColumns, + ProTable, +} from '@ant-design/pro-components'; +import { Space, Tag } from 'antd'; import dayjs from 'dayjs'; +import ReactECharts from 'echarts-for-react'; +import { HistoryOrder } from '../Order'; const ListPage: React.FC = () => { + const [data, setData] = useState({}); - const [data, setData] = useState({}); + useEffect(() => { + statisticscontrollerGetordersorce().then(({ data, success }) => { + if (success) setData(data); + }); + }, []); - useEffect(() => { - statisticscontrollerGetordersorce().then(({ data, success }) => { - if(success) setData(data) - }); - }, []); - - const option = useMemo(() => { - if(!data.inactiveRes) return {} - const xAxisData = data?.inactiveRes?.map(v=> v.order_month)?.sort(_=>-1) - const arr = data?.res?.map(v=>v.first_order_month_group) - const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index).sort((a,b)=> a.localeCompare(b)) - const series = [ - { - name: '新客户', - type: 'bar', - data: data?.inactiveRes?.map(v=> v.new_user_count)?.sort(_=>-1), - label: { - show: true, - }, - emphasis: { - focus: 'series' - }, - xAxisIndex: 0, - yAxisIndex: 0, - }, - { - name: '老客户', - type: 'bar', - data: data?.inactiveRes?.map(v=> v.old_user_count)?.sort(_=>-1), - label: { - show: true, - }, - emphasis: { - focus: 'series' - }, - xAxisIndex: 0, - yAxisIndex: 0, - }, - ...uniqueArr?.map(v => { - data?.res?.filter(item => item.order_month === v) - return { - name: v, - type: "bar", - stack: "total", - label: { - "show": true, - formatter: function(params) { - if(!params.value) return '' - return Math.abs(params.value) - }, - color: '#fff' - }, - "data": xAxisData.map(month => { - return (data?.res?.find(item => item.order_month === month && item.first_order_month_group === v)?.order_count || 0) - }), - xAxisIndex: 0, - yAxisIndex: 0, - } - }), - { - name: '未复购客户', - type: 'bar', - data: data?.inactiveRes?.map(v=> -v.inactive_user_count)?.sort(_=>-1), - stack: "total", - label: { - show: true, - }, - emphasis: { - focus: 'series' - }, - xAxisIndex: 1, - yAxisIndex: 1, - barWidth: "60%", - - itemStyle: { - color: '#f44336' - } - }, - ] - return { - grid: [ - { top: '10%', height: '70%' }, - { bottom: '10%', height: '10%' } - ], - legend: { - selectedMode: false - }, - xAxis: [{ - type: 'category', - data: xAxisData, - gridIndex: 0, - },{ - type: 'category', - data: xAxisData, - gridIndex: 1, - }], - yAxis: [{ - type: 'value', - gridIndex: 0, - },{ - type: 'value', - gridIndex: 1, - }], - series, - } - }, [data]) - - const [tableData, setTableData] = useState([]) - const actionRef = useRef(); - const columns: ProColumns[] = [ + const option = useMemo(() => { + if (!data.inactiveRes) return {}; + const xAxisData = data?.inactiveRes + ?.map((v) => v.order_month) + ?.sort((_) => -1); + const arr = data?.res?.map((v) => v.first_order_month_group); + const uniqueArr = arr + .filter((item, index) => arr.indexOf(item) === index) + .sort((a, b) => a.localeCompare(b)); + const series = [ { - title: '用户名', - dataIndex: 'username', - hideInSearch: true, - render: (_, record) => { - if (record.billing.first_name || record.billing.last_name) - return record.billing.first_name + ' ' + record.billing.last_name; - return record.shipping.first_name + ' ' + record.shipping.last_name; + name: '新客户', + type: 'bar', + data: data?.inactiveRes?.map((v) => v.new_user_count)?.sort((_) => -1), + label: { + show: true, }, - }, - { - title: '邮箱', - dataIndex: 'email', - }, - { - title: '首单时间', - dataIndex: 'first_purchase_date', - valueType: 'dateMonth', - sorter: true, - render: (_, record) => - record.first_purchase_date - ? dayjs(record.first_purchase_date).format('YYYY-MM-DD HH:mm:ss') - : '-', - }, - { - title: '尾单时间', - hideInSearch: true, - dataIndex: 'last_purchase_date', - valueType: 'dateTime', - sorter: true, - }, - { - title: '订单数', - dataIndex: 'orders', - hideInSearch: true, - sorter: true, - }, - { - title: '金额', - dataIndex: 'total', - hideInSearch: true, - sorter: true, - }, - { - title: 'state', - dataIndex: 'state', - render: (_, record) => record?.billing.state || record?.shipping.state, - }, - { - title: 'city', - dataIndex: 'city', - hideInSearch: true, - render: (_, record) => record?.billing.city || record?.shipping.city, - }, - { - title: '标签', - dataIndex: 'tags', - render: (_, record) => { - return ( - - {(record.tags || []).map((tag) => { - return ( - { - const { success, message: msg } = - await customercontrollerDeltag({ - email: record.email, - tag, - }); - return false; - }} - > - {tag} - - ); - })} - - ); + emphasis: { + focus: 'series', }, + xAxisIndex: 0, + yAxisIndex: 0, }, { - title: '操作', - dataIndex: 'option', - valueType: 'option', - render: (_, record) => { - return ( - - ); + name: '老客户', + type: 'bar', + data: data?.inactiveRes?.map((v) => v.old_user_count)?.sort((_) => -1), + label: { + show: true, + }, + emphasis: { + focus: 'series', + }, + xAxisIndex: 0, + yAxisIndex: 0, + }, + ...uniqueArr?.map((v) => { + data?.res?.filter((item) => item.order_month === v); + return { + name: v, + type: 'bar', + stack: 'total', + label: { + show: true, + formatter: function (params) { + if (!params.value) return ''; + return Math.abs(params.value); + }, + color: '#fff', + }, + data: xAxisData.map((month) => { + return ( + data?.res?.find( + (item) => + item.order_month === month && + item.first_order_month_group === v, + )?.order_count || 0 + ); + }), + xAxisIndex: 0, + yAxisIndex: 0, + }; + }), + { + name: '未复购客户', + type: 'bar', + data: data?.inactiveRes + ?.map((v) => -v.inactive_user_count) + ?.sort((_) => -1), + stack: 'total', + label: { + show: true, + }, + emphasis: { + focus: 'series', + }, + xAxisIndex: 1, + yAxisIndex: 1, + barWidth: '60%', + + itemStyle: { + color: '#f44336', }, }, ]; - return( - - { - if (params.componentType === 'series') { - setTableData([]) - const {success, data} = await statisticscontrollerGetinativeusersbymonth({ - month: params.name - }) - if(success) setTableData(data) - } - }, - }} - /> - { - tableData?.length ? - - :<> - - } - - ) -} + return { + grid: [ + { top: '10%', height: '70%' }, + { bottom: '10%', height: '10%' }, + ], + legend: { + selectedMode: false, + }, + xAxis: [ + { + type: 'category', + data: xAxisData, + gridIndex: 0, + }, + { + type: 'category', + data: xAxisData, + gridIndex: 1, + }, + ], + yAxis: [ + { + type: 'value', + gridIndex: 0, + }, + { + type: 'value', + gridIndex: 1, + }, + ], + series, + }; + }, [data]); -export default ListPage; \ No newline at end of file + const [tableData, setTableData] = useState([]); + const actionRef = useRef(); + const columns: ProColumns[] = [ + { + title: '用户名', + dataIndex: 'username', + hideInSearch: true, + render: (_, record) => { + if (record.billing.first_name || record.billing.last_name) + return record.billing.first_name + ' ' + record.billing.last_name; + return record.shipping.first_name + ' ' + record.shipping.last_name; + }, + }, + { + title: '邮箱', + dataIndex: 'email', + }, + { + title: '首单时间', + dataIndex: 'first_purchase_date', + valueType: 'dateMonth', + sorter: true, + render: (_, record) => + record.first_purchase_date + ? dayjs(record.first_purchase_date).format('YYYY-MM-DD HH:mm:ss') + : '-', + }, + { + title: '尾单时间', + hideInSearch: true, + dataIndex: 'last_purchase_date', + valueType: 'dateTime', + sorter: true, + }, + { + title: '订单数', + dataIndex: 'orders', + hideInSearch: true, + sorter: true, + }, + { + title: '金额', + dataIndex: 'total', + hideInSearch: true, + sorter: true, + }, + { + title: 'state', + dataIndex: 'state', + render: (_, record) => record?.billing.state || record?.shipping.state, + }, + { + title: 'city', + dataIndex: 'city', + hideInSearch: true, + render: (_, record) => record?.billing.city || record?.shipping.city, + }, + { + title: '标签', + dataIndex: 'tags', + render: (_, record) => { + return ( + + {(record.tags || []).map((tag) => { + return ( + { + const { success, message: msg } = + await customercontrollerDeltag({ + email: record.email, + tag, + }); + return false; + }} + > + {tag} + + ); + })} + + ); + }, + }, + { + title: '操作', + dataIndex: 'option', + valueType: 'option', + render: (_, record) => { + return ( + + ); + }, + }, + ]; + return ( + + { + if (params.componentType === 'series') { + setTableData([]); + const { success, data } = + await statisticscontrollerGetinativeusersbymonth({ + month: params.name, + }); + if (success) setTableData(data); + } + }, + }} + /> + {tableData?.length ? ( + + ) : ( + <> + )} + + ); +}; + +export default ListPage; diff --git a/src/pages/Statistics/Sales/index.tsx b/src/pages/Statistics/Sales/index.tsx index e39a415..96eab1b 100644 --- a/src/pages/Statistics/Sales/index.tsx +++ b/src/pages/Statistics/Sales/index.tsx @@ -223,14 +223,17 @@ const ListPage: React.FC = () => { (yooneTotal.yoone12Quantity || 0) + (yooneTotal.yoone15Quantity || 0) + (yooneTotal.yoone18Quantity || 0) + - (yooneTotal.zexQuantity || 0) - } + (yooneTotal.zexQuantity || 0)}
YOONE 3MG: {yooneTotal.yoone3Quantity || 0}
YOONE 6MG: {yooneTotal.yoone6Quantity || 0}
YOONE 9MG: {yooneTotal.yoone9Quantity || 0}
YOONE 12MG新: {yooneTotal.yoone12QuantityNew || 0}
-
YOONE 12MG白: {(yooneTotal.yoone12Quantity || 0) - (yooneTotal.yoone12QuantityNew || 0)}
+
+ YOONE 12MG白:{' '} + {(yooneTotal.yoone12Quantity || 0) - + (yooneTotal.yoone12QuantityNew || 0)} +
YOONE 15MG: {yooneTotal.yoone15Quantity || 0}
YOONE 18MG: {yooneTotal.yoone18Quantity || 0}
ZEX: {yooneTotal.zexQuantity || 0}
diff --git a/src/pages/Stock/PurchaseOrder/index.tsx b/src/pages/Stock/PurchaseOrder/index.tsx index 066ba35..5a00cd1 100644 --- a/src/pages/Stock/PurchaseOrder/index.tsx +++ b/src/pages/Stock/PurchaseOrder/index.tsx @@ -427,9 +427,7 @@ const UpdateForm: React.FC<{ {({ items }) => { - return ( - '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0) - ); + return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0); }} @@ -459,7 +457,7 @@ const UpdateForm: React.FC<{ return ( data?.map((item) => { return { - label: `${item.name} - ${item.nameCn}`, + label: `${item.name} - ${item.nameCn}`, value: item.sku, }; }) || [] @@ -624,7 +622,7 @@ const DetailForm: React.FC<{ return ( data?.map((item) => { return { - label: `${item.name} - ${item.nameCn}`, + label: `${item.name} - ${item.nameCn}`, value: item.sku, }; }) || [] diff --git a/src/pages/Stock/Record/index.tsx b/src/pages/Stock/Record/index.tsx index 48a5e88..5ece148 100644 --- a/src/pages/Stock/Record/index.tsx +++ b/src/pages/Stock/Record/index.tsx @@ -31,12 +31,12 @@ const ListPage: React.FC = () => { dataIndex: 'operationType', valueType: 'select', valueEnum: { - 'in': { - text: '入库' + in: { + text: '入库', + }, + out: { + text: '出库', }, - "out": { - text: '出库' - } }, }, { diff --git a/src/pages/Stock/Transfer/index.tsx b/src/pages/Stock/Transfer/index.tsx index a5b7a57..ee8b01b 100644 --- a/src/pages/Stock/Transfer/index.tsx +++ b/src/pages/Stock/Transfer/index.tsx @@ -207,7 +207,7 @@ const CreateForm: React.FC<{ drawerProps={{ destroyOnHidden: true, }} - onFinish={async ({orderNumber,...values}) => { + onFinish={async ({ orderNumber, ...values }) => { try { const { success, message: errMsg } = await stockcontrollerCreatetransfer(values); @@ -272,24 +272,38 @@ const CreateForm: React.FC<{ rules={[{ required: true, message: '请选择源目标仓库' }]} /> - { - const orderNumber = await form.getFieldValue('orderNumber') - const { data } = await stockcontrollerGetpurchaseorder({orderNumber}) - form.setFieldsValue({ - items: data?.map( - (item: { productName: string; productSku: string }) => ({ - ...item, - productSku: { - label: item.productName, - value: item.productSku, - }, - }), - ), - }) - }}>引用} /> + { + const orderNumber = await form.getFieldValue('orderNumber'); + const { data } = await stockcontrollerGetpurchaseorder({ + orderNumber, + }); + form.setFieldsValue({ + items: data?.map( + (item: { productName: string; productSku: string }) => ({ + ...item, + productSku: { + label: item.productName, + value: item.productSku, + }, + }), + ), + }); + }} + > + 引用 + + } + /> {({ items }) => { - return '数量:' + (items?.reduce?.((acc, cur) => acc + cur.quantity, 0)||0); + return ( + '数量:' + + (items?.reduce?.((acc, cur) => acc + cur.quantity, 0) || 0) + ); }} { return { - label: `${item.name} - ${item.nameCn}`, + label: `${item.name} - ${item.nameCn}`, value: item.sku, }; }) || [] diff --git a/src/pages/Subscription/List/index.tsx b/src/pages/Subscription/List/index.tsx index d1ac189..184d578 100644 --- a/src/pages/Subscription/List/index.tsx +++ b/src/pages/Subscription/List/index.tsx @@ -1,4 +1,8 @@ -import React, { useRef, useState } from 'react'; +import { sitecontrollerAll } from '@/servers/api/site'; +import { + subscriptioncontrollerList, + subscriptioncontrollerSync, +} from '@/servers/api/subscription'; import { ActionType, DrawerForm, @@ -7,14 +11,10 @@ import { ProFormSelect, ProTable, } from '@ant-design/pro-components'; -import { App, Button, Tag, Drawer, List } from 'antd'; +import { App, Button, Drawer, List, Tag } from 'antd'; import dayjs from 'dayjs'; +import React, { useRef, useState } from 'react'; import { request } from 'umi'; -import { - subscriptioncontrollerList, - subscriptioncontrollerSync, -} from '@/servers/api/subscription'; -import { sitecontrollerAll } from '@/servers/api/site'; /** * 订阅状态枚举(用于筛选与展示) @@ -77,7 +77,11 @@ const ListPage: React.FC = () => { valueEnum: SUBSCRIPTION_STATUS_ENUM, // 以 Tag 形式展示,更易辨识 render: (_, row) => - row?.status ? {SUBSCRIPTION_STATUS_ENUM[row.status]?.text || row.status} : '-', + row?.status ? ( + {SUBSCRIPTION_STATUS_ENUM[row.status]?.text || row.status} + ) : ( + '-' + ), width: 120, }, { @@ -152,9 +156,9 @@ const ListPage: React.FC = () => { const { success, data, message: errMsg } = resp as any; if (!success) throw new Error(errMsg || '获取失败'); // 仅保留与父订单号完全一致的订单(避免模糊匹配误入) - const candidates: any[] = (Array.isArray(data) ? data : []).filter( - (c: any) => String(c?.externalOrderId) === parentNumber - ); + const candidates: any[] = ( + Array.isArray(data) ? data : [] + ).filter((c: any) => String(c?.externalOrderId) === parentNumber); // 拉取详情,补充状态、金额、时间 const details = [] as any[]; for (const c of candidates) { @@ -230,14 +234,22 @@ const ListPage: React.FC = () => {
- {item?.date_created ? dayjs(item.date_created).format('YYYY-MM-DD HH:mm') : '-'} + + {item?.date_created + ? dayjs(item.date_created).format('YYYY-MM-DD HH:mm') + : '-'} + {item?.status || '-'} {item?.currency_symbol || ''} - {typeof item?.total === 'number' ? item.total.toFixed(2) : item?.total ?? '-'} + {typeof item?.total === 'number' + ? item.total.toFixed(2) + : item?.total ?? '-'}
@@ -274,7 +286,9 @@ const SyncForm: React.FC<{ */ onFinish={async (values) => { try { - const { success, message: errMsg } = await subscriptioncontrollerSync(values); + const { success, message: errMsg } = await subscriptioncontrollerSync( + values, + ); if (!success) { throw new Error(errMsg); } diff --git a/src/pages/Subscription/Orders/OrderDetailDrawer.tsx b/src/pages/Subscription/Orders/OrderDetailDrawer.tsx index eabbbb3..23dd234 100644 --- a/src/pages/Subscription/Orders/OrderDetailDrawer.tsx +++ b/src/pages/Subscription/Orders/OrderDetailDrawer.tsx @@ -1,31 +1,21 @@ -import React, { useEffect, useRef, useState } from 'react'; -import { - App, - Button, - Card, - Divider, - Drawer, - Empty, - Popconfirm, - Space, - Tag, -} from 'antd'; -import { ActionType, ProDescriptions } from '@ant-design/pro-components'; import { CopyOutlined, DeleteFilled } from '@ant-design/icons'; +import { ActionType, ProDescriptions } from '@ant-design/pro-components'; +import { App, Button, Card, Divider, Drawer, Empty, Popconfirm } from 'antd'; +import React, { useEffect, useRef } from 'react'; // 服务器 API 引用(保持与原 index.tsx 一致) +import { logisticscontrollerDelshipment } from '@/servers/api/logistics'; import { ordercontrollerChangestatus, ordercontrollerGetorderdetail, ordercontrollerSyncorderbyid, } from '@/servers/api/order'; -import { logisticscontrollerDelshipment } from '@/servers/api/logistics'; import { sitecontrollerAll } from '@/servers/api/site'; // 工具与子组件 +import { ORDER_STATUS_ENUM } from '@/constants'; import { formatShipmentState, formatSource } from '@/utils/format'; import RelatedOrders from './RelatedOrders'; -import { ORDER_STATUS_ENUM } from '@/constants'; // 为保持原文件结构简单,此处从 index.tsx 引入的子组件仍由原文件导出或保持原状 // 若后续需要彻底解耦,可将 OrderNote / Shipping / SalesChange 也独立到文件 @@ -35,13 +25,13 @@ type OrderRecord = API.Order; interface OrderDetailDrawerProps { tableRef: React.MutableRefObject; // 列表刷新引用 - orderId: number; // 订单主键 ID - record: OrderRecord; // 订单行记录 - open: boolean; // 是否打开抽屉 - onClose: () => void; // 关闭抽屉回调 - setActiveLine: (id: number) => void; // 高亮当前行 - OrderNoteComponent: React.ComponentType; // 备注组件(从外部注入) - SalesChangeComponent: React.ComponentType; // 换货组件(从外部注入) + orderId: number; // 订单主键 ID + record: OrderRecord; // 订单行记录 + open: boolean; // 是否打开抽屉 + onClose: () => void; // 关闭抽屉回调 + setActiveLine: (id: number) => void; // 高亮当前行 + OrderNoteComponent: React.ComponentType; // 备注组件(从外部注入) + SalesChangeComponent: React.ComponentType; // 换货组件(从外部注入) } const OrderDetailDrawer: React.FC = ({ @@ -59,14 +49,18 @@ const OrderDetailDrawer: React.FC = ({ // 加载详情数据(与 index.tsx 中完全保持一致) const initRequest = async () => { - const { data, success }: API.OrderDetailRes = await ordercontrollerGetorderdetail({ orderId }); + const { data, success }: API.OrderDetailRes = + await ordercontrollerGetorderdetail({ orderId }); if (!success || !data) return { data: {} } as any; - data.sales = data.sales?.reduce((acc: API.OrderSale[], cur: API.OrderSale) => { - const idx = acc.findIndex((v: any) => v.productId === cur.productId); - if (idx === -1) acc.push(cur); - else acc[idx].quantity += cur.quantity; - return acc; - }, []); + data.sales = data.sales?.reduce( + (acc: API.OrderSale[], cur: API.OrderSale) => { + const idx = acc.findIndex((v: any) => v.productId === cur.productId); + if (idx === -1) acc.push(cur); + else acc[idx].quantity += cur.quantity; + return acc; + }, + [], + ); return { data } as any; }; @@ -220,108 +214,273 @@ const OrderDetailDrawer: React.FC = ({ : []), ]} > - - { - const { data = [] } = await sitecontrollerAll(); - return data.map((item) => ({ label: item.siteName, value: item.id })); - }} /> - - + + { + const { data = [] } = await sitecontrollerAll(); + return data.map((item) => ({ + label: item.siteName, + value: item.id, + })); + }} + /> + + - ( -
{r?.shipping?.phone || r?.billing?.phone || '-'}
- )} /> + ( +
+ {r?.shipping?.phone || r?.billing?.phone || '-'} +
+ )} + /> - formatSource(r.source_type, r.utm_source)} /> - - - - ( -
-
company:{r?.shipping?.company || r?.billing?.company || '-'}
-
first_name:{r?.shipping?.first_name || r?.billing?.first_name || '-'}
-
last_name:{r?.shipping?.last_name || r?.billing?.last_name || '-'}
-
country:{r?.shipping?.country || r?.billing?.country || '-'}
-
state:{r?.shipping?.state || r?.billing?.state || '-'}
-
city:{r?.shipping?.city || r?.billing?.city || '-'}
-
postcode:{r?.shipping?.postcode || r?.billing?.postcode || '-'}
-
phone:{r?.shipping?.phone || r?.billing?.phone || '-'}
-
address_1:{r?.shipping?.address_1 || r?.billing?.address_1 || '-'}
-
- )} /> - ( -
    - {(r?.items || []).map((item: any) => ( -
  • {item.name}:{item.quantity}
  • - ))} -
- )} /> - ( - - )} /> - ( -
    - {(r?.sales || []).map((item: any) => ( -
  • {item.name}:{item.quantity}
  • - ))} -
- )} /> - ( - - )} /> - { - if (!r.notes || r.notes.length === 0) return (); - return ( -
- {r.notes.map((note: any) => ( -
-
- {note.username} - {note.createdAt} + formatSource(r.source_type, r.utm_source)} + /> + + + + ( +
+
+ company: + + {r?.shipping?.company || r?.billing?.company || '-'} + +
+
+ first_name: + + {r?.shipping?.first_name || r?.billing?.first_name || '-'} + +
+
+ last_name: + + {r?.shipping?.last_name || r?.billing?.last_name || '-'} + +
+
+ country: + + {r?.shipping?.country || r?.billing?.country || '-'} + +
+
+ state: + {r?.shipping?.state || r?.billing?.state || '-'} +
+
+ city:{r?.shipping?.city || r?.billing?.city || '-'} +
+
+ postcode: + + {r?.shipping?.postcode || r?.billing?.postcode || '-'} + +
+
+ phone: + {r?.shipping?.phone || r?.billing?.phone || '-'} +
+
+ address_1: + + {r?.shipping?.address_1 || r?.billing?.address_1 || '-'} + +
+
+ )} + /> + ( +
    + {(r?.items || []).map((item: any) => ( +
  • + {item.name}:{item.quantity} +
  • + ))} +
+ )} + /> + } + /> + ( +
    + {(r?.sales || []).map((item: any) => ( +
  • + {item.name}:{item.quantity} +
  • + ))} +
+ )} + /> + ( + + )} + /> + { + if (!r.notes || r.notes.length === 0) + return ; + return ( +
+ {r.notes.map((note: any) => ( +
+
+ {note.username} + {note.createdAt} +
+
{note.content}
-
{note.content}
-
- ))} -
- ); - }} /> - { - if (!r.shipment || r.shipment.length === 0) return (); - return ( -
- {r.shipment.map((v: any) => ( - - {v.tracking_provider} - {v.primary_tracking_number} - { - try { await navigator.clipboard.writeText(v.tracking_url); message.success('复制成功!'); } - catch { message.error('复制失败!'); } - }} /> - } - actions={ (v.state === 'waiting-for-scheduling' || v.state === 'waiting-for-transit') ? [ - { - try { const { success, message: errMsg } = await logisticscontrollerDelshipment({ id: v.id }); if (!success) throw new Error(errMsg); tableRef.current?.reload(); ref.current?.reload?.(); } - catch (error: any) { message.error(error.message); } - }}> - 取消运单 - - ] : [] } - > -
订单号: {Array.isArray(v?.orderIds) ? v.orderIds.join(',') : '-'}
- {Array.isArray(v?.items) && v.items.map((item: any) => ( -
{item.name}: {item.quantity}
- ))} -
- ))} -
- ); - }} /> + ))} +
+ ); + }} + /> + { + if (!r.shipment || r.shipment.length === 0) + return ; + return ( +
+ {r.shipment.map((v: any) => ( + + {v.tracking_provider} + {v.primary_tracking_number} + { + try { + await navigator.clipboard.writeText( + v.tracking_url, + ); + message.success('复制成功!'); + } catch { + message.error('复制失败!'); + } + }} + /> + + } + actions={ + v.state === 'waiting-for-scheduling' || + v.state === 'waiting-for-transit' + ? [ + { + try { + const { success, message: errMsg } = + await logisticscontrollerDelshipment({ + id: v.id, + }); + if (!success) throw new Error(errMsg); + tableRef.current?.reload(); + ref.current?.reload?.(); + } catch (error: any) { + message.error(error.message); + } + }} + > + + 取消运单 + , + ] + : [] + } + > +
+ 订单号:{' '} + {Array.isArray(v?.orderIds) ? v.orderIds.join(',') : '-'} +
+ {Array.isArray(v?.items) && + v.items.map((item: any) => ( +
+ {item.name}: {item.quantity} +
+ ))} +
+ ))} +
+ ); + }} + /> ); }; -export default OrderDetailDrawer; \ No newline at end of file +export default OrderDetailDrawer; diff --git a/src/pages/Subscription/Orders/RelatedOrders.tsx b/src/pages/Subscription/Orders/RelatedOrders.tsx index 5b06530..6600dd3 100644 --- a/src/pages/Subscription/Orders/RelatedOrders.tsx +++ b/src/pages/Subscription/Orders/RelatedOrders.tsx @@ -1,7 +1,7 @@ -import React from 'react'; import { Empty, Tag } from 'antd'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; +import React from 'react'; dayjs.extend(relativeTime); @@ -12,17 +12,36 @@ dayjs.extend(relativeTime); */ const RelatedOrders: React.FC<{ data?: any[] }> = ({ data = [] }) => { const rows = (Array.isArray(data) ? data : []).map((it: any) => { - const isSubscription = !!it?.externalSubscriptionId || !!it?.billing_period || !!it?.line_items; - const number = isSubscription ? `#${it?.externalSubscriptionId || it?.id}` : `#${it?.externalOrderId || it?.id}`; + const isSubscription = + !!it?.externalSubscriptionId || !!it?.billing_period || !!it?.line_items; + const number = isSubscription + ? `#${it?.externalSubscriptionId || it?.id}` + : `#${it?.externalOrderId || it?.id}`; const relationship = isSubscription ? 'Subscription' : 'Order'; - const dateRaw = it?.start_date || it?.date_created || it?.createdAt || it?.updatedAt; + const dateRaw = + it?.start_date || it?.date_created || it?.createdAt || it?.updatedAt; const dateText = dateRaw ? dayjs(dateRaw).fromNow() : '-'; const status = (isSubscription ? it?.status : it?.orderStatus) || '-'; const statusLower = String(status).toLowerCase(); - const color = statusLower === 'active' ? 'green' : statusLower === 'cancelled' ? 'red' : 'default'; + const color = + statusLower === 'active' + ? 'green' + : statusLower === 'cancelled' + ? 'red' + : 'default'; const totalNum = Number(it?.total || 0); - const totalText = isSubscription ? `$${totalNum.toFixed(2)} / ${it?.billing_period || 'period'}` : `$${totalNum.toFixed(2)}`; - return { key: `${isSubscription ? 'sub' : 'order'}-${it?.id}`, number, relationship, dateText, status, color, totalText }; + const totalText = isSubscription + ? `$${totalNum.toFixed(2)} / ${it?.billing_period || 'period'}` + : `$${totalNum.toFixed(2)}`; + return { + key: `${isSubscription ? 'sub' : 'order'}-${it?.id}`, + number, + relationship, + dateText, + status, + color, + totalText, + }; }); if (rows.length === 0) return ; @@ -30,7 +49,14 @@ const RelatedOrders: React.FC<{ data?: any[] }> = ({ data = [] }) => { return (
{/* 表头(英文文案,符合国际化默认英文的要求) */} -
+
订单编号
关系
日期
@@ -39,11 +65,23 @@ const RelatedOrders: React.FC<{ data?: any[] }> = ({ data = [] }) => {
{rows.map((r) => ( -
- +
+
{r.relationship}
{r.dateText}
-
{r.status}
+
+ {r.status} +
{r.totalText}
))} diff --git a/src/pages/Subscription/Orders/index.tsx b/src/pages/Subscription/Orders/index.tsx index bc4a9bb..f3a6514 100644 --- a/src/pages/Subscription/Orders/index.tsx +++ b/src/pages/Subscription/Orders/index.tsx @@ -1,12 +1,16 @@ -import React, { useRef, useState } from 'react'; -import { PageContainer } from '@ant-design/pro-layout'; -import type { ProColumns, ActionType, ProTableProps } from '@ant-design/pro-components'; -import { ProTable } from '@ant-design/pro-components'; -import { App, Tag, Button } from 'antd'; -import dayjs from 'dayjs'; import { ordercontrollerGetorders } from '@/servers/api/order'; -import OrderDetailDrawer from './OrderDetailDrawer'; import { sitecontrollerAll } from '@/servers/api/site'; +import type { + ActionType, + ProColumns, + ProTableProps, +} from '@ant-design/pro-components'; +import { ProTable } from '@ant-design/pro-components'; +import { PageContainer } from '@ant-design/pro-layout'; +import { App, Button, Tag } from 'antd'; +import dayjs from 'dayjs'; +import React, { useRef, useState } from 'react'; +import OrderDetailDrawer from './OrderDetailDrawer'; interface OrderItemRow { id: number; @@ -43,7 +47,10 @@ const OrdersPage: React.FC = () => { valueType: 'select', request: async () => { const { data = [] } = await sitecontrollerAll(); - return (data || []).map((item: any) => ({ label: item.siteName, value: item.id })); + return (data || []).map((item: any) => ({ + label: item.siteName, + value: item.id, + })); }, }, { @@ -51,7 +58,10 @@ const OrdersPage: React.FC = () => { dataIndex: 'date_created', width: 180, hideInSearch: true, - render: (_, row) => (row?.date_created ? dayjs(row.date_created).format('YYYY-MM-DD HH:mm') : '-'), + render: (_, row) => + row?.date_created + ? dayjs(row.date_created).format('YYYY-MM-DD HH:mm') + : '-', }, { title: '邮箱', @@ -109,7 +119,14 @@ const OrdersPage: React.FC = () => { const request: ProTableProps['request'] = async (params) => { try { - const { current = 1, pageSize = 10, siteId, keyword, customer_email, payment_method } = params as any; + const { + current = 1, + pageSize = 10, + siteId, + keyword, + customer_email, + payment_method, + } = params as any; const [startDate, endDate] = (params as any).dateRange || []; const resp = await ordercontrollerGetorders({ current, @@ -119,7 +136,9 @@ const OrdersPage: React.FC = () => { customer_email, payment_method, isSubscriptionOnly: true as any, - startDate: startDate ? (dayjs(startDate).toISOString() as any) : undefined, + startDate: startDate + ? (dayjs(startDate).toISOString() as any) + : undefined, endDate: endDate ? (dayjs(endDate).toISOString() as any) : undefined, } as any); const { success, data, message: errMsg } = resp as any; @@ -136,10 +155,10 @@ const OrdersPage: React.FC = () => { }; return ( - + actionRef={actionRef} - rowKey='id' + rowKey="id" columns={columns} request={request} pagination={{ showSizeChanger: true }} diff --git a/src/pages/Template/index.tsx b/src/pages/Template/index.tsx index 783fff1..ce3f980 100644 --- a/src/pages/Template/index.tsx +++ b/src/pages/Template/index.tsx @@ -87,7 +87,9 @@ const List: React.FC = () => { rowKey="id" toolBarRender={() => []} request={async (params) => { - const response = await templatecontrollerGettemplatelist(params as any) as any; + const response = (await templatecontrollerGettemplatelist( + params as any, + )) as any; return { data: response.items || [], total: response.total || 0, @@ -202,5 +204,4 @@ const UpdateForm: React.FC<{ ); }; - export default List; diff --git a/src/pages/Track/index.tsx b/src/pages/Track/index.tsx index ed45b43..3f06a50 100644 --- a/src/pages/Track/index.tsx +++ b/src/pages/Track/index.tsx @@ -1,6 +1,6 @@ import { + logisticscontrollerGetlistbyorderid, logisticscontrollerGetorderlist, - logisticscontrollerGetlistbyorderid } from '@/servers/api/logistics'; import { SearchOutlined } from '@ant-design/icons'; import { PageContainer, ProFormSelect } from '@ant-design/pro-components'; @@ -16,8 +16,9 @@ const TrackPage: React.FC = () => { debounceTime={500} request={async ({ keyWords }) => { if (!keyWords || keyWords.length < 3) return []; - const { data: trackList } = - await logisticscontrollerGetorderlist({ number: keyWords }); + const { data: trackList } = await logisticscontrollerGetorderlist({ + number: keyWords, + }); return trackList?.map((v) => { return { label: v.siteName + ' ' + v.externalOrderId, @@ -29,8 +30,8 @@ const TrackPage: React.FC = () => { prefix: '订单号', async onChange(value: string) { setId(value); - setData({}) - + setData({}); + const { data } = await logisticscontrollerGetlistbyorderid({ id, }); @@ -53,32 +54,34 @@ const TrackPage: React.FC = () => { ), }} /> - { - data?.item ? + {data?.item ? ( +
-
-

原订单内容

- {data?.item?.map((item) => ( -
- {item.name} * {item.quantity} -
- ))} -
-
: <> - } - { - data?.saleItem ? +

原订单内容

+ {data?.item?.map((item) => ( +
+ {item.name} * {item.quantity} +
+ ))} +
+
+ ) : ( + <> + )} + {data?.saleItem ? ( +
-
-

订单内容

- {data?.saleItem?.map((item) => ( -
- {item.name} * {item.quantity} -
- ))} -
-
: <> - } +

订单内容

+ {data?.saleItem?.map((item) => ( +
+ {item.name} * {item.quantity} +
+ ))} +
+
+ ) : ( + <> + )} ); }; diff --git a/src/style/order-list.css b/src/style/order-list.css index f43dc6a..ca3f1c3 100644 --- a/src/style/order-list.css +++ b/src/style/order-list.css @@ -1,3 +1,3 @@ .selected-line-order-protable { - background-color: #add8e6; -} \ No newline at end of file + background-color: #add8e6; +} diff --git a/typings.d.ts b/typings.d.ts index 651fbe8..88ae306 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -1,16 +1,14 @@ import '@umijs/max/typings'; declare namespace BaseType { - - type EnumTransformOptions { + type EnumTransformOptions = { value: string; // 用于作为 value 的字段名 label: string; // 用于作为 text 的字段名 status?: string | undefined; // 可选:用于设置状态的字段名 color?: string | undefined; // 可选:用于设置颜色的字段名 - } - + }; } declare global { const UMI_APP_API_URL: string; - } \ No newline at end of file +}