forked from yoone/WEB
init
This commit is contained in:
parent
27801fd448
commit
a500b88b31
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: require.resolve('@umijs/max/eslint'),
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/node_modules
|
||||||
|
/.env.local
|
||||||
|
/.umirc.local.ts
|
||||||
|
/config/config.local.ts
|
||||||
|
/src/.umi
|
||||||
|
/src/.umi-production
|
||||||
|
/src/.umi-test
|
||||||
|
/.umi
|
||||||
|
/.umi-production
|
||||||
|
/.umi-test
|
||||||
|
/dist
|
||||||
|
/.mfsu
|
||||||
|
.swc
|
||||||
|
/package-lock.json
|
||||||
|
/package.json
|
||||||
|
/yarn.lock
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
export default {
|
||||||
|
schemaPath: 'http://127.0.0.1:7001/swagger-ui/index.json',
|
||||||
|
serversPath: './src/servers',
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules
|
||||||
|
.umi
|
||||||
|
.umi-production
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"printWidth": 80,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"proseWrap": "never",
|
||||||
|
"overrides": [{ "files": ".prettierrc", "options": { "parser": "json" } }],
|
||||||
|
"plugins": ["prettier-plugin-organize-imports", "prettier-plugin-packagejson"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: require.resolve('@umijs/max/stylelint'),
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
import { defineConfig } from '@umijs/max';
|
||||||
|
|
||||||
|
const isDev = process.env.NODE_ENV === 'development';
|
||||||
|
const UMI_APP_API_URL = isDev
|
||||||
|
? 'http://localhost:7001'
|
||||||
|
: 'https://api.yoone.ca';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
antd: {},
|
||||||
|
access: {},
|
||||||
|
model: {},
|
||||||
|
initialState: {},
|
||||||
|
request: {},
|
||||||
|
layout: {
|
||||||
|
title: 'YOONE',
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
UMI_APP_API_URL,
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{ path: '/', redirect: '/home' },
|
||||||
|
{ name: '追踪', path: '/track', component: './Track', layout: false },
|
||||||
|
{ name: '登录', path: '/login', component: './Login', layout: false },
|
||||||
|
{ name: '首页', path: '/home', component: './Home' },
|
||||||
|
{
|
||||||
|
name: '组织架构',
|
||||||
|
path: '/organiza',
|
||||||
|
access: 'canSeeSuper',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: '用户管理',
|
||||||
|
path: '/organiza/user',
|
||||||
|
component: './Organiza/User',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '商品管理',
|
||||||
|
path: '/product',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: '商品分类',
|
||||||
|
path: '/product/category',
|
||||||
|
component: './Product/Category',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '强度',
|
||||||
|
path: '/product/strength',
|
||||||
|
component: './Product/Strength',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '口味',
|
||||||
|
path: '/product/flavors',
|
||||||
|
component: './Product/Flavors',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '产品列表',
|
||||||
|
path: '/product/list',
|
||||||
|
component: './Product/List',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'WP商品列表',
|
||||||
|
path: '/product/wp_list',
|
||||||
|
component: './Product/WpList',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '库存管理',
|
||||||
|
path: '/stock',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: '库存列表',
|
||||||
|
path: '/stock/list',
|
||||||
|
component: './Stock/List',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '仓库点',
|
||||||
|
path: '/stock/warehouse',
|
||||||
|
component: './Stock/Warehouse',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '入库管理',
|
||||||
|
path: '/stock/purchaseOrder',
|
||||||
|
component: './Stock/PurchaseOrder',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '调拨管理',
|
||||||
|
path: '/stock/transfer',
|
||||||
|
component: './Stock/Transfer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '库存记录',
|
||||||
|
path: '/stock/record',
|
||||||
|
component: './Stock/Record',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '订单管理',
|
||||||
|
path: '/order',
|
||||||
|
access: 'canSeeAdmin',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: '订单列表',
|
||||||
|
path: '/order/list',
|
||||||
|
component: './Order/List',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: '物流管理',
|
||||||
|
// path: '/logistics',
|
||||||
|
// routes: [
|
||||||
|
// {
|
||||||
|
// name: '服务商',
|
||||||
|
// path: '/logistics/services',
|
||||||
|
// component: './Logistics/Services',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: '地址管理',
|
||||||
|
// path: '/logistics/address',
|
||||||
|
// component: './Logistics/Address',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: '物流列表',
|
||||||
|
// path: '/logistics/list',
|
||||||
|
// component: './Logistics/List',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
name: '数据统计',
|
||||||
|
path: '/statistics',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
name: '销售统计',
|
||||||
|
path: '/statistics/sales',
|
||||||
|
component: './Statistics/Sales',
|
||||||
|
access: 'canSeeSuper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '订单统计',
|
||||||
|
path: '/statistics/order',
|
||||||
|
component: './Statistics/Order',
|
||||||
|
access: 'canSeeSuper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '客户统计',
|
||||||
|
path: '/statistics/customer',
|
||||||
|
component: './Statistics/Customer',
|
||||||
|
access: 'canSeeSuper',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '库存预测',
|
||||||
|
path: '/statistics/inventoryForecast',
|
||||||
|
component: './Statistics/InventoryForecast',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '补货',
|
||||||
|
path: '/statistics/restocking',
|
||||||
|
component: './Statistics/Restocking',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// path: '*',
|
||||||
|
// component: './404',
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
npmClient: 'pnpm',
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
const users = [
|
||||||
|
{ id: 0, name: 'Umi', nickName: 'U', gender: 'MALE' },
|
||||||
|
{ id: 1, name: 'Fish', nickName: 'B', gender: 'FEMALE' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'GET /api/v1/queryUserList': (req: any, res: any) => {
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
data: { list: users },
|
||||||
|
errorCode: 0,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'PUT /api/v1/user/': (req: any, res: any) => {
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
errorCode: 0,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
export default (initialState: any) => {
|
||||||
|
const canSeeSuper = initialState?.user?.isSuper;
|
||||||
|
const canSeeAdmin =
|
||||||
|
initialState?.user?.isSuper || initialState?.user?.isAdmin;
|
||||||
|
return {
|
||||||
|
canSeeSuper,
|
||||||
|
canSeeAdmin,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
// 运行时配置
|
||||||
|
|
||||||
|
import { LogoutOutlined, UserOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ProLayoutProps,
|
||||||
|
ProSchemaValueEnumObj,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { RequestConfig, history, useModel } from '@umijs/max';
|
||||||
|
import { App, Avatar, ConfigProvider, Dropdown, MenuProps } from 'antd';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
|
import { usercontrollerGetuser } from './servers/api/user';
|
||||||
|
|
||||||
|
// 设置 dayjs 全局语言为中文
|
||||||
|
dayjs.locale('zh-cn');
|
||||||
|
|
||||||
|
// 全局初始化数据配置,用于 Layout 用户信息和权限初始化
|
||||||
|
// 更多信息见文档:https://umijs.org/docs/api/runtime-config#getinitialstate
|
||||||
|
export async function getInitialState(): Promise<{
|
||||||
|
user?: Record<string, any>;
|
||||||
|
categoryList?: ProSchemaValueEnumObj;
|
||||||
|
sites?: API.SiteConfig[];
|
||||||
|
}> {
|
||||||
|
if (!localStorage.getItem('token') || history.location.pathname === '/login')
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const { data: user } = await usercontrollerGetuser();
|
||||||
|
return { user };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const layout = (): ProLayoutProps => {
|
||||||
|
const { initialState } = useModel('@@initialState');
|
||||||
|
const items: MenuProps['items'] = [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
label: '我的账号',
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'divider',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
label: '退出登录',
|
||||||
|
icon: <LogoutOutlined />,
|
||||||
|
onClick: async () => {
|
||||||
|
//TODO 清理服务器登陆状态
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
history.push('/login');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
menu: {
|
||||||
|
locale: false,
|
||||||
|
},
|
||||||
|
layout: 'mix',
|
||||||
|
actionsRender: () => (
|
||||||
|
<Dropdown key="avatar" menu={{ items }}>
|
||||||
|
<div style={{ cursor: 'pointer' }}>
|
||||||
|
<Avatar size="large" icon={<UserOutlined />} />
|
||||||
|
<span style={{ marginLeft: 8 }}>{initialState?.name}</span>
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const request: RequestConfig = {
|
||||||
|
baseURL: UMI_APP_API_URL,
|
||||||
|
requestInterceptors: [
|
||||||
|
(url: string, options: any) => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
return {
|
||||||
|
url,
|
||||||
|
options: {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
...options.headers,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errorConfig: {
|
||||||
|
errorHandler: (error: any) => {
|
||||||
|
if (error?.response?.status === 401) {
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
history.push('/login');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const onRouteChange = ({ location }: { location: Location }) => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
|
||||||
|
// 白名单,不需要登录的页面
|
||||||
|
const whiteList = ['/login', '/track'];
|
||||||
|
|
||||||
|
if (!token && !whiteList.includes(location.pathname)) {
|
||||||
|
// 没有 token 且不在白名单内,跳转到登录页
|
||||||
|
history.push('/login');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function rootContainer(container: React.ReactNode) {
|
||||||
|
// 全局过滤空字段逻辑
|
||||||
|
(ProTable as any).defaultProps = {
|
||||||
|
...(ProTable as any).defaultProps,
|
||||||
|
beforeSearchSubmit: (params: any) => {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(params).filter(
|
||||||
|
([_, value]) => value !== undefined && value !== null && value !== '',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<ConfigProvider>
|
||||||
|
<App>{container}</App>
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
import { Input, Select } from 'antd';
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
// 定义国家代码和扩展码的映射关系
|
||||||
|
const phoneExtensions: { [key: string]: string } = {
|
||||||
|
CA: '1',
|
||||||
|
CN: '86',
|
||||||
|
US: '1',
|
||||||
|
};
|
||||||
|
|
||||||
|
interface InternationalPhoneInputProps {
|
||||||
|
value?: { country?: string; phone?: string; extension?: string };
|
||||||
|
onChange?: (value: {
|
||||||
|
country: string;
|
||||||
|
phone: string;
|
||||||
|
extension?: string;
|
||||||
|
}) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InternationalPhoneInput: React.FC<InternationalPhoneInputProps> = ({
|
||||||
|
value = {},
|
||||||
|
onChange,
|
||||||
|
}) => {
|
||||||
|
const {
|
||||||
|
country = 'CA',
|
||||||
|
phone = '',
|
||||||
|
extension = phoneExtensions['CA'],
|
||||||
|
} = value || {};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
triggerChange({ extension });
|
||||||
|
}, []);
|
||||||
|
const triggerChange = (
|
||||||
|
changedValue: Partial<{
|
||||||
|
country: string;
|
||||||
|
phone: string;
|
||||||
|
extension?: string;
|
||||||
|
}>,
|
||||||
|
) => {
|
||||||
|
if (onChange) {
|
||||||
|
onChange({
|
||||||
|
country,
|
||||||
|
phone,
|
||||||
|
...value,
|
||||||
|
...changedValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCountryChange = (newCountry: string) => {
|
||||||
|
triggerChange({
|
||||||
|
country: newCountry,
|
||||||
|
extension: phoneExtensions[newCountry],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPhoneChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||||
|
triggerChange({ phone: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
addonBefore={
|
||||||
|
<Select
|
||||||
|
value={country}
|
||||||
|
onChange={onCountryChange}
|
||||||
|
style={{ width: 100 }}
|
||||||
|
>
|
||||||
|
<Option value="CA">🇨🇦 +1</Option>
|
||||||
|
<Option value="CN">🇨🇳 +86</Option>
|
||||||
|
<Option value="US">🇺🇸 +1</Option>
|
||||||
|
{/* 添加更多国家代码 */}
|
||||||
|
</Select>
|
||||||
|
}
|
||||||
|
value={phone}
|
||||||
|
onChange={onPhoneChange}
|
||||||
|
placeholder="请输入联系电话"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InternationalPhoneInput;
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
import { ProSchemaValueEnumObj } from '@ant-design/pro-components';
|
||||||
|
|
||||||
|
export const DEFAULT_NAME = 'YOONE';
|
||||||
|
|
||||||
|
export const PRODUCT_STATUS_ENUM: ProSchemaValueEnumObj = {
|
||||||
|
publish: {
|
||||||
|
text: '已发布',
|
||||||
|
status: 'success',
|
||||||
|
},
|
||||||
|
draft: {
|
||||||
|
text: '草稿',
|
||||||
|
status: 'default',
|
||||||
|
},
|
||||||
|
pending: {
|
||||||
|
text: '待审核',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
private: {
|
||||||
|
text: '私有',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
trash: {
|
||||||
|
text: '已删除',
|
||||||
|
status: 'error',
|
||||||
|
},
|
||||||
|
'auto-draft': {
|
||||||
|
text: '字段草稿',
|
||||||
|
status: 'default',
|
||||||
|
},
|
||||||
|
future: {
|
||||||
|
text: '定时发布',
|
||||||
|
status: 'success',
|
||||||
|
},
|
||||||
|
inherit: {
|
||||||
|
text: '继承状态',
|
||||||
|
status: 'default',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Purchase_Order_STATUS_ENUM: ProSchemaValueEnumObj = {
|
||||||
|
draft: {
|
||||||
|
text: '草稿',
|
||||||
|
status: 'default',
|
||||||
|
},
|
||||||
|
submitted: {
|
||||||
|
text: '已发货',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
received: {
|
||||||
|
text: '已到达',
|
||||||
|
status: 'success',
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ORDER_STATUS_ENUM: ProSchemaValueEnumObj = {
|
||||||
|
pending: {
|
||||||
|
text: '待确认',
|
||||||
|
status: 'default',
|
||||||
|
},
|
||||||
|
processing: {
|
||||||
|
text: '待发货',
|
||||||
|
status: 'success',
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
text: '已完成',
|
||||||
|
status: 'success',
|
||||||
|
},
|
||||||
|
cancelled: {
|
||||||
|
text: '已取消',
|
||||||
|
status: 'error',
|
||||||
|
},
|
||||||
|
refunded: {
|
||||||
|
text: '已退款',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
failed: {
|
||||||
|
text: '失败',
|
||||||
|
status: 'error',
|
||||||
|
},
|
||||||
|
after_sale_pending: {
|
||||||
|
text: '售后处理中',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
pending_reshipment: {
|
||||||
|
text: '待补发',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
pending_refund: {
|
||||||
|
text: '待退款',
|
||||||
|
status: 'warning',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// 全局共享数据示例
|
||||||
|
import { DEFAULT_NAME } from '@/constants';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
const useUser = () => {
|
||||||
|
const [name, setName] = useState<string>(DEFAULT_NAME);
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
setName,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useUser;
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
.container {
|
||||||
|
padding-top: 80px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
|
import { useModel } from '@umijs/max';
|
||||||
|
import styles from './index.less';
|
||||||
|
|
||||||
|
const HomePage: React.FC = () => {
|
||||||
|
const { name } = useModel('global');
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<div className={styles.container}></div>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HomePage;
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
import { usercontrollerGetuser, usercontrollerLogin } from '@/servers/api/user';
|
||||||
|
import { LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
LoginFormPage,
|
||||||
|
ProConfigProvider,
|
||||||
|
ProFormText,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { history, useModel } from '@umijs/max';
|
||||||
|
import { App, theme } from 'antd';
|
||||||
|
|
||||||
|
const Page = () => {
|
||||||
|
const { setInitialState } = useModel('@@initialState');
|
||||||
|
const { token } = theme.useToken();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
|
||||||
|
const onFinish = async (values: { username: string; password: string }) => {
|
||||||
|
try {
|
||||||
|
const { data, success } = await usercontrollerLogin(values);
|
||||||
|
if (success) {
|
||||||
|
message.success('登录成功');
|
||||||
|
localStorage.setItem('token', data?.token as string);
|
||||||
|
const { data: user } = await usercontrollerGetuser();
|
||||||
|
setInitialState({ user });
|
||||||
|
history.push('/');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
message.error('登录失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'white',
|
||||||
|
height: '100vh',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LoginFormPage
|
||||||
|
backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp"
|
||||||
|
backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr"
|
||||||
|
title="Yoone"
|
||||||
|
containerStyle={{
|
||||||
|
backgroundColor: 'rgba(0, 0, 0,0.65)',
|
||||||
|
backdropFilter: 'blur(4px)',
|
||||||
|
}}
|
||||||
|
onFinish={onFinish}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="username"
|
||||||
|
fieldProps={{
|
||||||
|
size: 'large',
|
||||||
|
prefix: (
|
||||||
|
<UserOutlined
|
||||||
|
style={{
|
||||||
|
color: token.colorText,
|
||||||
|
}}
|
||||||
|
className={'prefixIcon'}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
placeholder={'请输入用户名!'}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入用户名!',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<ProFormText.Password
|
||||||
|
name="password"
|
||||||
|
fieldProps={{
|
||||||
|
size: 'large',
|
||||||
|
prefix: (
|
||||||
|
<LockOutlined
|
||||||
|
style={{
|
||||||
|
color: token.colorText,
|
||||||
|
}}
|
||||||
|
className={'prefixIcon'}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
placeholder={'请输入密码!'}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码!',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
{/* <div
|
||||||
|
style={{
|
||||||
|
marginBlockEnd: 24,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormCheckbox noStyle name="autoLogin">
|
||||||
|
自动登录
|
||||||
|
</ProFormCheckbox>
|
||||||
|
<a
|
||||||
|
style={{
|
||||||
|
float: 'right',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
忘记密码
|
||||||
|
</a>
|
||||||
|
</div> */}
|
||||||
|
</LoginFormPage>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return (
|
||||||
|
<ProConfigProvider>
|
||||||
|
<Page />
|
||||||
|
</ProConfigProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,405 @@
|
||||||
|
import InternationalPhoneInput from '@/components/InternationalPhoneInput';
|
||||||
|
import {
|
||||||
|
logisticscontrollerCreateshippingaddress,
|
||||||
|
logisticscontrollerDelshippingaddress,
|
||||||
|
logisticscontrollerGetshippingaddresslist,
|
||||||
|
logisticscontrollerUpdateshippingaddress,
|
||||||
|
} from '@/servers/api/logistics';
|
||||||
|
import { stockcontrollerGetallstockpoints } from '@/servers/api/stock';
|
||||||
|
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormItem,
|
||||||
|
ProFormSelect,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Divider, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
|
||||||
|
const columns: ProColumns<API.ShippingAddress>[] = [
|
||||||
|
{
|
||||||
|
title: '仓库点',
|
||||||
|
dataIndex: 'stockPointId',
|
||||||
|
hideInSearch: true,
|
||||||
|
valueType: 'select',
|
||||||
|
request: async () => {
|
||||||
|
const { data = [] } = await stockcontrollerGetallstockpoints();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '地区',
|
||||||
|
dataIndex: ['address', 'region'],
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '城市',
|
||||||
|
dataIndex: ['address', 'city'],
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '邮编',
|
||||||
|
dataIndex: ['address', 'postal_code'],
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '详细地址',
|
||||||
|
dataIndex: ['address', 'address_line_1'],
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系电话',
|
||||||
|
render: (_, record) =>
|
||||||
|
`+${record.phone_number_extension} ${record.phone_number}`,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
<UpdateForm tableRef={actionRef} value={record} />
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await logisticscontrollerDelshippingaddress({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
request={async () => {
|
||||||
|
const { data, success } =
|
||||||
|
await logisticscontrollerGetshippingaddresslist();
|
||||||
|
if (success) {
|
||||||
|
return {
|
||||||
|
data: data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const region = {
|
||||||
|
AB: 'Alberta',
|
||||||
|
BC: 'British',
|
||||||
|
MB: 'Manitoba',
|
||||||
|
NB: 'New',
|
||||||
|
NL: 'Newfoundland',
|
||||||
|
NS: 'Nova',
|
||||||
|
ON: 'Ontario',
|
||||||
|
PE: 'Prince',
|
||||||
|
QC: 'Quebec',
|
||||||
|
SK: 'Saskatchewan',
|
||||||
|
NT: 'Northwest',
|
||||||
|
NU: 'Nunavut',
|
||||||
|
YT: 'Yukon',
|
||||||
|
};
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const { contact, ...params } = values;
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await logisticscontrollerCreateshippingaddress({
|
||||||
|
...params,
|
||||||
|
phone_number: contact?.phone,
|
||||||
|
phone_number_extension: contact?.extension,
|
||||||
|
phone_number_country: contact?.country,
|
||||||
|
} as API.ShippingAddress);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="stockPointId"
|
||||||
|
width="lg"
|
||||||
|
label="仓库点"
|
||||||
|
placeholder="请选择仓库点"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请选择仓库点' }]}
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await stockcontrollerGetallstockpoints();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProForm.Group title="地址">
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'country']}
|
||||||
|
label="国家"
|
||||||
|
initialValue={'CA'}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name={['address', 'region']}
|
||||||
|
label="地区"
|
||||||
|
placeholder={'请选择地区'}
|
||||||
|
showSearch
|
||||||
|
required
|
||||||
|
valueEnum={region}
|
||||||
|
rules={[{ required: true, message: '请选择地区' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'city']}
|
||||||
|
label="城市"
|
||||||
|
placeholder="请输入城市"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入城市' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'postal_code']}
|
||||||
|
label="邮编"
|
||||||
|
placeholder="请输入邮编"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入邮编' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'address_line_1']}
|
||||||
|
label="详细地址"
|
||||||
|
placeholder="请输入详细地址"
|
||||||
|
width="lg"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入详细地址' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
<ProFormItem
|
||||||
|
name="contact"
|
||||||
|
label="联系电话"
|
||||||
|
required
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
async validator(_, value) {
|
||||||
|
if (!value?.phone) {
|
||||||
|
return Promise.reject('请输入联系电话');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InternationalPhoneInput />
|
||||||
|
</ProFormItem>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
value: API.ShippingAddress;
|
||||||
|
}> = ({ tableRef, value }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
phone_number,
|
||||||
|
phone_number_country,
|
||||||
|
phone_number_extension,
|
||||||
|
...initialValue
|
||||||
|
} = value;
|
||||||
|
return (
|
||||||
|
<DrawerForm
|
||||||
|
title="编辑"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const { contact, ...params } = values;
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await logisticscontrollerUpdateshippingaddress(
|
||||||
|
{ id: id as number },
|
||||||
|
{
|
||||||
|
...params,
|
||||||
|
phone_number: contact?.phone,
|
||||||
|
phone_number_extension: contact?.extension,
|
||||||
|
phone_number_country: contact?.country,
|
||||||
|
} as API.ShippingAddress,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
initialValues={{
|
||||||
|
...initialValue,
|
||||||
|
contact: {
|
||||||
|
phone: phone_number,
|
||||||
|
extension: phone_number_extension,
|
||||||
|
country: phone_number_country,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="stockPointId"
|
||||||
|
width="lg"
|
||||||
|
label="仓库点"
|
||||||
|
placeholder="请选择仓库点"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请选择仓库点' }]}
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await stockcontrollerGetallstockpoints();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProForm.Group title="地址">
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'country']}
|
||||||
|
label="国家"
|
||||||
|
initialValue={'CA'}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name={['address', 'region']}
|
||||||
|
label="地区"
|
||||||
|
placeholder={'请选择地区'}
|
||||||
|
showSearch
|
||||||
|
required
|
||||||
|
valueEnum={region}
|
||||||
|
rules={[{ required: true, message: '请选择地区' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'city']}
|
||||||
|
label="城市"
|
||||||
|
placeholder="请输入城市"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入城市' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'postal_code']}
|
||||||
|
label="邮编"
|
||||||
|
placeholder="请输入邮编"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入邮编' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name={['address', 'address_line_1']}
|
||||||
|
label="详细地址"
|
||||||
|
placeholder="请输入详细地址"
|
||||||
|
width="lg"
|
||||||
|
required
|
||||||
|
rules={[{ required: true, message: '请输入详细地址' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
<ProFormItem
|
||||||
|
name="contact"
|
||||||
|
label="联系电话"
|
||||||
|
required
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
async validator(_, value) {
|
||||||
|
if (!value?.phone) {
|
||||||
|
return Promise.reject('请输入联系电话');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InternationalPhoneInput />
|
||||||
|
</ProFormItem>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
import { logisticscontrollerGetlist } from '@/servers/api/logistics';
|
||||||
|
import { stockcontrollerGetallstockpoints } from '@/servers/api/stock';
|
||||||
|
import { formatShipmentState } from '@/utils/format';
|
||||||
|
import { printPDF } from '@/utils/util';
|
||||||
|
import { CopyOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button } from 'antd';
|
||||||
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
|
|
||||||
|
const columns: ProColumns<API.Service>[] = [
|
||||||
|
{
|
||||||
|
title: '服务商',
|
||||||
|
dataIndex: 'tracking_provider',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '仓库',
|
||||||
|
dataIndex: 'stockPointId',
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: 'select',
|
||||||
|
request: async () => {
|
||||||
|
const { data = [] } = await stockcontrollerGetallstockpoints();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '快递单号',
|
||||||
|
dataIndex: 'primary_tracking_number',
|
||||||
|
render(_, record) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{record.primary_tracking_number}
|
||||||
|
<CopyOutlined
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(record.tracking_url);
|
||||||
|
message.success('复制成功!');
|
||||||
|
} catch (err) {
|
||||||
|
message.error('复制失败!');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'state',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return formatShipmentState(record.state);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
hideInSearch: true,
|
||||||
|
valueType: 'dateTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'operation',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (!record?.labels?.length) return null;
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
// printPDF([record.labels[record.labels.length - 1].url])
|
||||||
|
window.open(
|
||||||
|
record.labels[record.labels.length - 1].url,
|
||||||
|
'_blank',
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
打印
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleBatchPrint = async () => {
|
||||||
|
if (selectedRows.length === 0) {
|
||||||
|
message.warning('请选择要打印的项');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await printPDF(
|
||||||
|
selectedRows.map((row) => row.labels[row.labels.length - 1].url),
|
||||||
|
);
|
||||||
|
|
||||||
|
setSelectedRows([]);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (values) => {
|
||||||
|
console.log(values);
|
||||||
|
const { data, success } = await logisticscontrollerGetlist({
|
||||||
|
params: values,
|
||||||
|
});
|
||||||
|
if (success) {
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
// rowSelection={{
|
||||||
|
// selectedRowKeys: selectedRows.map((row) => row.id),
|
||||||
|
// onChange: (_, selectedRows) => setSelectedRows(selectedRows),
|
||||||
|
// }}
|
||||||
|
columns={columns}
|
||||||
|
tableAlertOptionRender={() => {
|
||||||
|
return (
|
||||||
|
<Button onClick={handleBatchPrint} type="primary">
|
||||||
|
批量打印
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
import {
|
||||||
|
logisticscontrollerGetservicelist,
|
||||||
|
logisticscontrollerSyncservices,
|
||||||
|
logisticscontrollerToggleactive,
|
||||||
|
} from '@/servers/api/logistics';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProFormSwitch,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
|
||||||
|
const columns: ProColumns<API.Service>[] = [
|
||||||
|
{
|
||||||
|
title: '服务商 ID',
|
||||||
|
dataIndex: 'id',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '运营商名称',
|
||||||
|
dataIndex: 'carrier_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '服务商名称',
|
||||||
|
dataIndex: 'service_name',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '启用',
|
||||||
|
dataIndex: 'isActive',
|
||||||
|
valueType: 'switch',
|
||||||
|
render(_, record) {
|
||||||
|
return (
|
||||||
|
<ProFormSwitch
|
||||||
|
fieldProps={{
|
||||||
|
checked: record.isActive,
|
||||||
|
onChange: async (value) => {
|
||||||
|
try {
|
||||||
|
const { success } = await logisticscontrollerToggleactive({
|
||||||
|
id: record.id,
|
||||||
|
isActive: value,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error('启动失败');
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.message || '启动失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
toolBarRender={() => [
|
||||||
|
<Button
|
||||||
|
key="syncSite"
|
||||||
|
type="primary"
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
const { success } = await logisticscontrollerSyncservices();
|
||||||
|
if (!success) {
|
||||||
|
throw new Error('同步失败');
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.message || '同步失败');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
同步服务商
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
request={async (values) => {
|
||||||
|
console.log(values);
|
||||||
|
const { data, success } = await logisticscontrollerGetservicelist(
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (success) {
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,125 @@
|
||||||
|
import {
|
||||||
|
usercontrollerAdduser,
|
||||||
|
usercontrollerListusers,
|
||||||
|
} from '@/servers/api/user';
|
||||||
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns[] = [
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
dataIndex: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '激活',
|
||||||
|
dataIndex: 'isActive',
|
||||||
|
valueEnum: {
|
||||||
|
true: {
|
||||||
|
text: '是',
|
||||||
|
},
|
||||||
|
false: {
|
||||||
|
text: '否',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '超管',
|
||||||
|
dataIndex: 'isSuper',
|
||||||
|
valueEnum: {
|
||||||
|
true: {
|
||||||
|
text: '是',
|
||||||
|
},
|
||||||
|
false: {
|
||||||
|
text: '否',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await usercontrollerListusers(params);
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } = await usercontrollerAdduser(
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="username"
|
||||||
|
label="用户名"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入用户名"
|
||||||
|
rules={[{ required: true, message: '请输入用户名' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="password"
|
||||||
|
label="密码"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
rules={[{ required: true, message: '请输入密码' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
import {
|
||||||
|
productcontrollerCreatecategory,
|
||||||
|
productcontrollerDeletecategory,
|
||||||
|
productcontrollerGetcategories,
|
||||||
|
productcontrollerUpdatecategory,
|
||||||
|
} from '@/servers/api/product';
|
||||||
|
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const List: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const columns: ProColumns<API.Category>[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
tip: '名称是唯一的 key',
|
||||||
|
formItemProps: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '名称为必填项',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '标识',
|
||||||
|
dataIndex: 'unique_key',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '更新时间',
|
||||||
|
dataIndex: 'updatedAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
{/* <UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
<Divider type="vertical" /> */}
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerDeletecategory({ id: record.id });
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer header={{ title: '分类列表' }}>
|
||||||
|
<ProTable<API.Category>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await productcontrollerGetcategories(
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.CreateCategoryDTO>
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerCreatecategory(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
width="md"
|
||||||
|
label="分类名称"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="unique_key"
|
||||||
|
width="md"
|
||||||
|
label="Key"
|
||||||
|
placeholder="请输入Key"
|
||||||
|
rules={[{ required: true, message: '请输入Key' }]}
|
||||||
|
/>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.Category;
|
||||||
|
}> = ({ tableRef, values: initialValues }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdateCategoryDTO>
|
||||||
|
title="编辑"
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerUpdatecategory(
|
||||||
|
{ id: initialValues.id },
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
width="md"
|
||||||
|
label="分类名称"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default List;
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
import {
|
||||||
|
productcontrollerCreateflavors,
|
||||||
|
productcontrollerDeleteflavors,
|
||||||
|
productcontrollerGetflavors,
|
||||||
|
productcontrollerUpdateflavors,
|
||||||
|
} from '@/servers/api/product';
|
||||||
|
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const List: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const columns: ProColumns<API.Category>[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
tip: '名称是唯一的 key',
|
||||||
|
formItemProps: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '名称为必填项',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '标识',
|
||||||
|
dataIndex: 'unique_key',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '更新时间',
|
||||||
|
dataIndex: 'updatedAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
{/* <UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
<Divider type="vertical" /> */}
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerDeleteflavors({ id: record.id });
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer header={{ title: '口味列表' }}>
|
||||||
|
<ProTable<API.Category>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await productcontrollerGetflavors(params);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.CreateCategoryDTO>
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerCreateflavors(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
width="md"
|
||||||
|
label="口味名称"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="unique_key"
|
||||||
|
width="md"
|
||||||
|
label="Key"
|
||||||
|
placeholder="请输入Key"
|
||||||
|
rules={[{ required: true, message: '请输入Key' }]}
|
||||||
|
/>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.Category;
|
||||||
|
}> = ({ tableRef, values: initialValues }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdateCategoryDTO>
|
||||||
|
title="编辑"
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerUpdateflavors(
|
||||||
|
{ id: initialValues.id },
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
width="md"
|
||||||
|
label="口味名称"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default List;
|
||||||
|
|
@ -0,0 +1,232 @@
|
||||||
|
import {
|
||||||
|
productcontrollerCreateproduct,
|
||||||
|
productcontrollerDeleteproduct,
|
||||||
|
productcontrollerGetcategorieall,
|
||||||
|
productcontrollerGetflavorsall,
|
||||||
|
productcontrollerGetproductlist,
|
||||||
|
productcontrollerGetstrengthall,
|
||||||
|
} from '@/servers/api/product';
|
||||||
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormSelect,
|
||||||
|
ProFormText,
|
||||||
|
ProFormTextArea,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Popconfirm } from 'antd';
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
|
||||||
|
const List: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const columns: ProColumns<API.Product>[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品描述',
|
||||||
|
dataIndex: 'description',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品分类',
|
||||||
|
dataIndex: 'categoryName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '强度',
|
||||||
|
dataIndex: 'strengthName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '口味',
|
||||||
|
dataIndex: 'flavorsName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '湿度',
|
||||||
|
dataIndex: 'humidity',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'sku',
|
||||||
|
dataIndex: 'sku',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '更新时间',
|
||||||
|
dataIndex: 'updatedAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerDeleteproduct({ id: record.id });
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer header={{ title: '产品列表' }}>
|
||||||
|
<ProTable<API.Product>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await productcontrollerGetproductlist(
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
rowSelection={{
|
||||||
|
onChange: (_, selectedRows) => setSelectedRows(selectedRows),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.CreateProductDTO>
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerCreateproduct(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea
|
||||||
|
name="description"
|
||||||
|
width="lg"
|
||||||
|
label="产品描述"
|
||||||
|
placeholder="请输入产品描述"
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="categoryId"
|
||||||
|
width="lg"
|
||||||
|
label="产品分类"
|
||||||
|
placeholder="请选择产品分类"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await productcontrollerGetcategorieall();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择产品分类' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="strengthId"
|
||||||
|
width="lg"
|
||||||
|
label="强度"
|
||||||
|
placeholder="请选择强度"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await productcontrollerGetstrengthall();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择强度' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="flavorsId"
|
||||||
|
width="lg"
|
||||||
|
label="口味"
|
||||||
|
placeholder="请选择口味"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await productcontrollerGetflavorsall();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择口味' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name="humidity"
|
||||||
|
width="lg"
|
||||||
|
label="干湿"
|
||||||
|
placeholder="请选择干湿"
|
||||||
|
valueEnum={{
|
||||||
|
dry: '干',
|
||||||
|
wet: '湿',
|
||||||
|
}}
|
||||||
|
rules={[{ required: true, message: '请选择干湿' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default List;
|
||||||
|
|
@ -0,0 +1,206 @@
|
||||||
|
import {
|
||||||
|
productcontrollerCreatestrength,
|
||||||
|
productcontrollerDeletestrength,
|
||||||
|
productcontrollerGetstrength,
|
||||||
|
} from '@/servers/api/product';
|
||||||
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const List: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const columns: ProColumns<API.Category>[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
tip: '名称是唯一的 key',
|
||||||
|
formItemProps: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '名称为必填项',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '标识',
|
||||||
|
dataIndex: 'unique_key',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '更新时间',
|
||||||
|
dataIndex: 'updatedAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
{/* <UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
<Divider type="vertical" /> */}
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerDeletestrength({ id: record.id });
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer header={{ title: '强度列表' }}>
|
||||||
|
<ProTable<API.Category>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await productcontrollerGetstrength(params);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.CreateCategoryDTO>
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await productcontrollerCreatestrength(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
width="md"
|
||||||
|
label="强度名称"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="unique_key"
|
||||||
|
width="md"
|
||||||
|
label="Key"
|
||||||
|
placeholder="请输入Key"
|
||||||
|
rules={[{ required: true, message: '请输入Key' }]}
|
||||||
|
/>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const UpdateForm: React.FC<{
|
||||||
|
// tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
// values: API.Category;
|
||||||
|
// }> = ({ tableRef, values: initialValues }) => {
|
||||||
|
// const { message } = App.useApp();
|
||||||
|
// return (
|
||||||
|
// <DrawerForm<API.UpdateCategoryDTO>
|
||||||
|
// title="编辑"
|
||||||
|
// initialValues={initialValues}
|
||||||
|
// trigger={
|
||||||
|
// <Button type="primary">
|
||||||
|
// <EditOutlined />
|
||||||
|
// 编辑
|
||||||
|
// </Button>
|
||||||
|
// }
|
||||||
|
// autoFocusFirstInput
|
||||||
|
// drawerProps={{
|
||||||
|
// destroyOnClose: true,
|
||||||
|
// }}
|
||||||
|
// onFinish={async (values) => {
|
||||||
|
// try {
|
||||||
|
// const { success, message: errMsg } =
|
||||||
|
// await productcontrollerUpdatestrength(
|
||||||
|
// { id: initialValues.id },
|
||||||
|
// values,
|
||||||
|
// );
|
||||||
|
// if (!success) {
|
||||||
|
// throw new Error(errMsg);
|
||||||
|
// }
|
||||||
|
// message.success('提交成功');
|
||||||
|
// tableRef.current?.reload();
|
||||||
|
// return true;
|
||||||
|
// } catch (error: any) {
|
||||||
|
// message.error(error.message);
|
||||||
|
// }
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <ProForm.Group>
|
||||||
|
// <ProFormText
|
||||||
|
// name="name"
|
||||||
|
// width="md"
|
||||||
|
// label="强度名称"
|
||||||
|
// placeholder="请输入名称"
|
||||||
|
// rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
// />
|
||||||
|
// </ProForm.Group>
|
||||||
|
// </DrawerForm>
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
export default List;
|
||||||
|
|
@ -0,0 +1,540 @@
|
||||||
|
import { PRODUCT_STATUS_ENUM } from '@/constants';
|
||||||
|
import {
|
||||||
|
productcontrollerProductbysku,
|
||||||
|
productcontrollerSearchproducts,
|
||||||
|
} from '@/servers/api/product';
|
||||||
|
import { sitecontrollerAll } from '@/servers/api/site';
|
||||||
|
import {
|
||||||
|
wpproductcontrollerGetwpproducts,
|
||||||
|
wpproductcontrollerSetconstitution,
|
||||||
|
wpproductcontrollerSyncproducts,
|
||||||
|
wpproductcontrollerUpdateproduct,
|
||||||
|
wpproductcontrollerUpdatevariation,
|
||||||
|
} from '@/servers/api/wpProduct';
|
||||||
|
import { EditOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormDigit,
|
||||||
|
ProFormList,
|
||||||
|
ProFormSelect,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Divider, Form } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const List: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<API.WpProductDTO>[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '站点',
|
||||||
|
dataIndex: 'siteId',
|
||||||
|
valueType: 'select',
|
||||||
|
request: async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'sku',
|
||||||
|
dataIndex: 'sku',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
valueType: 'select',
|
||||||
|
valueEnum: PRODUCT_STATUS_ENUM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '常规价格',
|
||||||
|
dataIndex: 'regular_price',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '销售价格',
|
||||||
|
dataIndex: 'sale_price',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '更新时间',
|
||||||
|
dataIndex: 'updatedAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
<UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
{record.type === 'simple' && record.sku ? (
|
||||||
|
<>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<SetComponent
|
||||||
|
tableRef={actionRef}
|
||||||
|
values={record}
|
||||||
|
isProduct={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const varColumns: ProColumns<API.VariationDTO>[] = [
|
||||||
|
{
|
||||||
|
title: '变体名',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'sku',
|
||||||
|
dataIndex: 'sku',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '常规价格',
|
||||||
|
dataIndex: 'regular_price',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '销售价格',
|
||||||
|
dataIndex: 'sale_price',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
<UpdateVaritation tableRef={actionRef} values={record} />
|
||||||
|
{record.sku ? (
|
||||||
|
<>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<SetComponent
|
||||||
|
tableRef={actionRef}
|
||||||
|
values={record}
|
||||||
|
isProduct={false}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer header={{ title: 'WP产品列表' }}>
|
||||||
|
<ProTable<API.WpProductDTO>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await wpproductcontrollerGetwpproducts(
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
toolBarRender={() => [<SyncForm tableRef={actionRef} />]}
|
||||||
|
expandable={{
|
||||||
|
rowExpandable: (record) => record.type === 'variable',
|
||||||
|
expandedRowRender: (record) => (
|
||||||
|
<ProTable<API.VariationDTO>
|
||||||
|
rowKey="id"
|
||||||
|
dataSource={record.variations}
|
||||||
|
pagination={false}
|
||||||
|
search={false}
|
||||||
|
options={false}
|
||||||
|
columns={varColumns}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SyncForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.wpproductcontrollerSyncproductsParams>
|
||||||
|
title="同步产品"
|
||||||
|
trigger={
|
||||||
|
<Button key="syncSite" type="primary">
|
||||||
|
同步产品
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await wpproductcontrollerSyncproducts(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('同步成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormSelect
|
||||||
|
name="siteId"
|
||||||
|
width="lg"
|
||||||
|
label="站点"
|
||||||
|
placeholder="请选择站点"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.WpProductDTO;
|
||||||
|
}> = ({ tableRef, values: initialValues }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdateProductDTO>
|
||||||
|
title="编辑产品"
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const { siteId, ...params } = values;
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await wpproductcontrollerUpdateproduct(
|
||||||
|
{
|
||||||
|
productId: initialValues.externalProductId,
|
||||||
|
siteId,
|
||||||
|
},
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText label="名称" width="lg" name="name" />
|
||||||
|
<ProFormSelect
|
||||||
|
width="lg"
|
||||||
|
label="站点"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
name="siteId"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="sku"
|
||||||
|
width="lg"
|
||||||
|
label="sku"
|
||||||
|
tooltip="Example: TO-ZY-06MG-WG-S-0001"
|
||||||
|
placeholder="请输入SKU"
|
||||||
|
/>
|
||||||
|
{initialValues.type === 'simple' ? (
|
||||||
|
<>
|
||||||
|
<ProFormDigit
|
||||||
|
name="regular_price"
|
||||||
|
width="lg"
|
||||||
|
label="常规价格"
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="sale_price"
|
||||||
|
width="lg"
|
||||||
|
label="促销价格"
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateVaritation: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.VariationDTO;
|
||||||
|
}> = ({ tableRef, values: initialValues }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdateProductDTO>
|
||||||
|
title="编辑变体"
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const { ...params } = values;
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await wpproductcontrollerUpdatevariation(
|
||||||
|
{
|
||||||
|
siteId: initialValues.siteId,
|
||||||
|
productId: initialValues.externalProductId,
|
||||||
|
variationId: initialValues.externalVariationId,
|
||||||
|
},
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText label="变体名称" width="lg" name="name" />
|
||||||
|
<ProFormText
|
||||||
|
name="sku"
|
||||||
|
width="lg"
|
||||||
|
label="sku"
|
||||||
|
tooltip="Example: TO-ZY-06MG-WG-S-0001"
|
||||||
|
placeholder="请输入SKU"
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="regular_price"
|
||||||
|
width="lg"
|
||||||
|
label="常规价格"
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="sale_price"
|
||||||
|
width="lg"
|
||||||
|
label="促销价格"
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SetComponent: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.VariationDTO | API.WpProductDTO;
|
||||||
|
isProduct: boolean;
|
||||||
|
}> = ({ tableRef, values: { id, constitution, name }, isProduct = false }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
const fetchInitialValues = async () => {
|
||||||
|
const initData = await Promise.all(
|
||||||
|
constitution?.map?.(async (item) => {
|
||||||
|
const { data } = await productcontrollerProductbysku({
|
||||||
|
sku: item.sku as string,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
quantity: item.quantity,
|
||||||
|
sku: {
|
||||||
|
label: data?.name,
|
||||||
|
value: item.sku,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}) || [],
|
||||||
|
);
|
||||||
|
form.setFieldsValue({
|
||||||
|
constitution: initData,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.SetConstitutionDTO>
|
||||||
|
title={name}
|
||||||
|
form={form}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary" danger={constitution?.length === 0}>
|
||||||
|
<EditOutlined />
|
||||||
|
构成
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async ({ constitution }) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await wpproductcontrollerSetconstitution(
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isProduct,
|
||||||
|
constitution,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onOpenChange={(visiable) => {
|
||||||
|
if (visiable) fetchInitialValues();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormList<{
|
||||||
|
sku: string;
|
||||||
|
quantity: number;
|
||||||
|
}>
|
||||||
|
name="constitution"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增' }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
const arr =
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || [];
|
||||||
|
return arr;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="sku"
|
||||||
|
label="产品"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
filterOption: false,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button type="link" danger onClick={() => remove(fields.key)}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default List;
|
||||||
|
|
@ -0,0 +1,236 @@
|
||||||
|
import { statisticscontrollerGetcustomerorders } from '@/servers/api/statistics';
|
||||||
|
import {
|
||||||
|
PageContainer,
|
||||||
|
ProDescriptions,
|
||||||
|
ProForm,
|
||||||
|
ProFormDateMonthRangePicker,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { Space } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const [month, setMonth] = useState('');
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<Space direction="vertical" size={30}>
|
||||||
|
<ProForm
|
||||||
|
layout="inline"
|
||||||
|
onFinish={async (values) => {
|
||||||
|
setMonth(values.month);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormDateMonthRangePicker label="日期" name="month" />
|
||||||
|
</ProForm>
|
||||||
|
<ProDescriptions
|
||||||
|
params={{ month }}
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } =
|
||||||
|
await statisticscontrollerGetcustomerorders(params);
|
||||||
|
return { data };
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProDescriptions.Item label="总用户数" dataIndex="users" />
|
||||||
|
<ProDescriptions.Item label="3MG订单数" dataIndex="order_with_3mg" />
|
||||||
|
<ProDescriptions.Item label="6MG订单数" dataIndex="order_with_6mg" />
|
||||||
|
<ProDescriptions.Item label="9MG订单数" dataIndex="order_with_9mg" />
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="12MG订单数"
|
||||||
|
dataIndex="order_with_12mg"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="15MG订单数"
|
||||||
|
dataIndex="order_with_15mg"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN3MG订单数"
|
||||||
|
dataIndex="zyn_3mg_orders"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN6MG订单数"
|
||||||
|
dataIndex="zyn_6mg_orders"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZOLT订单数"
|
||||||
|
dataIndex="zolt_15mg_orders"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="一购用户数"
|
||||||
|
dataIndex="users_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="二购用户数"
|
||||||
|
dataIndex="users_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="三购用户数"
|
||||||
|
dataIndex="users_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE一购用户数"
|
||||||
|
dataIndex="users_with_yoone_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE二购用户数"
|
||||||
|
dataIndex="users_with_yoone_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE三购用户数"
|
||||||
|
dataIndex="users_with_yoone_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 3MG一购用户数"
|
||||||
|
dataIndex="users_with_yoone_3mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 3MG二购用户数"
|
||||||
|
dataIndex="users_with_yoone_3mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOON 3MG三购用户数"
|
||||||
|
dataIndex="users_with_yoone_3mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 6MG一购用户数"
|
||||||
|
dataIndex="users_with_yoone_6mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 6MG二购用户数"
|
||||||
|
dataIndex="users_with_yoone_6mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOON 6MG三购用户数"
|
||||||
|
dataIndex="users_with_yoone_6mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 9MG一购用户数"
|
||||||
|
dataIndex="users_with_yoone_9mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 9MG二购用户数"
|
||||||
|
dataIndex="users_with_yoone_9mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOON 9MG三购用户数"
|
||||||
|
dataIndex="users_with_yoone_9mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 12MG一购用户数"
|
||||||
|
dataIndex="users_with_yoone_12mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 12MG二购用户数"
|
||||||
|
dataIndex="users_with_yoone_12mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOON 12MG三购用户数"
|
||||||
|
dataIndex="users_with_yoone_12mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 15MG一购用户数"
|
||||||
|
dataIndex="users_with_yoone_15mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOONE 15MG二购用户数"
|
||||||
|
dataIndex="users_with_yoone_15mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="YOON 15MG三购用户数"
|
||||||
|
dataIndex="users_with_yoone_15mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN一购用户数"
|
||||||
|
dataIndex="users_with_zyn_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN二购用户数"
|
||||||
|
dataIndex="users_with_zyn_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN三购用户数"
|
||||||
|
dataIndex="users_with_zyn_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN 3MG一购用户数"
|
||||||
|
dataIndex="users_with_zyn_3mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN 3MG二购用户数"
|
||||||
|
dataIndex="users_with_zyn_3mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN 3MG三购用户数"
|
||||||
|
dataIndex="users_with_zyn_3mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN 6G一购用户数"
|
||||||
|
dataIndex="users_with_zyn_6mg_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN 6G二购用户数"
|
||||||
|
dataIndex="users_with_zyn_6mg_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZYN 6G三购用户数"
|
||||||
|
dataIndex="users_with_zyn_6mg_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZOLT一购用户数"
|
||||||
|
dataIndex="users_with_zolt_one_purchase"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZOLT二购用户数"
|
||||||
|
dataIndex="users_with_zolt_two_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="ZOLT三购用户数"
|
||||||
|
dataIndex="users_with_zolt_three_purchases"
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="一购产品"
|
||||||
|
render={(_, record) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{record?.first_hot_purchase?.map((v) => (
|
||||||
|
<div>
|
||||||
|
产品名称:{v.name} 用户数:{v.user_count}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="二购产品"
|
||||||
|
render={(_, record) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{record?.second_hot_purchase?.map((v) => (
|
||||||
|
<div>
|
||||||
|
产品名称:{v.name} 用户数:{v.user_count}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProDescriptions.Item
|
||||||
|
label="三购产品"
|
||||||
|
render={(_, record) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{record?.third_hot_purchase?.map((v) => (
|
||||||
|
<div>
|
||||||
|
产品名称:{v.name} 用户数:{v.user_count}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ProDescriptions>
|
||||||
|
</Space>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
import { statisticscontrollerStockforecast } from '@/servers/api/statistics';
|
||||||
|
import { stockcontrollerGetallstockpoints } from '@/servers/api/stock';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProFormDatePicker,
|
||||||
|
ProFormDigit,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [points, setPoints] = useState<API.StockPoint[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
stockcontrollerGetallstockpoints().then(({ data }) => {
|
||||||
|
setPoints(data as API.StockPoint[]);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [real, setReal] = useState({});
|
||||||
|
|
||||||
|
const columns: ProColumns[] = [
|
||||||
|
{
|
||||||
|
title: '产品名称',
|
||||||
|
dataIndex: 'productName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'SKU',
|
||||||
|
dataIndex: 'productSku',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
...points
|
||||||
|
?.filter((point: API.StockPoint) => !point.ignore)
|
||||||
|
?.map((point: API.StockPoint) => ({
|
||||||
|
title: point.name,
|
||||||
|
dataIndex: `point_${point.name}`,
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_: any, record: any) {
|
||||||
|
const quantity = record.stockDetails?.find(
|
||||||
|
(item: any) => item.id === point.id,
|
||||||
|
)?.quantity;
|
||||||
|
return quantity || 0;
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{
|
||||||
|
title: '途中库存',
|
||||||
|
dataIndex: 'transitStock',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '加拿大库存',
|
||||||
|
dataIndex: 'caTotalStock',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (!record.caTotalStock || record.caTotalStock > 400) {
|
||||||
|
return record.caTotalStock;
|
||||||
|
}
|
||||||
|
return <span style={{ color: 'red' }}>{record.caTotalStock}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '总库存',
|
||||||
|
dataIndex: 'totalStock',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '30天',
|
||||||
|
dataIndex: 'totalSales_30',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '2*15天',
|
||||||
|
dataIndex: 'totalSales_15',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '补货数量',
|
||||||
|
dataIndex: 'restockQuantity',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '实补数量',
|
||||||
|
dataIndex: 'restockQuantityReal',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return (
|
||||||
|
<ProFormDigit
|
||||||
|
key={record.productSku}
|
||||||
|
initialValue={0}
|
||||||
|
fieldProps={{
|
||||||
|
onChange(value) {
|
||||||
|
setReal({
|
||||||
|
...real,
|
||||||
|
[record.productSku]: value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'B端实补数量',
|
||||||
|
dataIndex: 'restockQuantityReal',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return <ProFormDigit key={'b_' + record.productSku} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '加拿大剩余天数',
|
||||||
|
dataIndex: 'caAvailableDays',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (!record.caAvailableDays || record.caAvailableDays > 40) {
|
||||||
|
return record.caAvailableDays;
|
||||||
|
}
|
||||||
|
return <span style={{ color: 'red' }}>{record.caAvailableDays}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '剩余天数',
|
||||||
|
dataIndex: 'availableDays',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (!record.availableDays || record.availableDays > 70) {
|
||||||
|
return record.availableDays;
|
||||||
|
}
|
||||||
|
return <span style={{ color: 'red' }}>{record.availableDays}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '实补后剩余天数',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (!record.availableDays) return '-';
|
||||||
|
const availableDays = Number(record.availableDays);
|
||||||
|
const quantity = real?.[record.productSku] || 0;
|
||||||
|
const day =
|
||||||
|
availableDays +
|
||||||
|
Math.floor(
|
||||||
|
quantity /
|
||||||
|
(Math.max(record.totalSales_30, record.totalSales_15) / 30),
|
||||||
|
);
|
||||||
|
return day;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '实补后日期',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (!record.availableDays) return '-';
|
||||||
|
const availableDays = Number(record.availableDays);
|
||||||
|
const quantity = real?.[record.productSku] || 0;
|
||||||
|
const day =
|
||||||
|
availableDays +
|
||||||
|
Math.floor(
|
||||||
|
quantity /
|
||||||
|
(Math.max(record.totalSales_30, record.totalSales_15) / 30),
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<ProFormDatePicker
|
||||||
|
readonly
|
||||||
|
fieldProps={{ value: dayjs().add(day, 'd') }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
// tableStyle={{ height: '80vh', overflow: 'auto' }}
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (param) => {
|
||||||
|
const { data, success } = await statisticscontrollerStockforecast(
|
||||||
|
param,
|
||||||
|
);
|
||||||
|
if (success) {
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
dateFormatter="number"
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,887 @@
|
||||||
|
import { ORDER_STATUS_ENUM } from '@/constants';
|
||||||
|
import { sitecontrollerAll } from '@/servers/api/site';
|
||||||
|
import {
|
||||||
|
statisticscontrollerGetorderbydate,
|
||||||
|
statisticscontrollerGetorderbyemail,
|
||||||
|
statisticscontrollerGetorderstatistics,
|
||||||
|
} from '@/servers/api/statistics';
|
||||||
|
import { formatSource } from '@/utils/format';
|
||||||
|
import {
|
||||||
|
ModalForm,
|
||||||
|
PageContainer,
|
||||||
|
ProForm,
|
||||||
|
ProFormDateRangePicker,
|
||||||
|
ProFormSelect,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import ReactECharts from 'echarts-for-react';
|
||||||
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
const highlightText = (text: string, keyword: string) => {
|
||||||
|
if (!keyword) return text;
|
||||||
|
const parts = text.split(new RegExp(`(${keyword})`, 'gi'));
|
||||||
|
return parts.map((part, index) =>
|
||||||
|
part.toLowerCase() === keyword.toLowerCase() ? (
|
||||||
|
<span key={index} style={{ color: 'red', fontWeight: 'bold' }}>
|
||||||
|
{part}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
part
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const [xAxis, setXAxis] = useState([]);
|
||||||
|
const [series, setSeries] = useState<any[]>([]);
|
||||||
|
const [selectedDate, setSelectedDate] = useState(null);
|
||||||
|
|
||||||
|
const option = useMemo(
|
||||||
|
() => ({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: function (params) {
|
||||||
|
const items = params.map((item) => {
|
||||||
|
return `<span style="display: inline-block;width: 250px">${item.marker} ${item.seriesName}: ${item.value}</span>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 每4个一行
|
||||||
|
const rows = [];
|
||||||
|
for (let i = 0; i < items.length; i += 4) {
|
||||||
|
rows.push(items.slice(i, i + 4).join(''));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows.join('<br/>');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['订单数', '总金额', '平均金额', '盒数'],
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: xAxis,
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '订单数',
|
||||||
|
position: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '总金额',
|
||||||
|
position: 'right',
|
||||||
|
offset: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '平均金额',
|
||||||
|
position: 'right',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '盒数',
|
||||||
|
position: 'left',
|
||||||
|
offset: 60,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series,
|
||||||
|
}),
|
||||||
|
[xAxis, series],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProForm
|
||||||
|
layout="inline"
|
||||||
|
onFinish={async (values) => {
|
||||||
|
setXAxis([]);
|
||||||
|
setSeries([]);
|
||||||
|
setSelectedDate(null);
|
||||||
|
// setKeyword(values?.keyword || '');
|
||||||
|
const { date, ...params } = values;
|
||||||
|
const [startDate, endDate] = date;
|
||||||
|
const { data, success } =
|
||||||
|
await statisticscontrollerGetorderstatistics({
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
if (success) {
|
||||||
|
const res = data?.sort(() => -1);
|
||||||
|
setXAxis(res?.map((v) => dayjs(v.order_date).format('YYYY-MM-DD')));
|
||||||
|
setSeries([
|
||||||
|
{
|
||||||
|
name: '首购订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.first_purchase_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '首购金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.first_purchase_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '复购订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.repeat_purchase_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '复购金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.repeat_purchase_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TOGO CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.togo_cpc_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TOGO 非CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.non_togo_cpc_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CAN CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.can_cpc_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CAN 非CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.non_can_cpc_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.cpc_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.zyn_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.yoone_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.zex_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.cpc_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.zyn_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.zex_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '非CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.non_cpc_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN 非CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.non_zyn_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 非CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.non_yoone_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX 非CPC订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.non_zex_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '非CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.non_cpc_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN 非CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.non_zyn_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 非CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.non_yoone_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX 非CPC金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.non_zex_total),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.zyn_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.zyn_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_zyn_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZYN 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_zyn_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE套装金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_G_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE套装盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_G_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE套装CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_G_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE套装非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_G_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE单盒金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_S_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE单盒盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_S_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE单盒CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_S_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE单盒非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_S_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 3MG 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_3_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 3MG 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_3_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 3MG CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_3_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 3MG 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_3_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 6MG 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_6_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 6MG 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_6_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 6MG CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_6_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 6MG 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_6_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 9MG 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_9_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 9MG 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_9_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 9MG CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_9_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 9MG 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_9_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 12MG 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_12_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 12MG 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_12_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 12MG CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_12_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 12MG 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_12_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 15MG 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.yoone_15_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 15MG 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.yoone_15_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 15MG CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_yoone_15_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'YOONE 15MG 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_yoone_15_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX 盒数金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.zex_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX 盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.zex_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.cpc_zex_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ZEX 非CPC盒数',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 3,
|
||||||
|
data: res?.map((v) => v.non_cpc_zex_quantity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.total_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TOGO订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.togo_total_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CAN订单数',
|
||||||
|
type: 'line',
|
||||||
|
data: res?.map((v) => v.can_total_orders),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '总金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.total_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TOGO总金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.togo_total_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CAN总金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: res?.map((v) => v.can_total_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '平均金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 2,
|
||||||
|
data: res?.map((v) => v.avg_total_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TOGO平均金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 2,
|
||||||
|
data: res?.map((v) => v.avg_togo_total_amount),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CAN平均金额',
|
||||||
|
type: 'line',
|
||||||
|
yAxisIndex: 2,
|
||||||
|
data: res?.map((v) => v.avg_can_total_amount),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormDateRangePicker
|
||||||
|
label="日期"
|
||||||
|
rules={[{ required: true, message: '请选择日期' }]}
|
||||||
|
name="date"
|
||||||
|
/>
|
||||||
|
{/* <ProFormText label="关键词" name="keyword" /> */}
|
||||||
|
<ProFormSelect
|
||||||
|
label="站点"
|
||||||
|
name="siteId"
|
||||||
|
request={async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* <ProFormSelect
|
||||||
|
label="类型"
|
||||||
|
name="purchaseType"
|
||||||
|
valueEnum={{
|
||||||
|
first_purchase: '首购',
|
||||||
|
repeat_purchase: '复购',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
label="来源"
|
||||||
|
name="orderType"
|
||||||
|
valueEnum={{
|
||||||
|
cpc: '广告',
|
||||||
|
non_cpc: '非广告',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
label="品牌"
|
||||||
|
name="brand"
|
||||||
|
valueEnum={{
|
||||||
|
zyn: 'ZYN',
|
||||||
|
zex: 'ZEX',
|
||||||
|
yoone: 'YOONE',
|
||||||
|
}}
|
||||||
|
/> */}
|
||||||
|
</ProForm>
|
||||||
|
{series?.length ? (
|
||||||
|
<ReactECharts
|
||||||
|
style={{ height: 450 }}
|
||||||
|
option={option}
|
||||||
|
onEvents={{
|
||||||
|
click: (params) => {
|
||||||
|
if (params.componentType === 'series') {
|
||||||
|
setSelectedDate(params.name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
<DailyOrders selectedDate={selectedDate} />
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DailyOrders: React.FC<{
|
||||||
|
selectedDate;
|
||||||
|
}> = ({ selectedDate }) => {
|
||||||
|
const [orders, setOrders] = useState([]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!selectedDate) {
|
||||||
|
setOrders([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statisticscontrollerGetorderbydate({
|
||||||
|
date: selectedDate,
|
||||||
|
}).then(({ data, success }) => {
|
||||||
|
if (success) {
|
||||||
|
setOrders(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [selectedDate]);
|
||||||
|
|
||||||
|
const handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
// 获取排序字段和排序方式
|
||||||
|
const { field, order } = sorter || {};
|
||||||
|
|
||||||
|
if (field && order) {
|
||||||
|
const sortedData = [...orders].sort((a, b) => {
|
||||||
|
if (['total', 'order_count', 'total_spent'].includes(field)) {
|
||||||
|
const valA = Number(a[field]);
|
||||||
|
const valB = Number(b[field]);
|
||||||
|
if (isNaN(valA)) return 1;
|
||||||
|
if (isNaN(valB)) return -1;
|
||||||
|
if (order === 'ascend') {
|
||||||
|
return valA - valB;
|
||||||
|
}
|
||||||
|
return valB - valA;
|
||||||
|
}
|
||||||
|
if (order === 'ascend') {
|
||||||
|
return a[field] > b[field] ? 1 : -1;
|
||||||
|
}
|
||||||
|
return a[field] < b[field] ? 1 : -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
setOrders(sortedData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!selectedDate) return <></>;
|
||||||
|
return (
|
||||||
|
<ProTable
|
||||||
|
search={false}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '订单号',
|
||||||
|
dataIndex: 'externalOrderId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '客户邮箱',
|
||||||
|
dataIndex: 'customer_email',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '站点',
|
||||||
|
dataIndex: 'siteId',
|
||||||
|
valueType: 'select',
|
||||||
|
request: async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '首单时间',
|
||||||
|
dataIndex: 'first_purchase_date',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '支付时间',
|
||||||
|
dataIndex: 'date_paid',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单金额',
|
||||||
|
dataIndex: 'total',
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '总订单数',
|
||||||
|
dataIndex: 'order_count',
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '总订单金额',
|
||||||
|
dataIndex: 'total_spent',
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单类型',
|
||||||
|
dataIndex: 'purchase_type',
|
||||||
|
sorter: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
if (record.purchase_type === 'first_purchase') return '首单';
|
||||||
|
return '复购单';
|
||||||
|
},
|
||||||
|
filters: [
|
||||||
|
{ text: '首单', value: 'first_purchase' },
|
||||||
|
{ text: '复购单', value: 'repeat_purchase' },
|
||||||
|
],
|
||||||
|
onFilter: (value, record) => {
|
||||||
|
return record.purchase_type === value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'orderStatus',
|
||||||
|
hideInSearch: true,
|
||||||
|
valueType: 'select',
|
||||||
|
valueEnum: ORDER_STATUS_ENUM,
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '来源',
|
||||||
|
hideInSearch: true,
|
||||||
|
sorter: true,
|
||||||
|
render: (_, record) =>
|
||||||
|
formatSource(record.source_type, record.utm_source),
|
||||||
|
filters: [
|
||||||
|
{ text: 'google广告', value: 'source' },
|
||||||
|
{ text: 'google搜索', value: 'organic' },
|
||||||
|
{ text: '直达', value: 'direct' },
|
||||||
|
{ text: '其他', value: 'other' },
|
||||||
|
],
|
||||||
|
onFilter: (value, record) => {
|
||||||
|
if (value === 'source') {
|
||||||
|
return (
|
||||||
|
record.source_type === 'utm' && record.utm_source === 'google'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (value === 'organic') {
|
||||||
|
return (
|
||||||
|
record.source_type === 'organic' &&
|
||||||
|
record.utm_source === 'google'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (value === 'direct') {
|
||||||
|
return record.source_type === 'typein';
|
||||||
|
}
|
||||||
|
if (value === '其他') {
|
||||||
|
return !['utm', 'organic', 'typein'].includes(record.source_type);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单内容',
|
||||||
|
dataIndex: 'orderItems',
|
||||||
|
render: (_, record) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{record.orderItems?.map((item) => (
|
||||||
|
// <div>{highlightText(item.name, keyword)}</div>
|
||||||
|
<div>{item.name}</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
filters: [
|
||||||
|
{ text: 'ZYN', value: 'zyn' },
|
||||||
|
{ text: 'YOONE', value: 'yoone' },
|
||||||
|
{ text: 'ZEX', value: 'zex' },
|
||||||
|
],
|
||||||
|
onFilter: (value, record) => {
|
||||||
|
return record.orderItems?.some((v) =>
|
||||||
|
v?.name?.toLowerCase().includes(value),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => {
|
||||||
|
return <HistoryOrder email={record.customer_email} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={orders}
|
||||||
|
onChange={handleTableChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const HistoryOrder: React.FC<{
|
||||||
|
email: string;
|
||||||
|
}> = ({ email }) => {
|
||||||
|
return (
|
||||||
|
<ModalForm
|
||||||
|
title={`历史订单${email}`}
|
||||||
|
trigger={<Button type="primary">历史订单</Button>}
|
||||||
|
modalProps={{ destroyOnClose: true, footer: null }}
|
||||||
|
width="80vw"
|
||||||
|
>
|
||||||
|
<ProTable
|
||||||
|
search={false}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '订单号',
|
||||||
|
dataIndex: 'externalOrderId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '客户邮箱',
|
||||||
|
dataIndex: 'customer_email',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '站点',
|
||||||
|
dataIndex: 'siteId',
|
||||||
|
valueType: 'select',
|
||||||
|
request: async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '支付时间',
|
||||||
|
dataIndex: 'date_paid',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单金额',
|
||||||
|
dataIndex: 'total',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'orderStatus',
|
||||||
|
hideInSearch: true,
|
||||||
|
valueType: 'select',
|
||||||
|
valueEnum: ORDER_STATUS_ENUM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '来源',
|
||||||
|
hideInSearch: true,
|
||||||
|
render: (_, record) =>
|
||||||
|
formatSource(record.source_type, record.utm_source),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单内容',
|
||||||
|
dataIndex: 'orderItems',
|
||||||
|
render: (_, record) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{record.orderItems?.map((item) => (
|
||||||
|
<div>
|
||||||
|
${item.total} : {item.name} * {item.quantity}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
request={async () => {
|
||||||
|
const { data, success } = await statisticscontrollerGetorderbyemail({
|
||||||
|
email,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ModalForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
import { statisticscontrollerRestocking } from '@/servers/api/statistics';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProFormDigit,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [count, setCount] = useState(4);
|
||||||
|
const history = useMemo(
|
||||||
|
() =>
|
||||||
|
Array.from({ length: Math.min(!!count ? count : 5, 10) }).map((_, i) => {
|
||||||
|
if (dayjs().date() > 20) i++;
|
||||||
|
return dayjs().add(i, 'month').format('YYYY-MM');
|
||||||
|
}),
|
||||||
|
[count],
|
||||||
|
);
|
||||||
|
|
||||||
|
const [savety, setSavety] = useState({});
|
||||||
|
|
||||||
|
const columns: ProColumns[] = [
|
||||||
|
{
|
||||||
|
title: '产品名称',
|
||||||
|
dataIndex: 'productName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '30天销量',
|
||||||
|
dataIndex: 'last30DaysSales',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '2*15天销量',
|
||||||
|
dataIndex: 'last15DaysSales',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return 2 * record.last15DaysSales;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '库存',
|
||||||
|
dataIndex: 'totalStock',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
...history.map((v, i) => ({
|
||||||
|
title: v,
|
||||||
|
onCell: () => ({ style: { padding: 0 } }),
|
||||||
|
align: 'center' as any,
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
const base = record.lastMonthSales;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
position: 'absolute',
|
||||||
|
justifyContent: 'center',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ position: 'absolute', zIndex: 99 }}>
|
||||||
|
<div>{base}</div>
|
||||||
|
<div>{base}</div>
|
||||||
|
<div>{base}</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: 1,
|
||||||
|
width:
|
||||||
|
Math.max(Math.min(record.totalStock / base - i, 1), 0) * 100 +
|
||||||
|
'%',
|
||||||
|
height: '100%',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
backgroundColor: 'red',
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{
|
||||||
|
title: '安全补充系数',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return (
|
||||||
|
<ProFormDigit
|
||||||
|
key={record.productSku}
|
||||||
|
width={100}
|
||||||
|
fieldProps={{
|
||||||
|
defaultValue: 0,
|
||||||
|
onChange(value) {
|
||||||
|
setSavety({
|
||||||
|
...savety,
|
||||||
|
[record.productSku]: value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
const base = record.lastMonthSales;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{count * base}</div>
|
||||||
|
<div>{2 * count * base}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '合计',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
const base = record.lastMonthSales;
|
||||||
|
return 3 * count * base + (savety[record.productSku] || 0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '修正数',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
const base = record.lastMonthSales;
|
||||||
|
return (
|
||||||
|
<ProFormDigit
|
||||||
|
key={'fix' + record.productSku + (savety[record.productSku] || 0)}
|
||||||
|
width={100}
|
||||||
|
fieldProps={{
|
||||||
|
defaultValue: 3 * count * base + (savety[record.productSku] || 0),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (param) => {
|
||||||
|
const { data, success } = await statisticscontrollerRestocking(param);
|
||||||
|
if (success) {
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
dateFormatter="number"
|
||||||
|
toolBarRender={() => [
|
||||||
|
<ProFormText
|
||||||
|
key="count"
|
||||||
|
width="100px"
|
||||||
|
fieldProps={{
|
||||||
|
onChange: (e) => setCount(e.target.value),
|
||||||
|
value: count,
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,185 @@
|
||||||
|
import { ordercontrollerGetordersales } from '@/servers/api/order';
|
||||||
|
import { sitecontrollerAll } from '@/servers/api/site';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProFormSwitch,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [total, setTotal] = useState(0);
|
||||||
|
const [isSource, setIsSource] = useState(false);
|
||||||
|
const [yooneTotal, setYooneTotal] = useState({});
|
||||||
|
|
||||||
|
const columns: ProColumns<API.OrderSaleDTO>[] = [
|
||||||
|
{
|
||||||
|
title: '时间段',
|
||||||
|
dataIndex: 'dateRange',
|
||||||
|
valueType: 'dateTimeRange',
|
||||||
|
hideInTable: true,
|
||||||
|
formItemProps: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择时间段',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '站点',
|
||||||
|
dataIndex: 'siteId',
|
||||||
|
valueType: 'select',
|
||||||
|
request: async () => {
|
||||||
|
const { data = [] } = await sitecontrollerAll();
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.siteName,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
hideInTable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '分类',
|
||||||
|
dataIndex: 'categoryName',
|
||||||
|
hideInSearch: true,
|
||||||
|
hideInTable: isSource,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '数量',
|
||||||
|
dataIndex: 'totalQuantity',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '一单订单数',
|
||||||
|
dataIndex: 'firstOrderCount',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (isSource) return record.firstOrderCount;
|
||||||
|
return `${record.firstOrderCount}(${record.firstOrderYOONEBoxCount})`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '两单订单数',
|
||||||
|
dataIndex: 'secondOrderCount',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (isSource) return record.secondOrderCount;
|
||||||
|
return `${record.secondOrderCount}(${record.secondOrderYOONEBoxCount})`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三单订单数',
|
||||||
|
dataIndex: 'thirdOrderCount',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (isSource) return record.thirdOrderCount;
|
||||||
|
return `${record.thirdOrderCount}(${record.thirdOrderYOONEBoxCount})`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三单以上订单数',
|
||||||
|
dataIndex: 'moreThirdOrderCount',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (isSource) return record.moreThirdOrderCount;
|
||||||
|
return `${record.moreThirdOrderCount}(${record.moreThirdOrderYOONEBoxCount})`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订单数',
|
||||||
|
dataIndex: 'totalOrders',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
params={{ isSource }}
|
||||||
|
form={{
|
||||||
|
// ignoreRules: false,
|
||||||
|
initialValues: {
|
||||||
|
dateRange: [dayjs().startOf('month'), dayjs().endOf('month')],
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
request={async ({ dateRange, ...param }) => {
|
||||||
|
const [startDate, endDate] = dateRange.values();
|
||||||
|
const { data, success } = await ordercontrollerGetordersales({
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
...param,
|
||||||
|
});
|
||||||
|
if (success) {
|
||||||
|
setTotal(data?.totalQuantity || 0);
|
||||||
|
setYooneTotal({
|
||||||
|
yoone3Quantity: data?.yoone3Quantity || 0,
|
||||||
|
yoone6Quantity: data?.yoone6Quantity || 0,
|
||||||
|
yoone9Quantity: data?.yoone9Quantity || 0,
|
||||||
|
yoone12Quantity: data?.yoone12Quantity || 0,
|
||||||
|
yoone15Quantity: data?.yoone15Quantity || 0,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
setTotal(0);
|
||||||
|
setYooneTotal({});
|
||||||
|
return {
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
dateFormatter="number"
|
||||||
|
footer={() => `总计: ${total}`}
|
||||||
|
toolBarRender={() => [
|
||||||
|
<ProFormSwitch
|
||||||
|
label="原产品"
|
||||||
|
fieldProps={{
|
||||||
|
value: isSource,
|
||||||
|
onChange: () => setIsSource(!isSource),
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: '#fff',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
padding: '10px',
|
||||||
|
marginTop: '20px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
YOONE:{' '}
|
||||||
|
{(yooneTotal.yoone3Quantity || 0) +
|
||||||
|
(yooneTotal.yoone6Quantity || 0) +
|
||||||
|
(yooneTotal.yoone9Quantity || 0) +
|
||||||
|
(yooneTotal.yoone12Quantity || 0) +
|
||||||
|
(yooneTotal.yoone15Quantity || 0)}
|
||||||
|
</div>
|
||||||
|
<div>YOONE 3MG: {yooneTotal.yoone3Quantity || 0}</div>
|
||||||
|
<div>YOONE 6MG: {yooneTotal.yoone6Quantity || 0}</div>
|
||||||
|
<div>YOONE 9MG: {yooneTotal.yoone9Quantity || 0}</div>
|
||||||
|
<div>YOONE 12MG: {yooneTotal.yoone12Quantity || 0}</div>
|
||||||
|
<div>YOONE 15MG: {yooneTotal.yoone15Quantity || 0}</div>
|
||||||
|
</div>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
import {
|
||||||
|
stockcontrollerGetallstockpoints,
|
||||||
|
stockcontrollerGetstocks,
|
||||||
|
} from '@/servers/api/stock';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App } from 'antd';
|
||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [points, setPoints] = useState<API.StockPoint[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
stockcontrollerGetallstockpoints().then(({ data }) => {
|
||||||
|
setPoints(data as API.StockPoint[]);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
const columns: ProColumns<API.StockDTO>[] = [
|
||||||
|
{
|
||||||
|
title: '产品名称',
|
||||||
|
dataIndex: 'productName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'SKU',
|
||||||
|
dataIndex: 'productSku',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
...points?.map((point: API.StockPoint) => ({
|
||||||
|
title: point.name,
|
||||||
|
dataIndex: `point_${point.name}`,
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_: any, record: API.StockDTO) {
|
||||||
|
const quantity = record.stockPoint?.find(
|
||||||
|
(item) => item.id === point.id,
|
||||||
|
)?.quantity;
|
||||||
|
return quantity || 0;
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{
|
||||||
|
title: '运输中',
|
||||||
|
dataIndex: 'inTransitQuantity',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: '更新时间',
|
||||||
|
// dataIndex: 'updatedAt',
|
||||||
|
// valueType: 'dateTime',
|
||||||
|
// hideInSearch: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: '创建时间',
|
||||||
|
// dataIndex: 'createdAt',
|
||||||
|
// valueType: 'dateTime',
|
||||||
|
// hideInSearch: true,
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable<API.StockDTO>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await stockcontrollerGetstocks(params);
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
// toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,682 @@
|
||||||
|
import { Purchase_Order_STATUS_ENUM } from '@/constants';
|
||||||
|
import { productcontrollerSearchproducts } from '@/servers/api/product';
|
||||||
|
import {
|
||||||
|
stockcontrollerCreatepurchaseorder,
|
||||||
|
stockcontrollerDelpurchaseorder,
|
||||||
|
stockcontrollerGetallstockpoints,
|
||||||
|
stockcontrollerGetpurchaseorders,
|
||||||
|
stockcontrollerReceivepurchaseorder,
|
||||||
|
stockcontrollerUpdatepurchaseorder,
|
||||||
|
} from '@/servers/api/stock';
|
||||||
|
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormDatePicker,
|
||||||
|
ProFormDependency,
|
||||||
|
ProFormDigit,
|
||||||
|
ProFormList,
|
||||||
|
ProFormSelect,
|
||||||
|
ProFormText,
|
||||||
|
ProFormTextArea,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Divider, Form, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const PurchaseOrderPage: React.FC = () => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<API.PurchaseOrderDTO>[] = [
|
||||||
|
{
|
||||||
|
title: '订单编号',
|
||||||
|
dataIndex: 'orderNumber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '仓库',
|
||||||
|
dataIndex: 'stockPointName',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
valueType: 'select',
|
||||||
|
valueEnum: Purchase_Order_STATUS_ENUM,
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '预计到货时间',
|
||||||
|
dataIndex: 'expectedArrivalTime',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '数量',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return record.items.reduce((cur, next) => {
|
||||||
|
return cur + next.quantity;
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'note',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '更新时间',
|
||||||
|
dataIndex: 'updatedAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
{record.status !== 'received' && (
|
||||||
|
<UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
)}
|
||||||
|
{record.status === 'draft' ? (
|
||||||
|
<>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerDelpurchaseorder({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
) : record.status === 'submitted' ? (
|
||||||
|
<>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="入库"
|
||||||
|
description="确认已到达?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerReceivepurchaseorder({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary">入库</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<DetailForm tableRef={actionRef} values={record} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable<API.PurchaseOrderDTO>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await stockcontrollerGetpurchaseorders(
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.CreatePurchaseOrderDTO>
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
form={form}
|
||||||
|
autoFocusFirstInput
|
||||||
|
layout="vertical"
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerCreatepurchaseorder(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="stockPointId"
|
||||||
|
label="仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name={'status'}
|
||||||
|
label="状态"
|
||||||
|
placeholder={'请选择状态'}
|
||||||
|
valueEnum={Purchase_Order_STATUS_ENUM}
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请选择状态' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea label="备注" name="note" width={'lg'} />
|
||||||
|
<ProFormDatePicker
|
||||||
|
name="expectedArrivalTime"
|
||||||
|
label="预计到货时间"
|
||||||
|
placeholder={'请选择预计到货时间'}
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请选择预计到货时间' }]}
|
||||||
|
/>
|
||||||
|
<ProFormDependency name={['items']}>
|
||||||
|
{({ items }) => {
|
||||||
|
return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0);
|
||||||
|
}}
|
||||||
|
</ProFormDependency>
|
||||||
|
<ProFormList<API.PurchaseOrderItem>
|
||||||
|
name="items"
|
||||||
|
label="产品"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增', size: 'large' }}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="productSku"
|
||||||
|
label={'产品' + (idx + 1)}
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
filterOption: false,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
onChange={(_, option) => {
|
||||||
|
form.setFieldValue(
|
||||||
|
['items', fields.key, 'productName'],
|
||||||
|
option.title,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormText name={'productName'} label="产品名称" hidden={true} />
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="price"
|
||||||
|
label="价格"
|
||||||
|
placeholder="请输入价格"
|
||||||
|
rules={[{ required: true, message: '请输入价格' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button type="link" danger onClick={() => remove(fields.key)}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.UpdatePurchaseOrderDTO & {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
}> = ({ tableRef, values }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const initialValues = {
|
||||||
|
...values,
|
||||||
|
items: values?.items?.map((item: API.PurchaseOrderItem) => ({
|
||||||
|
...item,
|
||||||
|
productSku: {
|
||||||
|
label: item.productName,
|
||||||
|
value: item.productSku,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdatePurchaseOrderDTO>
|
||||||
|
title="编辑"
|
||||||
|
form={form}
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerUpdatepurchaseorder(
|
||||||
|
{ id: initialValues.id },
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="stockPointId"
|
||||||
|
label="仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name={'status'}
|
||||||
|
label="状态"
|
||||||
|
placeholder={'请选择状态'}
|
||||||
|
valueEnum={Purchase_Order_STATUS_ENUM}
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请选择状态' }]}
|
||||||
|
/>
|
||||||
|
<ProFormDatePicker
|
||||||
|
name="expectedArrivalTime"
|
||||||
|
label="预计到货时间"
|
||||||
|
placeholder={'请选择预计到货时间'}
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请选择预计到货时间' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea label="备注" name="note" width={'lg'} />
|
||||||
|
<ProFormDependency name={['items']}>
|
||||||
|
{({ items }) => {
|
||||||
|
return (
|
||||||
|
'数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</ProFormDependency>
|
||||||
|
<ProFormList<API.PurchaseOrderItem>
|
||||||
|
name="items"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增', size: 'large' }}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="productSku"
|
||||||
|
label="产品"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
filterOption: false,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
onChange={(_, option) => {
|
||||||
|
form.setFieldValue(
|
||||||
|
['items', fields.key, 'productName'],
|
||||||
|
option?.title,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormText name="productName" label="产品名称" hidden={true} />
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="price"
|
||||||
|
label="价格"
|
||||||
|
placeholder="请输入价格"
|
||||||
|
rules={[{ required: true, message: '请输入价格' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button type="link" danger onClick={() => remove(fields.key)}>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DetailForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.UpdatePurchaseOrderDTO & {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
}> = ({ tableRef, values }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const initialValues = {
|
||||||
|
...values,
|
||||||
|
items: values?.items?.map((item: API.PurchaseOrderItem) => ({
|
||||||
|
...item,
|
||||||
|
productSku: {
|
||||||
|
label: item.productName,
|
||||||
|
value: item.productSku,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdatePurchaseOrderDTO>
|
||||||
|
title="详情"
|
||||||
|
form={form}
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={<Button type="primary">详情</Button>}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
readonly={true}
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="stockPointId"
|
||||||
|
label="仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="orderNumber"
|
||||||
|
label="订单编号"
|
||||||
|
placeholder="请输入订单编号"
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请输入订单编号' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
name={'status'}
|
||||||
|
label="状态"
|
||||||
|
placeholder={'请选择状态'}
|
||||||
|
valueEnum={Purchase_Order_STATUS_ENUM}
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请选择状态' }]}
|
||||||
|
/>
|
||||||
|
<ProFormDatePicker
|
||||||
|
name="expectedArrivalTime"
|
||||||
|
label="预计到货时间"
|
||||||
|
placeholder={'请选择预计到货时间'}
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请选择预计到货时间' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea label="备注" name="note" width={'lg'} />
|
||||||
|
<ProFormList<API.PurchaseOrderItem>
|
||||||
|
name="items"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增', size: 'large' }}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="productSku"
|
||||||
|
label="产品"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
filterOption: false,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
onChange={(_, option) => {
|
||||||
|
form.setFieldValue(
|
||||||
|
['items', fields.key, 'productName'],
|
||||||
|
option?.title,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormText name="productName" label="产品名称" hidden={true} />
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormDigit
|
||||||
|
name="price"
|
||||||
|
label="价格"
|
||||||
|
placeholder="请输入价格"
|
||||||
|
rules={[{ required: true, message: '请输入价格' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 2,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PurchaseOrderPage;
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { stockcontrollerGetstockrecords } from '@/servers/api/stock';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<API.StockRecordDTO>[] = [
|
||||||
|
{
|
||||||
|
title: '仓库',
|
||||||
|
dataIndex: 'stockPointName',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产品名称',
|
||||||
|
dataIndex: 'productName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'SKU',
|
||||||
|
dataIndex: 'productSku',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '库存',
|
||||||
|
hideInSearch: true,
|
||||||
|
render: (_, record: API.StockRecordDTO) => (
|
||||||
|
<span>
|
||||||
|
{record?.operationType === 'in' ? '+' : '-'}
|
||||||
|
{record.quantityChange}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作人',
|
||||||
|
dataIndex: 'operatorName',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'note',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable<API.StockRecordDTO>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await stockcontrollerGetstockrecords(
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
// toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,688 @@
|
||||||
|
import { productcontrollerSearchproducts } from '@/servers/api/product';
|
||||||
|
import {
|
||||||
|
stockcontrollerCanceltransfer,
|
||||||
|
stockcontrollerCreatetransfer,
|
||||||
|
stockcontrollerGetallstockpoints,
|
||||||
|
stockcontrollerGettransfers,
|
||||||
|
stockcontrollerLosttransfer,
|
||||||
|
stockcontrollerReceivetransfer,
|
||||||
|
stockcontrollerUpdatetransfer,
|
||||||
|
} from '@/servers/api/stock';
|
||||||
|
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormDatePicker,
|
||||||
|
ProFormDependency,
|
||||||
|
ProFormDigit,
|
||||||
|
ProFormList,
|
||||||
|
ProFormSelect,
|
||||||
|
ProFormText,
|
||||||
|
ProFormTextArea,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Divider, Form, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const TransferPage: React.FC = () => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns[] = [
|
||||||
|
{
|
||||||
|
title: '订单编号',
|
||||||
|
dataIndex: 'orderNumber',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '源仓库',
|
||||||
|
dataIndex: 'sourceStockPointName',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '目标仓库',
|
||||||
|
dataIndex: 'destStockPointName',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
if (record.isLost) return '已丢失';
|
||||||
|
if (record.isCancel) return '已取消';
|
||||||
|
if (record.isArrived) return '已到达';
|
||||||
|
return '运输中';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '数量',
|
||||||
|
hideInSearch: true,
|
||||||
|
render(_, record) {
|
||||||
|
return record.items.reduce((cur, next) => {
|
||||||
|
return cur + next.quantity;
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'note',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '到货时间',
|
||||||
|
dataIndex: 'arriveAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发货时间',
|
||||||
|
dataIndex: 'sendAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
{!record.isCancel && !record.isArrived && !record.isLost ? (
|
||||||
|
<>
|
||||||
|
<UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="入库"
|
||||||
|
description="确认已到达?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerReceivetransfer({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary">入库</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="丢失"
|
||||||
|
description="确认该批货已丢失?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerLosttransfer({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary">丢失</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="取消"
|
||||||
|
description="确认取消?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerCanceltransfer({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<DetailForm tableRef={actionRef} values={record} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await stockcontrollerGettransfers(params);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
return (
|
||||||
|
<DrawerForm
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
form={form}
|
||||||
|
autoFocusFirstInput
|
||||||
|
layout="vertical"
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
console.log(values);
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerCreatetransfer(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormDatePicker
|
||||||
|
name="sendAt"
|
||||||
|
label="发货时间"
|
||||||
|
rules={[{ required: true, message: '请选择发货时间' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="sourceStockPointId"
|
||||||
|
label="源仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择源仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="destStockPointId"
|
||||||
|
label="目标仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择源目标仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea name="note" label="备注" />
|
||||||
|
<ProFormDependency name={['items']}>
|
||||||
|
{({ items }) => {
|
||||||
|
return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0);
|
||||||
|
}}
|
||||||
|
</ProFormDependency>
|
||||||
|
<ProFormList
|
||||||
|
name="items"
|
||||||
|
label="产品"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增', size: 'large' }}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="productSku"
|
||||||
|
label={'产品' + (idx + 1)}
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
onChange={(_, option) => {
|
||||||
|
form.setFieldValue(
|
||||||
|
['items', fields.key, 'productName'],
|
||||||
|
option.title,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormText name={'productName'} label="产品名称" hidden={true} />
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.UpdatePurchaseOrderDTO & {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
}> = ({ tableRef, values }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const initialValues = {
|
||||||
|
...values,
|
||||||
|
items: values?.items?.map((item: API.PurchaseOrderItem) => ({
|
||||||
|
...item,
|
||||||
|
productSku: {
|
||||||
|
label: item.productName,
|
||||||
|
value: item.productSku,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdatePurchaseOrderDTO>
|
||||||
|
title="编辑"
|
||||||
|
form={form}
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerUpdatetransfer(
|
||||||
|
{ id: initialValues.id },
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormSelect
|
||||||
|
readonly
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="sourceStockPointId"
|
||||||
|
label="源仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择源仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="destStockPointId"
|
||||||
|
label="目标仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择源目标仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea name="note" label="备注" />
|
||||||
|
<ProFormDependency name={['items']}>
|
||||||
|
{({ items }) => {
|
||||||
|
return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0);
|
||||||
|
}}
|
||||||
|
</ProFormDependency>
|
||||||
|
<ProFormList
|
||||||
|
name="items"
|
||||||
|
label="产品"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增', size: 'large' }}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="productSku"
|
||||||
|
label={'产品' + (idx + 1)}
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
onChange={(_, option) => {
|
||||||
|
form.setFieldValue(
|
||||||
|
['items', fields.key, 'productName'],
|
||||||
|
option.title,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormText name={'productName'} label="产品名称" hidden={true} />
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DetailForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: Record<string, any>;
|
||||||
|
}> = ({ tableRef, values }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const initialValues = {
|
||||||
|
...values,
|
||||||
|
items: values?.items?.map(
|
||||||
|
(item: { productName: string; productSku: string }) => ({
|
||||||
|
...item,
|
||||||
|
productSku: {
|
||||||
|
label: item.productName,
|
||||||
|
value: item.productSku,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<DrawerForm
|
||||||
|
title="详情"
|
||||||
|
form={form}
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={<Button type="primary">详情</Button>}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
readonly={true}
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
name="orderNumber"
|
||||||
|
label="订单编号"
|
||||||
|
placeholder="请输入订单编号"
|
||||||
|
width={'lg'}
|
||||||
|
rules={[{ required: true, message: '请输入订单编号' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="sourceStockPointId"
|
||||||
|
label="源仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择源仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await stockcontrollerGetallstockpoints();
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="destStockPointId"
|
||||||
|
label="目标仓库"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择仓库"
|
||||||
|
rules={[{ required: true, message: '请选择源目标仓库' }]}
|
||||||
|
/>
|
||||||
|
<ProFormTextArea name="note" label="备注" />
|
||||||
|
<ProFormList<API.PurchaseOrderItem>
|
||||||
|
name="items"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '至少需要一个商品',
|
||||||
|
validator: (_, value) =>
|
||||||
|
value && value.length > 0
|
||||||
|
? Promise.resolve()
|
||||||
|
: Promise.reject('至少需要一个商品'),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
creatorButtonProps={{ children: '新增', size: 'large' }}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
>
|
||||||
|
{(fields, idx, { remove }) => (
|
||||||
|
<div key={idx}>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormSelect
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (keyWords.length < 3) return [];
|
||||||
|
try {
|
||||||
|
const { data } = await productcontrollerSearchproducts({
|
||||||
|
name: keyWords,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
data?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.sku,
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
name="productSku"
|
||||||
|
label="产品"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请选择产品"
|
||||||
|
tooltip="至少输入3个字符"
|
||||||
|
fieldProps={{
|
||||||
|
showSearch: true,
|
||||||
|
}}
|
||||||
|
transform={(value) => {
|
||||||
|
return value?.value || value;
|
||||||
|
}}
|
||||||
|
debounceTime={300} // 防抖,减少请求频率
|
||||||
|
rules={[{ required: true, message: '请选择产品' }]}
|
||||||
|
onChange={(_, option) => {
|
||||||
|
form.setFieldValue(
|
||||||
|
['items', fields.key, 'productName'],
|
||||||
|
option?.title,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProFormText name="productName" label="产品名称" hidden={true} />
|
||||||
|
<ProFormDigit
|
||||||
|
name="quantity"
|
||||||
|
label="数量"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
rules={[{ required: true, message: '请输入数量' }]}
|
||||||
|
fieldProps={{
|
||||||
|
precision: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</ProFormList>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TransferPage;
|
||||||
|
|
@ -0,0 +1,239 @@
|
||||||
|
import {
|
||||||
|
stockcontrollerCreatestockpoint,
|
||||||
|
stockcontrollerDelstockpoints,
|
||||||
|
stockcontrollerGetstockpoints,
|
||||||
|
stockcontrollerUpdatestockpoint,
|
||||||
|
} from '@/servers/api/stock';
|
||||||
|
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
ActionType,
|
||||||
|
DrawerForm,
|
||||||
|
PageContainer,
|
||||||
|
ProColumns,
|
||||||
|
ProForm,
|
||||||
|
ProFormText,
|
||||||
|
ProTable,
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import { App, Button, Divider, Popconfirm } from 'antd';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
const ListPage: React.FC = () => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<API.StockPoint>[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '地址',
|
||||||
|
dataIndex: 'location',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系人',
|
||||||
|
dataIndex: 'contactPerson',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系电话',
|
||||||
|
dataIndex: 'contactPhone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'option',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_, record) => (
|
||||||
|
<>
|
||||||
|
<UpdateForm tableRef={actionRef} values={record} />
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Popconfirm
|
||||||
|
title="删除"
|
||||||
|
description="确认删除?"
|
||||||
|
onConfirm={async () => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerDelstockpoints({
|
||||||
|
id: record.id as number,
|
||||||
|
});
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button type="primary" danger>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer ghost>
|
||||||
|
<ProTable<API.StockPoint>
|
||||||
|
headerTitle="查询表格"
|
||||||
|
actionRef={actionRef}
|
||||||
|
rowKey="id"
|
||||||
|
request={async (params) => {
|
||||||
|
const { data, success } = await stockcontrollerGetstockpoints(params);
|
||||||
|
return {
|
||||||
|
total: data?.total || 0,
|
||||||
|
data: data?.items || [],
|
||||||
|
success,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
|
||||||
|
search={false}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CreateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
}> = ({ tableRef }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.CreateStockPointDTO>
|
||||||
|
title="新建"
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<PlusOutlined />
|
||||||
|
新建
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerCreatestockpoint(values);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
tableRef.current?.reload();
|
||||||
|
message.success('提交成功');
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="location"
|
||||||
|
label="地址"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入地址"
|
||||||
|
rules={[{ required: true, message: '请输入地址' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="contactPerson"
|
||||||
|
label="联系人"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入联系人"
|
||||||
|
rules={[{ required: true, message: '请输入联系人' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="contactPhone"
|
||||||
|
label="联系电话"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入联系电话"
|
||||||
|
rules={[{ required: true, message: '请输入联系电话' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateForm: React.FC<{
|
||||||
|
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||||
|
values: API.StockPoint;
|
||||||
|
}> = ({ tableRef, values: initialValues }) => {
|
||||||
|
const { message } = App.useApp();
|
||||||
|
return (
|
||||||
|
<DrawerForm<API.UpdateStockPointDTO>
|
||||||
|
title="编辑"
|
||||||
|
initialValues={initialValues}
|
||||||
|
trigger={
|
||||||
|
<Button type="primary">
|
||||||
|
<EditOutlined />
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
autoFocusFirstInput
|
||||||
|
drawerProps={{
|
||||||
|
destroyOnClose: true,
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
try {
|
||||||
|
const { success, message: errMsg } =
|
||||||
|
await stockcontrollerUpdatestockpoint(
|
||||||
|
{ id: initialValues.id as number },
|
||||||
|
values,
|
||||||
|
);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(errMsg);
|
||||||
|
}
|
||||||
|
message.success('提交成功');
|
||||||
|
tableRef.current?.reload();
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="name"
|
||||||
|
label="名称"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
rules={[{ required: true, message: '请输入名称' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="location"
|
||||||
|
label="地址"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入地址"
|
||||||
|
rules={[{ required: true, message: '请输入地址' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="contactPerson"
|
||||||
|
label="联系人"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入联系人"
|
||||||
|
rules={[{ required: true, message: '请输入联系人' }]}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="contactPhone"
|
||||||
|
label="联系电话"
|
||||||
|
width="lg"
|
||||||
|
placeholder="请输入联系电话"
|
||||||
|
rules={[{ required: true, message: '请输入联系电话' }]}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</DrawerForm>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListPage;
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
import {
|
||||||
|
logisticscontrollerGetlistbytrackingid,
|
||||||
|
logisticscontrollerGettrackingnumber,
|
||||||
|
} from '@/servers/api/logistics';
|
||||||
|
import { SearchOutlined } from '@ant-design/icons';
|
||||||
|
import { PageContainer, ProFormSelect } from '@ant-design/pro-components';
|
||||||
|
import { Col, Row } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
const TrackPage: React.FC = () => {
|
||||||
|
const [id, setId] = useState<string>();
|
||||||
|
const [data, setData] = useState([]);
|
||||||
|
return (
|
||||||
|
<PageContainer>
|
||||||
|
<ProFormSelect
|
||||||
|
showSearch={true}
|
||||||
|
debounceTime={500}
|
||||||
|
request={async ({ keyWords }) => {
|
||||||
|
if (!keyWords || keyWords.length < 3) return [];
|
||||||
|
const { data: trackList } =
|
||||||
|
await logisticscontrollerGettrackingnumber({ number: keyWords });
|
||||||
|
return trackList?.map(
|
||||||
|
(v: {
|
||||||
|
tracking_provider: string;
|
||||||
|
primary_tracking_number: string;
|
||||||
|
id: string;
|
||||||
|
}) => {
|
||||||
|
return {
|
||||||
|
label: v.tracking_provider + ' ' + v.primary_tracking_number,
|
||||||
|
value: v.id,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
fieldProps={{
|
||||||
|
prefix: '追踪号',
|
||||||
|
onChange(value: string) {
|
||||||
|
setId(value);
|
||||||
|
},
|
||||||
|
allowClear: false,
|
||||||
|
suffixIcon: (
|
||||||
|
<SearchOutlined
|
||||||
|
onClick={async (e) => {
|
||||||
|
if (!id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { data } = await logisticscontrollerGetlistbytrackingid({
|
||||||
|
shipment_id: id,
|
||||||
|
});
|
||||||
|
setData(data);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>原订单</Col>
|
||||||
|
<Col span={18}>产品</Col>
|
||||||
|
<Col span={6}>数量</Col>
|
||||||
|
{data?.orderItem?.map((v: any) => (
|
||||||
|
<>
|
||||||
|
<Col span={18}>{v.name}</Col>
|
||||||
|
<Col span={6}>{v.quantity}</Col>
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row style={{ marginTop: '30px' }}>
|
||||||
|
<Col span={18}>产品</Col>
|
||||||
|
<Col span={6}>数量</Col>
|
||||||
|
{data?.shipmentItem?.map((v: any) => (
|
||||||
|
<>
|
||||||
|
<Col span={18}>{v.name}</Col>
|
||||||
|
<Col span={6}>{v.quantity}</Col>
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrackPage;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
// API 更新时间:
|
||||||
|
// API 唯一标识:
|
||||||
|
import * as logistics from './logistics';
|
||||||
|
import * as order from './order';
|
||||||
|
import * as product from './product';
|
||||||
|
import * as site from './site';
|
||||||
|
import * as statistics from './statistics';
|
||||||
|
import * as stock from './stock';
|
||||||
|
import * as user from './user';
|
||||||
|
import * as webhook from './webhook';
|
||||||
|
import * as wpProduct from './wpProduct';
|
||||||
|
export default {
|
||||||
|
logistics,
|
||||||
|
order,
|
||||||
|
product,
|
||||||
|
site,
|
||||||
|
statistics,
|
||||||
|
stock,
|
||||||
|
user,
|
||||||
|
webhook,
|
||||||
|
wpProduct,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,202 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/createShipment/${param0} */
|
||||||
|
export async function logisticscontrollerCreateshipment(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerCreateshipmentParams,
|
||||||
|
body: API.ShipmentBookDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { orderId: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/logistics/createShipment/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/createShippingAddress */
|
||||||
|
export async function logisticscontrollerCreateshippingaddress(
|
||||||
|
body: API.ShippingAddress,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/logistics/createShippingAddress', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /logistics/delShippingAddress/${param0} */
|
||||||
|
export async function logisticscontrollerDelshippingaddress(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerDelshippingaddressParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/logistics/delShippingAddress/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/getListByTrackingId */
|
||||||
|
export async function logisticscontrollerGetlistbytrackingid(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerGetlistbytrackingidParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/logistics/getListByTrackingId', {
|
||||||
|
method: 'POST',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/getPaymentMethods */
|
||||||
|
export async function logisticscontrollerGetpaymentmethods(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/logistics/getPaymentMethods', {
|
||||||
|
method: 'POST',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/getRateList */
|
||||||
|
export async function logisticscontrollerGetratelist(
|
||||||
|
body: API.ShippingDetailsDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.RateLitRes>('/logistics/getRateList', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /logistics/getServiceList */
|
||||||
|
export async function logisticscontrollerGetservicelist(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerGetservicelistParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.ServiceListRes>('/logistics/getServiceList', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /logistics/getShippingAddressList */
|
||||||
|
export async function logisticscontrollerGetshippingaddresslist(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<API.ShippingAddressListRes>(
|
||||||
|
'/logistics/getShippingAddressList',
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/getTrackingNumber */
|
||||||
|
export async function logisticscontrollerGettrackingnumber(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerGettrackingnumberParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/logistics/getTrackingNumber', {
|
||||||
|
method: 'POST',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /logistics/list */
|
||||||
|
export async function logisticscontrollerGetlist(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/logistics/list', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /logistics/shipment/${param0} */
|
||||||
|
export async function logisticscontrollerDelshipment(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerDelshipmentParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/logistics/shipment/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/syncServices */
|
||||||
|
export async function logisticscontrollerSyncservices(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<API.BooleanRes>('/logistics/syncServices', {
|
||||||
|
method: 'POST',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /logistics/toggleActive */
|
||||||
|
export async function logisticscontrollerToggleactive(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/logistics/toggleActive', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /logistics/updateShippingAddress/${param0} */
|
||||||
|
export async function logisticscontrollerUpdateshippingaddress(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.logisticscontrollerUpdateshippingaddressParams,
|
||||||
|
body: API.ShippingAddress,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/logistics/updateShippingAddress/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /order/${param0} */
|
||||||
|
export async function ordercontrollerGetorderdetail(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerGetorderdetailParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { orderId: param0, ...queryParams } = params;
|
||||||
|
return request<API.OrderDetailRes>(`/order/${param0}`, {
|
||||||
|
method: 'GET',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /order/${param0} */
|
||||||
|
export async function ordercontrollerDelorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerDelorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/order/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/createNote */
|
||||||
|
export async function ordercontrollerCreatenote(
|
||||||
|
body: API.CreateOrderNoteDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/order/createNote', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/getOrderByNumber */
|
||||||
|
export async function ordercontrollerGetorderbynumber(
|
||||||
|
body: string,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/order/getOrderByNumber', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /order/getOrders */
|
||||||
|
export async function ordercontrollerGetorders(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerGetordersParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.OrderListRes>('/order/getOrders', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /order/getOrderSales */
|
||||||
|
export async function ordercontrollerGetordersales(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerGetordersalesParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.OrderSaleListRes>('/order/getOrderSales', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/order/cancel/${param0} */
|
||||||
|
export async function ordercontrollerCancelorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerCancelorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/order/order/cancel/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/order/completed/${param0} */
|
||||||
|
export async function ordercontrollerCompletedorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerCompletedorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/order/order/completed/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/order/create */
|
||||||
|
export async function ordercontrollerCreateorder(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/order/order/create', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/order/refund/${param0} */
|
||||||
|
export async function ordercontrollerRefundorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerRefundorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/order/order/refund/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /order/order/status/${param0} */
|
||||||
|
export async function ordercontrollerChangestatus(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerChangestatusParams,
|
||||||
|
body: string,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/order/order/status/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/syncOrder/${param0} */
|
||||||
|
export async function ordercontrollerSyncorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerSyncorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { siteId: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/order/syncOrder/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /order/syncOrder/${param1}/order/${param0} */
|
||||||
|
export async function ordercontrollerSyncorderbyid(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.ordercontrollerSyncorderbyidParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { orderId: param0, siteId: param1, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/order/syncOrder/${param1}/order/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,329 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /product/ */
|
||||||
|
export async function productcontrollerCreateproduct(
|
||||||
|
body: API.CreateProductDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.ProductRes>('/product/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /product/${param0} */
|
||||||
|
export async function productcontrollerUpdateproduct(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerUpdateproductParams,
|
||||||
|
body: API.UpdateProductDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.ProductRes>(`/product/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /product/${param0} */
|
||||||
|
export async function productcontrollerDeleteproduct(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerDeleteproductParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/product/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /product/batchSetSku */
|
||||||
|
export async function productcontrollerBatchsetsku(
|
||||||
|
body: API.BatchSetSkuDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/product/batchSetSku', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/categorieAll */
|
||||||
|
export async function productcontrollerGetcategorieall(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/product/categorieAll', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/categories */
|
||||||
|
export async function productcontrollerGetcategories(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerGetcategoriesParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.ProductCatListRes>('/product/categories', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /product/category */
|
||||||
|
export async function productcontrollerCreatecategory(
|
||||||
|
body: API.CreateCategoryDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.ProductCatRes>('/product/category', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /product/category/${param0} */
|
||||||
|
export async function productcontrollerUpdatecategory(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerUpdatecategoryParams,
|
||||||
|
body: API.UpdateCategoryDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.ProductCatRes>(`/product/category/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /product/category/${param0} */
|
||||||
|
export async function productcontrollerDeletecategory(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerDeletecategoryParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/product/category/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/flavors */
|
||||||
|
export async function productcontrollerGetflavors(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerGetflavorsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/product/flavors', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /product/flavors */
|
||||||
|
export async function productcontrollerCreateflavors(
|
||||||
|
body: API.CreateFlavorsDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/product/flavors', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /product/flavors/${param0} */
|
||||||
|
export async function productcontrollerUpdateflavors(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerUpdateflavorsParams,
|
||||||
|
body: API.UpdateFlavorsDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/product/flavors/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /product/flavors/${param0} */
|
||||||
|
export async function productcontrollerDeleteflavors(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerDeleteflavorsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/product/flavors/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/flavorsAll */
|
||||||
|
export async function productcontrollerGetflavorsall(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/product/flavorsAll', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/list */
|
||||||
|
export async function productcontrollerGetproductlist(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerGetproductlistParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.ProductListRes>('/product/list', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/search */
|
||||||
|
export async function productcontrollerSearchproducts(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerSearchproductsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.ProductsRes>('/product/search', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/sku/${param0} */
|
||||||
|
export async function productcontrollerProductbysku(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerProductbyskuParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { sku: param0, ...queryParams } = params;
|
||||||
|
return request<API.ProductRes>(`/product/sku/${param0}`, {
|
||||||
|
method: 'GET',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/strength */
|
||||||
|
export async function productcontrollerGetstrength(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerGetstrengthParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/product/strength', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /product/strength */
|
||||||
|
export async function productcontrollerCreatestrength(
|
||||||
|
body: API.CreateStrengthDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/product/strength', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /product/strength/${param0} */
|
||||||
|
export async function productcontrollerUpdatestrength(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerUpdatestrengthParams,
|
||||||
|
body: API.UpdateStrengthDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<any>(`/product/strength/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /product/strength/${param0} */
|
||||||
|
export async function productcontrollerDeletestrength(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.productcontrollerDeletestrengthParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/product/strength/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /product/strengthAll */
|
||||||
|
export async function productcontrollerGetstrengthall(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/product/strengthAll', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /site/all */
|
||||||
|
export async function sitecontrollerAll(options?: { [key: string]: any }) {
|
||||||
|
return request<API.WpSitesResponse>('/site/all', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /statistics/getCustomerOrders */
|
||||||
|
export async function statisticscontrollerGetcustomerorders(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/statistics/getCustomerOrders', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /statistics/order */
|
||||||
|
export async function statisticscontrollerGetorderstatistics(
|
||||||
|
body: API.OrderStatisticsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/statistics/order', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /statistics/orderByDate */
|
||||||
|
export async function statisticscontrollerGetorderbydate(
|
||||||
|
body: string,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/statistics/orderByDate', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /statistics/orderByEmail */
|
||||||
|
export async function statisticscontrollerGetorderbyemail(
|
||||||
|
body: string,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/statistics/orderByEmail', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /statistics/restocking */
|
||||||
|
export async function statisticscontrollerRestocking(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/statistics/restocking', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /statistics/stockForecast */
|
||||||
|
export async function statisticscontrollerStockforecast(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/statistics/stockForecast', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /stock/ */
|
||||||
|
export async function stockcontrollerGetstocks(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerGetstocksParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.StockListRes>('/stock/', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/cancelTransfer/${param0} */
|
||||||
|
export async function stockcontrollerCanceltransfer(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerCanceltransferParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/cancelTransfer/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/lostTransfer/${param0} */
|
||||||
|
export async function stockcontrollerLosttransfer(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerLosttransferParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/lostTransfer/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /stock/purchase-order */
|
||||||
|
export async function stockcontrollerGetpurchaseorders(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerGetpurchaseordersParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.PurchaseOrderListRes>('/stock/purchase-order', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/purchase-order */
|
||||||
|
export async function stockcontrollerCreatepurchaseorder(
|
||||||
|
body: API.CreatePurchaseOrderDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/stock/purchase-order', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /stock/purchase-order/${param0} */
|
||||||
|
export async function stockcontrollerUpdatepurchaseorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerUpdatepurchaseorderParams,
|
||||||
|
body: API.UpdatePurchaseOrderDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/purchase-order/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/purchase-order/${param0} */
|
||||||
|
export async function stockcontrollerReceivepurchaseorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerReceivepurchaseorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/purchase-order/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /stock/purchase-order/${param0} */
|
||||||
|
export async function stockcontrollerDelpurchaseorder(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerDelpurchaseorderParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/purchase-order/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /stock/receiveTransfer/${param0} */
|
||||||
|
export async function stockcontrollerUpdatetransfer(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerUpdatetransferParams,
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/receiveTransfer/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/receiveTransfer/${param0} */
|
||||||
|
export async function stockcontrollerReceivetransfer(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerReceivetransferParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/receiveTransfer/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /stock/records */
|
||||||
|
export async function stockcontrollerGetstockrecords(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerGetstockrecordsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.StockRecordListRes>('/stock/records', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /stock/stock-point */
|
||||||
|
export async function stockcontrollerGetstockpoints(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerGetstockpointsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.StockPointListRes>('/stock/stock-point', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/stock-point */
|
||||||
|
export async function stockcontrollerCreatestockpoint(
|
||||||
|
body: API.CreateStockPointDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/stock/stock-point', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /stock/stock-point/${param0} */
|
||||||
|
export async function stockcontrollerUpdatestockpoint(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerUpdatestockpointParams,
|
||||||
|
body: API.UpdateStockPointDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/stock-point/${param0}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 DELETE /stock/stock-point/${param0} */
|
||||||
|
export async function stockcontrollerDelstockpoints(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.stockcontrollerDelstockpointsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/stock/stock-point/${param0}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /stock/stock-point/all */
|
||||||
|
export async function stockcontrollerGetallstockpoints(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<API.StockPointAllRespone>('/stock/stock-point/all', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /stock/transfer */
|
||||||
|
export async function stockcontrollerGettransfers(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/stock/transfer', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/transfer */
|
||||||
|
export async function stockcontrollerCreatetransfer(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/stock/transfer', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /stock/update */
|
||||||
|
export async function stockcontrollerUpdatestock(
|
||||||
|
body: API.UpdateStockDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.BooleanRes>('/stock/update', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,74 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /user/ */
|
||||||
|
export async function usercontrollerGetuser(options?: { [key: string]: any }) {
|
||||||
|
return request<any>('/user/', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /user/add */
|
||||||
|
export async function usercontrollerAdduser(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/user/add', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /user/list */
|
||||||
|
export async function usercontrollerListusers(options?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}) {
|
||||||
|
return request<any>('/user/list', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /user/login */
|
||||||
|
export async function usercontrollerLogin(
|
||||||
|
body: API.LoginDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.LoginRes>('/user/login', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /user/logout */
|
||||||
|
export async function usercontrollerLogout(options?: { [key: string]: any }) {
|
||||||
|
return request<API.BooleanRes>('/user/logout', {
|
||||||
|
method: 'POST',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /user/toggleActive */
|
||||||
|
export async function usercontrollerToggleactive(
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/user/toggleActive', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /webhook/ */
|
||||||
|
export async function webhookcontrollerTest(options?: { [key: string]: any }) {
|
||||||
|
return request<any>('/webhook/', {
|
||||||
|
method: 'GET',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /webhook/woocommerce */
|
||||||
|
export async function webhookcontrollerHandlewoowebhook(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.webhookcontrollerHandlewoowebhookParams,
|
||||||
|
body: Record<string, any>,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<any>('/webhook/woocommerce', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
// @ts-ignore
|
||||||
|
/* eslint-disable */
|
||||||
|
import { request } from 'umi';
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /wp_product/${param0}/constitution */
|
||||||
|
export async function wpproductcontrollerSetconstitution(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.wpproductcontrollerSetconstitutionParams,
|
||||||
|
body: API.SetConstitutionDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { id: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/wp_product/${param0}/constitution`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 GET /wp_product/list */
|
||||||
|
export async function wpproductcontrollerGetwpproducts(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.wpproductcontrollerGetwpproductsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.WpProductListRes>('/wp_product/list', {
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /wp_product/siteId/${param1}/products/${param0} */
|
||||||
|
export async function wpproductcontrollerUpdateproduct(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.wpproductcontrollerUpdateproductParams,
|
||||||
|
body: API.UpdateWpProductDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { productId: param0, siteId: param1, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(
|
||||||
|
`/wp_product/siteId/${param1}/products/${param0}`,
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 PUT /wp_product/siteId/${param2}/products/${param1}/variations/${param0} */
|
||||||
|
export async function wpproductcontrollerUpdatevariation(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.wpproductcontrollerUpdatevariationParams,
|
||||||
|
body: API.UpdateVariationDTO,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
variationId: param0,
|
||||||
|
productId: param1,
|
||||||
|
siteId: param2,
|
||||||
|
...queryParams
|
||||||
|
} = params;
|
||||||
|
return request<any>(
|
||||||
|
`/wp_product/siteId/${param2}/products/${param1}/variations/${param0}`,
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
params: { ...queryParams },
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此处后端没有提供注释 POST /wp_product/sync/${param0} */
|
||||||
|
export async function wpproductcontrollerSyncproducts(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.wpproductcontrollerSyncproductsParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const { siteId: param0, ...queryParams } = params;
|
||||||
|
return request<API.BooleanRes>(`/wp_product/sync/${param0}`, {
|
||||||
|
method: 'POST',
|
||||||
|
params: { ...queryParams },
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { ProSchemaValueEnumObj } from '@ant-design/pro-components';
|
||||||
|
import { BaseType } from 'typings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将数组转换成 valueEnum 格式
|
||||||
|
* @param array 数据源数组
|
||||||
|
* @param options 转换配置
|
||||||
|
* @returns valueEnum 对象
|
||||||
|
*/
|
||||||
|
export function transformToValueEnum<T>(
|
||||||
|
array: T[],
|
||||||
|
options: BaseType.EnumTransformOptions = {
|
||||||
|
value: 'id',
|
||||||
|
label: 'name',
|
||||||
|
status: 'status',
|
||||||
|
color: 'color',
|
||||||
|
},
|
||||||
|
): ProSchemaValueEnumObj {
|
||||||
|
const { value, label, status, color } = options;
|
||||||
|
|
||||||
|
return array.reduce((acc, item: any) => {
|
||||||
|
const key = String(item[value]);
|
||||||
|
acc[key] = {
|
||||||
|
text: String(item[label]),
|
||||||
|
...(status && item[status] ? { status: String(item[status]) } : {}),
|
||||||
|
...(color && item[color] ? { color: String(item[color]) } : {}),
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}, {} as ProSchemaValueEnumObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatSource(type: string | undefined, utm?: string) {
|
||||||
|
if (!type) return 'Unknon';
|
||||||
|
if (type === 'admin') return 'Web Admin';
|
||||||
|
if (type === 'typein') return 'Direct';
|
||||||
|
if (type === 'utm') return 'Source: ' + utm;
|
||||||
|
return type + ': ' + utm;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatShipmentState(state: string) {
|
||||||
|
switch (state) {
|
||||||
|
case 'draft':
|
||||||
|
return '草稿';
|
||||||
|
case 'waiting-for-scheduling':
|
||||||
|
return '等待调度';
|
||||||
|
case 'waiting-for-transit':
|
||||||
|
return '等待运输';
|
||||||
|
case 'in-transit':
|
||||||
|
return '运输中';
|
||||||
|
case 'delivered':
|
||||||
|
return '已到达';
|
||||||
|
case 'exception':
|
||||||
|
return '异常';
|
||||||
|
case 'missing':
|
||||||
|
return '丢失';
|
||||||
|
case 'cancelled':
|
||||||
|
return '取消';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import printJS from 'print-js';
|
||||||
|
|
||||||
|
export async function printPDF(urls: string[]) {
|
||||||
|
let index = 0;
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (index >= urls.length) return;
|
||||||
|
printJS({
|
||||||
|
printable: urls[index],
|
||||||
|
type: 'pdf',
|
||||||
|
showModal: true,
|
||||||
|
onPrintDialogClose: () => {
|
||||||
|
index++;
|
||||||
|
setTimeout(next, 1000); // 等待下一个
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
console.error('打印失败:', err);
|
||||||
|
index++;
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": "./src/.umi/tsconfig.json"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import '@umijs/max/typings';
|
||||||
|
|
||||||
|
declare namespace BaseType {
|
||||||
|
|
||||||
|
type EnumTransformOptions {
|
||||||
|
value: string; // 用于作为 value 的字段名
|
||||||
|
label: string; // 用于作为 text 的字段名
|
||||||
|
status?: string | undefined; // 可选:用于设置状态的字段名
|
||||||
|
color?: string | undefined; // 可选:用于设置颜色的字段名
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
const UMI_APP_API_URL: string;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue