fix: 合并冲突
This commit is contained in:
5
src/pages/prod/category/category-selecr.tsx
Normal file
5
src/pages/prod/category/category-selecr.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
const CateGorySelect = () => {
|
||||
return <div></div>;
|
||||
};
|
||||
|
||||
export default CateGorySelect;
|
||||
@@ -1,11 +1,20 @@
|
||||
import type {
|
||||
ProColumns,
|
||||
ProCoreActionType,
|
||||
ProFormColumnsType,
|
||||
} from '@ant-design/pro-components';
|
||||
import { Modal, message, Switch } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import TagEditor from '@/components/TagEditor';
|
||||
import TinyMCEEditor from '@/components/Tinymce';
|
||||
export const baseTenantColumns: ProColumns<API.CategoryDO>[] = [
|
||||
import UploadImages from '@/components/Upload/UploadImages';
|
||||
import { dateFormatS } from '@/constants';
|
||||
import {
|
||||
type Category,
|
||||
getProdCategoryPage,
|
||||
updateProdCategory,
|
||||
} from '@/services/prod/category-manager';
|
||||
export const baseTenantColumns: ProColumns<Category>[] = [
|
||||
{
|
||||
title: '类目名称',
|
||||
dataIndex: 'categoryName',
|
||||
@@ -36,118 +45,189 @@ export const baseTenantColumns: ProColumns<API.CategoryDO>[] = [
|
||||
dataIndex: 'status',
|
||||
valueType: 'switch',
|
||||
hideInSearch: true,
|
||||
render: (
|
||||
_,
|
||||
record: Category,
|
||||
_index: number,
|
||||
action: ProCoreActionType | undefined,
|
||||
) => (
|
||||
<Switch
|
||||
checked={record.status === 1}
|
||||
checkedChildren="开启"
|
||||
unCheckedChildren="禁用"
|
||||
onChange={(checked) => {
|
||||
Modal.confirm({
|
||||
title: '确认操作',
|
||||
content: `确认要"${checked ? '启用' : '禁用'}${
|
||||
record.categoryName
|
||||
}"类目吗?`,
|
||||
onOk: async () => {
|
||||
console.log(checked);
|
||||
await updateProdCategory({
|
||||
status: checked ? 1 : 0,
|
||||
categoryId: record.categoryId,
|
||||
});
|
||||
message.success('修改成功');
|
||||
action?.reload();
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
valueType: 'dateRange',
|
||||
hideInSearch: true, // 在搜索表单中隐藏
|
||||
render: (_, record: API.CategoryDO) =>
|
||||
render: (_, record: Category) =>
|
||||
dayjs(record.createTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
},
|
||||
];
|
||||
|
||||
export const formColumns = (data: {
|
||||
type: string;
|
||||
grade: number;
|
||||
}): ProFormColumnsType[] => [
|
||||
{
|
||||
title: '类目',
|
||||
dataIndex: 'grade',
|
||||
valueType: 'radio',
|
||||
fieldProps: {
|
||||
value: data.grade || 1,
|
||||
options: [
|
||||
{ label: '一级类目', value: 1 },
|
||||
{ label: '二级类目', value: 2 },
|
||||
{ label: '三级类目', value: 3 },
|
||||
],
|
||||
disabled: data.type === 'create',
|
||||
export const formColumns = (data: { type: string }): ProFormColumnsType[] => {
|
||||
console.log(data, 'data');
|
||||
return [
|
||||
{
|
||||
title: '类目',
|
||||
dataIndex: 'grade',
|
||||
valueType: 'radio',
|
||||
fieldProps: {
|
||||
options: [
|
||||
{ label: '一级类目', value: 1 },
|
||||
{ label: '二级类目', value: 2 },
|
||||
{ label: '三级类目', value: 3 },
|
||||
],
|
||||
disabled: data.type === 'update',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类目名称',
|
||||
dataIndex: 'username',
|
||||
formItemProps: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
},
|
||||
],
|
||||
{
|
||||
title: '类目名称',
|
||||
dataIndex: 'categoryName',
|
||||
formItemProps: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '排序权重',
|
||||
dataIndex: 'sort',
|
||||
valueType: 'digit',
|
||||
},
|
||||
{
|
||||
title: '类目描述',
|
||||
dataIndex: 'description',
|
||||
valueType: 'textarea',
|
||||
renderFormItem: () => {
|
||||
return <TinyMCEEditor />;
|
||||
{
|
||||
title: '排序权重',
|
||||
dataIndex: 'sort',
|
||||
valueType: 'digit',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '关联父级',
|
||||
dataIndex: 'parentId',
|
||||
valueType: 'select',
|
||||
hideInForm: data.grade - 1 === 0,
|
||||
},
|
||||
{
|
||||
title: '类目icon',
|
||||
dataIndex: 'icon',
|
||||
},
|
||||
{
|
||||
title: '类目标签',
|
||||
dataIndex: 'tages',
|
||||
renderFormItem: () => {
|
||||
return (
|
||||
<TagEditor
|
||||
placeholder="输入标签名称"
|
||||
maxCount={10}
|
||||
tagProps={{
|
||||
color: 'blue',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
{
|
||||
title: '类目描述',
|
||||
dataIndex: 'description',
|
||||
valueType: 'textarea',
|
||||
renderFormItem: () => {
|
||||
return <TinyMCEEditor />;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类目状态',
|
||||
dataIndex: 'status',
|
||||
hideInForm: data.type === 'create',
|
||||
},
|
||||
{
|
||||
title: '类目ID',
|
||||
dataIndex: 'categoryId',
|
||||
hideInForm: data.type === 'create',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
valueType: 'dateTime',
|
||||
hideInForm: data.type === 'create',
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
dataIndex: 'creator',
|
||||
hideInForm: data.type === 'create',
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updateTime',
|
||||
valueType: 'dateTime',
|
||||
hideInForm: data.type === 'create',
|
||||
},
|
||||
{
|
||||
title: '更新人',
|
||||
dataIndex: 'updator',
|
||||
hideInForm: data.type === 'create',
|
||||
},
|
||||
];
|
||||
{
|
||||
title: '关联父级',
|
||||
dataIndex: 'parentId',
|
||||
valueType: 'select',
|
||||
fieldProps: {
|
||||
fieldNames: { label: 'categoryName', value: 'categoryId' },
|
||||
},
|
||||
dependencies: ['grade'],
|
||||
request: async (params) => {
|
||||
const res = await getProdCategoryPage({
|
||||
grade: Number(params.grade) - 1,
|
||||
});
|
||||
return res;
|
||||
},
|
||||
renderFormItem: (schema, config, form) => {
|
||||
const grade = form.getFieldValue('grade');
|
||||
if (Number(grade) === 1) {
|
||||
return null;
|
||||
}
|
||||
return config.defaultRender(schema);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类目icon',
|
||||
dataIndex: 'icon',
|
||||
renderFormItem: () => {
|
||||
return <UploadImages multiple={true} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类目标签',
|
||||
dataIndex: 'tag',
|
||||
renderFormItem: () => {
|
||||
return (
|
||||
<TagEditor
|
||||
placeholder="输入标签名称"
|
||||
maxCount={10}
|
||||
tagProps={{
|
||||
color: 'blue',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类目状态',
|
||||
dataIndex: 'status',
|
||||
hideInForm: data.type === 'create',
|
||||
renderFormItem: (_schema, _config, form) => {
|
||||
const status = form.getFieldValue('status');
|
||||
return <span>{status ? '启用' : '禁用'}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类目ID',
|
||||
dataIndex: 'categoryId',
|
||||
hideInForm: data.type === 'create',
|
||||
renderFormItem: (_schema, _config, form) => {
|
||||
const categoryId = form.getFieldValue('categoryId');
|
||||
return <span>{categoryId}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
valueType: 'dateTime',
|
||||
hideInForm: data.type === 'create',
|
||||
renderFormItem: (_schema, _config, form) => {
|
||||
const createTime = form.getFieldValue('createTime');
|
||||
return <span>{dayjs(createTime).format(dateFormatS)}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
dataIndex: 'creator',
|
||||
hideInForm: data.type === 'create',
|
||||
renderFormItem: (_schema, _config, form) => {
|
||||
const creator = form.getFieldValue('creator');
|
||||
return <span>{creator}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updateTime',
|
||||
valueType: 'dateTime',
|
||||
hideInForm: data.type === 'create',
|
||||
renderFormItem: (_schema, _config, form) => {
|
||||
const dateTime = form.getFieldValue('dateTime');
|
||||
return <span>{dayjs(dateTime).format(dateFormatS)}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '更新人',
|
||||
dataIndex: 'updator',
|
||||
hideInForm: data.type === 'create',
|
||||
renderFormItem: (_schema, _config, form) => {
|
||||
const updator = form.getFieldValue('updator');
|
||||
return <span>{updator}</span>;
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
// {
|
||||
// title: "模板内容",
|
||||
|
||||
@@ -9,23 +9,30 @@ import ConfigurableDrawerForm, {
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import type { ToolbarAction } from '@/components/EnhancedProTable/types';
|
||||
import { formStatusType } from '@/constants';
|
||||
import { getCategoryList } from '@/services/prodApi/category';
|
||||
import {
|
||||
type Category,
|
||||
type CategoryReq,
|
||||
createProdCategory,
|
||||
getProdCategoryPage,
|
||||
updateProdCategory,
|
||||
} from '@/services/prod/category-manager';
|
||||
import { baseTenantColumns, formColumns } from './config';
|
||||
|
||||
const ProdCategory = () => {
|
||||
const tableRef = useRef<ActionType>(null);
|
||||
const [type, setType] = useState<'create' | 'update' | 'test'>('create');
|
||||
const [grade, setGrade] = useState<string>('');
|
||||
const [grade, setGrade] = useState<number>();
|
||||
const configurableDrawerRef = useRef<ConfigurableDrawerFormRef>(null);
|
||||
const [id, setId] = useState<number>(0);
|
||||
const onChange = useCallback(
|
||||
(key: string) => {
|
||||
setGrade(key);
|
||||
setGrade(Number(key));
|
||||
},
|
||||
[grade],
|
||||
);
|
||||
|
||||
const onFetch = async (params: API.getProductCategoryCategoryListParams) => {
|
||||
const data = await getCategoryList({
|
||||
const onFetch = async (params: CategoryReq) => {
|
||||
const data = await getProdCategoryPage({
|
||||
...params,
|
||||
grade: grade ? Number(grade) : undefined,
|
||||
});
|
||||
@@ -37,7 +44,7 @@ const ProdCategory = () => {
|
||||
|
||||
const handleAdd = () => {
|
||||
setType('create');
|
||||
configurableDrawerRef.current?.open();
|
||||
configurableDrawerRef.current?.open({ grade: 1 });
|
||||
};
|
||||
|
||||
const toolbarActions: ToolbarAction[] = [
|
||||
@@ -49,26 +56,35 @@ const ProdCategory = () => {
|
||||
onClick: handleAdd,
|
||||
},
|
||||
];
|
||||
const handleEdit = async (row: API.CategoryDO) => {
|
||||
const handleEdit = async (row: Category) => {
|
||||
setType('update');
|
||||
row.categoryId && setId(row.categoryId);
|
||||
configurableDrawerRef.current?.open(row);
|
||||
};
|
||||
const handleSubmit = async (values: API.CategoryDO) => {
|
||||
console.log('values', values);
|
||||
// const success = await handleAdd(values as API.CategoryDO);
|
||||
// if (success) {
|
||||
// handleClose();
|
||||
// }
|
||||
return true;
|
||||
};
|
||||
const handleSubmit = useCallback(
|
||||
async (values: Category) => {
|
||||
if (type === 'create') {
|
||||
await createProdCategory(values);
|
||||
} else {
|
||||
await updateProdCategory({
|
||||
...values,
|
||||
categoryId: id,
|
||||
});
|
||||
}
|
||||
tableRef.current?.reload(true);
|
||||
return true;
|
||||
},
|
||||
|
||||
const actionColumns: ProColumns<API.CategoryDO> = {
|
||||
[id, type],
|
||||
);
|
||||
|
||||
const actionColumns: ProColumns<Category> = {
|
||||
title: '操作',
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
fixed: 'right',
|
||||
width: 120,
|
||||
render: (_text: React.ReactNode, record: API.CategoryDO, _: number) => [
|
||||
render: (_text: React.ReactNode, record: Category, _: number) => [
|
||||
<a key="edit" onClick={() => handleEdit(record)}>
|
||||
编辑
|
||||
</a>,
|
||||
@@ -80,7 +96,7 @@ const ProdCategory = () => {
|
||||
const renderChildren = () => {
|
||||
return (
|
||||
<>
|
||||
<EnhancedProTable<API.CategoryDO>
|
||||
<EnhancedProTable<Category>
|
||||
ref={tableRef}
|
||||
columns={columns}
|
||||
rowKey="categoryId"
|
||||
@@ -93,9 +109,11 @@ const ProdCategory = () => {
|
||||
<ConfigurableDrawerForm
|
||||
ref={configurableDrawerRef}
|
||||
title={formStatusType[type]}
|
||||
// width="50vw"
|
||||
columns={formColumns({ grade: Number(grade), type })}
|
||||
width={'60vw'}
|
||||
columns={formColumns({ type })}
|
||||
onSubmit={handleSubmit}
|
||||
footer={undefined}
|
||||
bodyStyle={{}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@@ -123,7 +141,14 @@ const ProdCategory = () => {
|
||||
children: renderChildren(),
|
||||
},
|
||||
];
|
||||
return <Tabs defaultActiveKey={grade} items={items} onChange={onChange} />;
|
||||
return (
|
||||
<Tabs
|
||||
defaultActiveKey={grade as unknown as string}
|
||||
items={items}
|
||||
destroyOnHidden
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProdCategory;
|
||||
|
||||
151
src/pages/prod/list/components/prod-info.tsx
Normal file
151
src/pages/prod/list/components/prod-info.tsx
Normal file
@@ -0,0 +1,151 @@
|
||||
import {
|
||||
ProForm,
|
||||
ProFormGroup,
|
||||
ProFormSelect,
|
||||
ProFormText,
|
||||
ProFormTextArea,
|
||||
} from '@ant-design/pro-components';
|
||||
import { Divider } from 'antd';
|
||||
import React from 'react';
|
||||
import TagEditor from '@/components/TagEditor';
|
||||
import TinymceEditor from '@/components/Tinymce';
|
||||
import UploadImages from '@/components/Upload/UploadImages';
|
||||
import UploadVideo from '@/components/Upload/UploadVideo';
|
||||
import type { Prod } from '@/services/prod/prod-manager';
|
||||
|
||||
interface ProdInfoProps<T> {
|
||||
onRefresh?: (type?: string) => void;
|
||||
data?: T;
|
||||
}
|
||||
|
||||
const ProdInfo = <T extends Record<string, any>>(props: ProdInfoProps<T>) => {
|
||||
console.log(props, 'ProdInfo');
|
||||
return (
|
||||
<>
|
||||
<ProFormGroup title="一、基础信息">
|
||||
<ProFormText
|
||||
name="prodName"
|
||||
label="商品名字"
|
||||
rules={[{ required: true }]}
|
||||
width="xl"
|
||||
/>
|
||||
<ProFormText name="abbreviation" label="商品简称" width="xl" />
|
||||
<ProFormText name="brief" label="商品概述" width="xl" />
|
||||
<ProFormText name="prodNumber" label="商品编码" width="xl" />
|
||||
<ProFormText name="brand" label="品牌" width="xl" />
|
||||
<ProFormText name="shopId" label="商品所有权" width="xl" />
|
||||
<ProFormText name="categoryName" label="关联类目" width="xl" />
|
||||
<ProForm.Item
|
||||
name="tag"
|
||||
label="商品标签"
|
||||
tooltip="设置卖点标签,单标签限xx字符,最多x个标签"
|
||||
layout="horizontal"
|
||||
width="xl"
|
||||
required={false}
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<TagEditor
|
||||
placeholder="输入标签名称"
|
||||
maxCount={10}
|
||||
tagProps={{
|
||||
color: 'blue',
|
||||
}}
|
||||
/>
|
||||
</ProForm.Item>
|
||||
</ProFormGroup>
|
||||
<ProFormGroup title="二、内容展示">
|
||||
<ProForm.Item
|
||||
style={{ width: '100%' }}
|
||||
name="pic"
|
||||
label="主图"
|
||||
width="xl"
|
||||
extra="仅支持.jpg .png 格式,建议图片比例1:1,限1张"
|
||||
// rules={[{ required: true }]}
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<UploadImages />
|
||||
</ProForm.Item>
|
||||
<ProForm.Item
|
||||
style={{ width: '100%' }}
|
||||
name="imgs"
|
||||
label="轮播图"
|
||||
layout="horizontal"
|
||||
width="xl"
|
||||
extra="仅支持.jpg .png 格式,建议图片比例1:1,限7张"
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<UploadImages />
|
||||
</ProForm.Item>
|
||||
<ProForm.Item
|
||||
style={{ width: '100%' }}
|
||||
name="whiteImg"
|
||||
label="白底图"
|
||||
width="xl"
|
||||
extra="仅支持.jpg .png 格式,建议图片比例1:1,限1张"
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<UploadImages />
|
||||
</ProForm.Item>
|
||||
<ProForm.Item
|
||||
name="video"
|
||||
label="主视频"
|
||||
width="xl"
|
||||
extra="仅支持.MP4 .MOV 格式,建议比例1:1、16:9,限1个"
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<UploadVideo />
|
||||
</ProForm.Item>
|
||||
<ProForm.Item
|
||||
name="content"
|
||||
label="图文介绍"
|
||||
rules={[{ required: true }]}
|
||||
width="xl"
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<TinymceEditor />
|
||||
</ProForm.Item>
|
||||
</ProFormGroup>
|
||||
<ProFormGroup title="三、营销与传播">
|
||||
<ProFormText
|
||||
name="seoShortName"
|
||||
label="短标题"
|
||||
colProps={{
|
||||
span: 20,
|
||||
}}
|
||||
/>
|
||||
<ProFormText name="seoSearch" label="SEO标题" width={'xl'} />
|
||||
<ProFormTextArea name="keyword" label="商品关键词" width={'xl'} />
|
||||
<Divider />
|
||||
|
||||
<ProForm.Item
|
||||
style={{ width: '100%' }}
|
||||
name="shareImage"
|
||||
label="分享图"
|
||||
width="xl"
|
||||
extra="仅支持.jpg .png 格式,限1张"
|
||||
>
|
||||
<UploadImages />
|
||||
</ProForm.Item>
|
||||
<ProFormTextArea
|
||||
name="shareContent"
|
||||
label="分享话术"
|
||||
placeholder={'请输入分享话术'}
|
||||
width={'xl'}
|
||||
/>
|
||||
</ProFormGroup>
|
||||
<ProFormGroup>
|
||||
<ProFormSelect name="status" label="商品状态" readonly />
|
||||
<ProFormText name="prodId" label="商品ID" readonly />
|
||||
<ProFormText name="createTime" label="创建时间" readonly />
|
||||
<ProFormText name="creator" label="创建人" readonly />
|
||||
<ProFormText name="updateTime" label="更新时间" readonly />
|
||||
<ProFormText name="updater" label="更新人" readonly />
|
||||
<ProFormText name="version" label="版本号" readonly />
|
||||
</ProFormGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ProdInfo) as <_T extends Record<string, any>>(
|
||||
props: ProdInfoProps<Prod>,
|
||||
) => React.ReactElement;
|
||||
69
src/pages/prod/list/components/service-rule/index.tsx
Normal file
69
src/pages/prod/list/components/service-rule/index.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { ProForm, ProFormText } from '@ant-design/pro-components';
|
||||
|
||||
const ServiceRule: React.FC = () => {
|
||||
return (
|
||||
<ProForm<{
|
||||
name: string;
|
||||
company: string;
|
||||
}>
|
||||
grid
|
||||
onFinish={async (values) => {
|
||||
// await waitTime(2000);
|
||||
console.log(values);
|
||||
// message.success('提交成功');
|
||||
}}
|
||||
initialValues={{
|
||||
name: '蚂蚁设计有限公司',
|
||||
useMode: 'chapter',
|
||||
}}
|
||||
>
|
||||
<ProForm.Group>
|
||||
<ProFormText
|
||||
width="md"
|
||||
name="name"
|
||||
label="签约客户名称"
|
||||
tooltip="最长为 24 位"
|
||||
placeholder="请输入名称"
|
||||
/>
|
||||
<ProFormText
|
||||
width="md"
|
||||
name="company"
|
||||
label="我方公司名称"
|
||||
placeholder="请输入名称"
|
||||
/>
|
||||
</ProForm.Group>
|
||||
<ProFormText width="sm" name="id" label="主合同编号" />
|
||||
<ProForm.Item
|
||||
label="数组数据"
|
||||
name="dataSource"
|
||||
// initialValue={defaultData}
|
||||
trigger="onValuesChange"
|
||||
>
|
||||
{/* <EditableProTable<DataSourceType>
|
||||
rowKey="id"
|
||||
toolBarRender={false}
|
||||
columns={columns}
|
||||
recordCreatorProps={{
|
||||
newRecordType: 'dataSource',
|
||||
position: 'top',
|
||||
record: () => ({
|
||||
id: Date.now(),
|
||||
addonBefore: 'ccccccc',
|
||||
decs: 'testdesc',
|
||||
}),
|
||||
}}
|
||||
editable={{
|
||||
type: 'multiple',
|
||||
editableKeys,
|
||||
onChange: setEditableRowKeys,
|
||||
actionRender: (row, _, dom) => {
|
||||
return [dom.delete];
|
||||
},
|
||||
}} */}
|
||||
{/* /> */}
|
||||
</ProForm.Item>
|
||||
</ProForm>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServiceRule;
|
||||
31
src/pages/prod/list/components/sku/index.tsx
Normal file
31
src/pages/prod/list/components/sku/index.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { ProForm } from '@ant-design/pro-components';
|
||||
import React from 'react';
|
||||
import SkuConfig from './sku-confiig';
|
||||
import SkuList from './sku-list';
|
||||
|
||||
const Sku: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<ProForm.Item
|
||||
style={{ width: '100%' }}
|
||||
name="prodPropSaveReqVO"
|
||||
layout="horizontal"
|
||||
width="xl"
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<SkuConfig />
|
||||
</ProForm.Item>
|
||||
<ProForm.Item
|
||||
style={{ width: '100%' }}
|
||||
name="skuList"
|
||||
layout="horizontal"
|
||||
width="xl"
|
||||
// getValueFromEvent={(e) => e.fileList}
|
||||
>
|
||||
<SkuList />
|
||||
</ProForm.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(Sku);
|
||||
24
src/pages/prod/list/components/sku/sku-confiig.tsx
Normal file
24
src/pages/prod/list/components/sku/sku-confiig.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Typography } from 'antd';
|
||||
import React from 'react';
|
||||
import DraggableTagList from '@/components/Draggable/DraggableTagList';
|
||||
import type { SkuConfig } from '@/services/prod/prod-manager';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const Sku: React.FC<{
|
||||
value?: SkuConfig;
|
||||
onChange?: (value: SkuConfig) => void;
|
||||
}> = (_props) => {
|
||||
// const { value, onChange } = props;
|
||||
return (
|
||||
<>
|
||||
<Title level={4}>规格设置</Title>
|
||||
<Text type="secondary">
|
||||
你想区分商品的哪些属性?第一次使用?<a>点此查看详情</a>
|
||||
学习。商品创建成功后,规格属性不可增减,如需变更规格逻辑定义,请创建新的商品。
|
||||
</Text>
|
||||
<DraggableTagList />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(Sku);
|
||||
22
src/pages/prod/list/components/sku/sku-list.tsx
Normal file
22
src/pages/prod/list/components/sku/sku-list.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Typography } from 'antd';
|
||||
import React from 'react';
|
||||
import type { SkuConfig } from '@/services/prod/prod-manager';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const SkuList: React.FC<{
|
||||
value?: SkuConfig;
|
||||
onChange?: (value: SkuConfig) => void;
|
||||
}> = (props) => {
|
||||
const { value } = props;
|
||||
console.log('value', value);
|
||||
return (
|
||||
<>
|
||||
<Title level={4}>SKU 列表</Title>
|
||||
<Text type="secondary">
|
||||
请填写SKU价格与可售数量,高级设置可自定义更多内容。
|
||||
</Text>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(SkuList);
|
||||
90
src/pages/prod/list/config.tsx
Normal file
90
src/pages/prod/list/config.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import type { ProColumns } from '@ant-design/pro-components';
|
||||
import { Badge, Button, Image, Space, Typography } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import type { Prod } from '@/services/prod/prod-manager';
|
||||
|
||||
const { Text } = Typography;
|
||||
export const baseTenantColumns: ProColumns<Prod>[] = [
|
||||
{
|
||||
title: '商品',
|
||||
dataIndex: 'prodName',
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
<Image width={64} height={64} src={record.pic} />
|
||||
<div>
|
||||
<div>
|
||||
<Text>{record.categoryName}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">ID:{record.categoryName}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">类目:{record.categoryName}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '服务信息',
|
||||
dataIndex: 'categoryId',
|
||||
render: () => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">服务区域:</Text>
|
||||
<Text></Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">服务区域:</Text>
|
||||
<Text></Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">紧急服务:</Text>
|
||||
<Text></Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
valueType: 'switch',
|
||||
width: 300,
|
||||
hideInSearch: true,
|
||||
render: () => (
|
||||
<Space direction="vertical">
|
||||
<Space>
|
||||
<Badge status="success" text="出售中" />
|
||||
<Badge status="default" text="已置灰" />
|
||||
<Badge status="warning" text="待审核" />
|
||||
<Badge status="default" text="仓库中" />
|
||||
</Space>
|
||||
<Button size="small" type="dashed">
|
||||
状态控制
|
||||
</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '时间信息',
|
||||
dataIndex: 'createTime',
|
||||
valueType: 'dateRange',
|
||||
hideInSearch: true, // 在搜索表单中隐藏
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Image></Image> 某某某某有限公司
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">创建时间:</Text>
|
||||
{dayjs(record.createTime).format('YYYY-MM-DD HH:mm:ss')}
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">更新时间:</Text>
|
||||
{dayjs(record.updateTime).format('YYYY-MM-DD HH:mm:ss')}
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
84
src/pages/prod/list/detail.tsx
Normal file
84
src/pages/prod/list/detail.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { FormInstance } from '@ant-design/pro-components';
|
||||
import { ProCard, ProForm, StepsForm } from '@ant-design/pro-components';
|
||||
import { message } from 'antd';
|
||||
import { useEffect } from 'react';
|
||||
import ProdInfo from '@/pages/prod/list/components/prod-info';
|
||||
import Sku from '@/pages/prod/list/components/sku';
|
||||
import type { Prod, ProdDetail, SkuConfig } from '@/services/prod/prod-manager';
|
||||
|
||||
const waitTime = (time: number = 100) => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
}, time);
|
||||
});
|
||||
};
|
||||
|
||||
const ProdDetailPage: React.FC<{
|
||||
data?: Prod;
|
||||
formRef?: React.RefObject<FormInstance<any>>;
|
||||
}> = (props) => {
|
||||
const { data, formRef } = props;
|
||||
console.log(data, 'ProdDetailPage');
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
formRef?.current?.setFieldsValue(data);
|
||||
}
|
||||
}, [data]);
|
||||
return (
|
||||
<ProCard>
|
||||
{data?.prodId ? (
|
||||
<ProForm
|
||||
formRef={formRef}
|
||||
layout="horizontal"
|
||||
grid={true}
|
||||
submitter={false}
|
||||
>
|
||||
<ProdInfo />
|
||||
</ProForm>
|
||||
) : (
|
||||
<StepsForm<ProdDetail>
|
||||
current={0}
|
||||
formRef={formRef}
|
||||
submitter={false}
|
||||
onFinish={async () => {
|
||||
await waitTime(1000);
|
||||
message.success('提交成功');
|
||||
}}
|
||||
formProps={{
|
||||
validateMessages: {
|
||||
required: '此项为必填项',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<StepsForm.StepForm<ProdDetail>
|
||||
grid={true}
|
||||
layout="horizontal"
|
||||
name="info"
|
||||
title="填写商品信息"
|
||||
onFinish={async () => {
|
||||
try {
|
||||
await formRef?.current?.validateFields();
|
||||
console.log(formRef?.current?.getFieldsValue());
|
||||
} catch (error: any) {
|
||||
console.log(error);
|
||||
message.error(error.msg);
|
||||
}
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
<ProdInfo data={data} />
|
||||
</StepsForm.StepForm>
|
||||
<StepsForm.StepForm<SkuConfig> name="sku" title="设置商品规格">
|
||||
<Sku />
|
||||
</StepsForm.StepForm>
|
||||
<StepsForm.StepForm<ProdDetail> name="prod" title="发布商品">
|
||||
提交
|
||||
</StepsForm.StepForm>
|
||||
</StepsForm>
|
||||
)}
|
||||
</ProCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProdDetailPage;
|
||||
@@ -1,5 +1,250 @@
|
||||
import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import type { MenuProps, TabsProps } from 'antd';
|
||||
import { Button, Dropdown, Space, Tabs } from 'antd';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import ConfigurableDrawerForm, {
|
||||
type ConfigurableDrawerFormRef,
|
||||
} from '@/components/DrawerForm';
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import type { ToolbarAction } from '@/components/EnhancedProTable/types';
|
||||
import { formStatusType } from '@/constants';
|
||||
import ProdDetail from '@/pages/prod/list/detail';
|
||||
import {
|
||||
createProd,
|
||||
getProdDetail,
|
||||
getProdPage,
|
||||
type Prod,
|
||||
type ProdReq,
|
||||
updateProd,
|
||||
} from '@/services/prod/prod-manager';
|
||||
import { baseTenantColumns } from './config';
|
||||
|
||||
const ProdList = () => {
|
||||
return <div>ProdList</div>;
|
||||
const tableRef = useRef<ActionType>(null);
|
||||
const [type, setType] = useState<'create' | 'update' | 'test'>('create');
|
||||
const [status, setStatus] = useState<number>();
|
||||
const detailRef = useRef<ConfigurableDrawerFormRef>(null);
|
||||
// const editRef = useRef<ConfigurableDrawerFormRef>(null);
|
||||
const [id, setId] = useState<number>(0);
|
||||
const onChange = useCallback(
|
||||
(key: string) => {
|
||||
setStatus(Number(key));
|
||||
},
|
||||
[status],
|
||||
);
|
||||
|
||||
const onFetch = async (params: ProdReq) => {
|
||||
const data = await getProdPage({
|
||||
...params,
|
||||
status: status ? status : undefined,
|
||||
});
|
||||
return {
|
||||
data: data.list,
|
||||
success: true,
|
||||
};
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
setType('create');
|
||||
detailRef.current?.open({});
|
||||
};
|
||||
|
||||
const toolbarActions: ToolbarAction[] = [
|
||||
{
|
||||
key: 'add',
|
||||
label: '新建',
|
||||
type: 'primary',
|
||||
icon: <PlusOutlined />,
|
||||
onClick: handleAdd,
|
||||
},
|
||||
];
|
||||
const handleEdit = async (row: Prod) => {
|
||||
setType('update');
|
||||
const res = await getProdDetail({ id: row.prodId as number });
|
||||
setId(row.prodId as number);
|
||||
detailRef.current?.open(res);
|
||||
};
|
||||
// 商品更新
|
||||
// const _handleEditSubmit = async (values: Prod) => {
|
||||
// await updateProd(values);
|
||||
// tableRef.current?.reload();
|
||||
// message.success("编辑成功");
|
||||
// return true;
|
||||
// };
|
||||
const handleSubmit = useCallback(
|
||||
async (values: Prod) => {
|
||||
if (type === 'create') {
|
||||
await createProd(values);
|
||||
} else {
|
||||
await updateProd({
|
||||
...values,
|
||||
categoryId: id,
|
||||
});
|
||||
}
|
||||
tableRef.current?.reload();
|
||||
return true;
|
||||
},
|
||||
|
||||
[id, type],
|
||||
);
|
||||
|
||||
// const renderDetailFooter = () => {
|
||||
// if (type === "update") {
|
||||
// return (
|
||||
// <Space>
|
||||
// <Button onClick={() => detailRef.current?.close()}>取消</Button>
|
||||
// <Button type="primary" onClick={handleEditSubmit}>
|
||||
// 确定
|
||||
// </Button>
|
||||
// </Space>
|
||||
// );
|
||||
// } else {
|
||||
// return (
|
||||
// <Button type="primary" onClick={() => detailRef.current?.close()}>
|
||||
// 确定
|
||||
// </Button>
|
||||
// );
|
||||
// }
|
||||
// };
|
||||
const itemsMenu = (row: Prod): MenuProps['items'] => [
|
||||
{
|
||||
key: 'edit',
|
||||
label: (
|
||||
<Button type="link" onClick={() => handleEdit(row)}>
|
||||
商品编辑
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'sku',
|
||||
label: <Button type="link">SKU管理</Button>,
|
||||
},
|
||||
{
|
||||
key: 'rules-service',
|
||||
label: <Button type="link">服务规则编辑</Button>,
|
||||
},
|
||||
{
|
||||
key: 'extend-service',
|
||||
label: <Button type="link">扩展服务管理</Button>,
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
label: <Button type="link">状态控制</Button>,
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
label: (
|
||||
<Button color="danger" variant="link">
|
||||
删除商品
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
const actionColumns: ProColumns<Prod> = {
|
||||
title: '操作',
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
|
||||
width: 200,
|
||||
render: (_text: React.ReactNode, record: Prod, _: number) => [
|
||||
<Space style={{ width: '100%' }} wrap size={0} key={record.prodId}>
|
||||
<Space.Compact direction="vertical" block key="1">
|
||||
<Button type="link" onClick={() => handleEdit(record)}>
|
||||
商品编辑
|
||||
</Button>
|
||||
<Button type="link">SKU管理</Button>
|
||||
</Space.Compact>
|
||||
<Space.Compact direction="vertical" block key="2">
|
||||
<Button type="link">服务规则</Button>
|
||||
<Button type="link">扩展服务</Button>
|
||||
</Space.Compact>
|
||||
<Space.Compact direction="vertical" block key="3">
|
||||
<Dropdown menu={{ items: itemsMenu(record) }} placement="bottomLeft">
|
||||
<Button type="link">
|
||||
<EllipsisOutlined />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</Space.Compact>
|
||||
</Space>,
|
||||
],
|
||||
};
|
||||
|
||||
const columns = [...baseTenantColumns, actionColumns];
|
||||
const renderChildren = () => {
|
||||
return (
|
||||
<>
|
||||
<EnhancedProTable<Prod>
|
||||
ref={tableRef}
|
||||
columns={columns}
|
||||
request={onFetch}
|
||||
toolbarActions={toolbarActions}
|
||||
headerTitle="短信渠道"
|
||||
showIndex={false}
|
||||
rowKey="prodId"
|
||||
showSelection={false}
|
||||
/>
|
||||
|
||||
<ConfigurableDrawerForm
|
||||
ref={detailRef}
|
||||
onSubmit={handleSubmit}
|
||||
// footer={renderDetailFooter()}
|
||||
title={formStatusType[type]}
|
||||
width={'80vw'}
|
||||
bodyStyle={{
|
||||
background: '#f5f5f5',
|
||||
paddingTop: 8,
|
||||
}}
|
||||
>
|
||||
<ProdDetail />
|
||||
</ConfigurableDrawerForm>
|
||||
{/* <ConfigurableDrawerForm
|
||||
ref={editRef}
|
||||
onSubmit={handleEditSubmit}
|
||||
footer={renderDetailFooter()}
|
||||
width={"80vw"}
|
||||
bodyStyle={{
|
||||
background: "#f5f5f5",
|
||||
paddingTop: 8,
|
||||
}}
|
||||
>
|
||||
<ProdDetail />
|
||||
</ConfigurableDrawerForm> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const items: TabsProps['items'] = [
|
||||
{
|
||||
key: '',
|
||||
label: '全部商品',
|
||||
children: renderChildren(),
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
label: '出售中的商品',
|
||||
children: renderChildren(),
|
||||
},
|
||||
{
|
||||
key: '0',
|
||||
label: '仓库中的商品',
|
||||
children: renderChildren(),
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: '待审核的商品',
|
||||
children: renderChildren(),
|
||||
},
|
||||
];
|
||||
return (
|
||||
<Tabs
|
||||
defaultActiveKey={status as unknown as string}
|
||||
items={items}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProdList;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// src/pages/system/menu/index.tsx
|
||||
|
||||
import { PlusOutlined, ReloadOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
PlusOutlined,
|
||||
ReloadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Modal, Popconfirm } from 'antd';
|
||||
@@ -11,8 +15,6 @@ import ConfigurableDrawerForm, {
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import type { ToolbarAction } from '@/components/EnhancedProTable/types';
|
||||
import { formStatusType } from '@/constants';
|
||||
import { useMessage } from '@/hooks/antd/useMessage';
|
||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache';
|
||||
import {
|
||||
createMenu,
|
||||
deleteMenu,
|
||||
@@ -27,11 +29,10 @@ import { baseMenuColumns, formColumns } from './config';
|
||||
const SystemMenu = () => {
|
||||
const configurableDrawerRef = useRef<ConfigurableDrawerFormRef>(null);
|
||||
const tableRef = useRef<ActionType>(null);
|
||||
const { wsCache } = useCache();
|
||||
const message = useMessage(); // 消息弹窗
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const [type, setType] = useState<'create' | 'update'>('create');
|
||||
const [id, setId] = useState<number>(0);
|
||||
const { initialState, setInitialState } = useModel('@@initialState');
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const handleEdit = (record: MenuVO) => {
|
||||
setType('update');
|
||||
setId(record.id);
|
||||
@@ -64,13 +65,18 @@ const SystemMenu = () => {
|
||||
|
||||
const handleReload = async () => {
|
||||
try {
|
||||
await message.confirm('即将更新缓存刷新浏览器!', '刷新菜单缓存');
|
||||
// 清空,从而触发刷新
|
||||
// wsCache.delete(CACHE_KEY.USER);
|
||||
// wsCache.delete(CACHE_KEY.ROLE_ROUTERS);
|
||||
await initialState?.fetchUserInfo?.();
|
||||
// 刷新浏览器
|
||||
location.reload();
|
||||
await modal.confirm({
|
||||
title: '刷新菜单缓存',
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
content: '即将更新缓存刷新浏览器!',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
await initialState?.fetchUserInfo?.();
|
||||
// 刷新浏览器
|
||||
location.reload();
|
||||
},
|
||||
});
|
||||
} catch {}
|
||||
};
|
||||
|
||||
@@ -137,6 +143,7 @@ const SystemMenu = () => {
|
||||
const columns = [...baseMenuColumns, actionColumns];
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
<EnhancedProTable<MenuVO>
|
||||
ref={tableRef}
|
||||
columns={columns}
|
||||
|
||||
@@ -1,43 +1,52 @@
|
||||
import type { ProColumns } from '@ant-design/pro-components';
|
||||
import { Button, Space, Tag, Typography } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import { dateFormat, dateFormatS } from '@/constants';
|
||||
import { Image, Space, Tag, Typography } from 'antd';
|
||||
import type { TradeOrderPageRespVO } from '@/services/trade/order';
|
||||
|
||||
const { Text, Paragraph } = Typography;
|
||||
export const baseOrderColumns: ProColumns<TradeOrderPageRespVO>[] = [
|
||||
{
|
||||
title: '商品',
|
||||
dataIndex: 'spuName',
|
||||
dataIndex: 'items',
|
||||
hideInSearch: true,
|
||||
width: '100%',
|
||||
ellipsis: true,
|
||||
render: (_, record) => (
|
||||
<Paragraph>
|
||||
<Paragraph ellipsis style={{ marginBottom: 0 }}>
|
||||
{record.spuName}
|
||||
</Paragraph>
|
||||
<div>{record.skuName}</div>
|
||||
<Space>
|
||||
<div>
|
||||
<Text type="secondary">数量:</Text>
|
||||
<Text>{record.count}</Text>
|
||||
render: (_, record) => {
|
||||
if (!record.items) {
|
||||
return _;
|
||||
}
|
||||
return record.items.map((item) => (
|
||||
<div
|
||||
style={{ width: '100%', display: 'flex', gap: '8px' }}
|
||||
key={item.id}
|
||||
>
|
||||
<Image src={item.picUrl} width={64} height={64} />
|
||||
<div style={{ flex: '1', overflow: 'hidden' }}>
|
||||
<Paragraph ellipsis style={{ width: '100%', marginBottom: 0 }}>
|
||||
{item.spuName}测试商品名称测试商品名称测试商品名称测试商品名称
|
||||
</Paragraph>
|
||||
<div>{item.skuName}</div>
|
||||
<Space>
|
||||
<div>
|
||||
<Text type="secondary">数量:</Text>
|
||||
<Text>{item.count || 0}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">单价:</Text>
|
||||
<Text>
|
||||
{item.price || 0}/{item.unit || '-'}
|
||||
</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">到手价:</Text>
|
||||
<Text>
|
||||
{item.handedPrice || 0}/{item.unit || '-'}
|
||||
</Text>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">单价:</Text>
|
||||
<Text>
|
||||
{record.price}/{record.unit}
|
||||
</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">到手价:</Text>
|
||||
<Text>
|
||||
{record.handedPrice}/{record.unit}
|
||||
</Text>
|
||||
</div>
|
||||
</Space>
|
||||
</Paragraph>
|
||||
),
|
||||
</div>
|
||||
));
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
@@ -50,7 +59,7 @@ export const baseOrderColumns: ProColumns<TradeOrderPageRespVO>[] = [
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Paragraph ellipsis style={{ marginBottom: 0 }}>
|
||||
<Text type="secondary">预约时间:</Text>
|
||||
<Text>{dayjs(record.subTime).format(dateFormatS)}</Text>
|
||||
<Text>{record?.subTime || '-'}</Text>
|
||||
<Tag style={{ marginLeft: 10 }}>预约</Tag>
|
||||
<Tag color="error" style={{ marginLeft: 10 }}>
|
||||
加急
|
||||
@@ -58,14 +67,11 @@ export const baseOrderColumns: ProColumns<TradeOrderPageRespVO>[] = [
|
||||
</Paragraph>
|
||||
<Paragraph ellipsis style={{ marginBottom: 0 }}>
|
||||
<Text type="secondary">服务地址:</Text>
|
||||
<Text>
|
||||
{record.serveAddress}
|
||||
服务地址:服务地址:服务地址:服务地址:服务地址:服务地址:
|
||||
</Text>
|
||||
<Text>{record.serveAddress || '-'}</Text>
|
||||
</Paragraph>
|
||||
<div>
|
||||
<Text type="secondary">用户备注:</Text>
|
||||
<Text>{record.userRemark}</Text>
|
||||
<Text>{record.userRemark || '-'}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
@@ -74,20 +80,20 @@ export const baseOrderColumns: ProColumns<TradeOrderPageRespVO>[] = [
|
||||
title: '财务',
|
||||
dataIndex: 'price',
|
||||
hideInSearch: true,
|
||||
width: '100',
|
||||
width: '100%',
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">实付金额:</Text>
|
||||
<Text>{record.payPrice}</Text>
|
||||
<Text>{record?.payPrice || '-'}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">支付方式:</Text>
|
||||
<Text>{record.payType}</Text>
|
||||
<Text>{record.payType || '-'}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">财务状态:</Text>
|
||||
<Text>{record.financeStatus}</Text>
|
||||
<Text>{record.financeStatus || '-'}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
|
||||
@@ -1,23 +1,36 @@
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { Avatar, Button, Card, Empty, Space, Steps, Typography } from 'antd';
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Card,
|
||||
Divider,
|
||||
Empty,
|
||||
Space,
|
||||
Steps,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import RcResizeObserver from 'rc-resize-observer';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { OrderStatus, OrderStatusLabels } from '@/constants/trade';
|
||||
import type { TradeOrderBaseInfo } from '@/services/trade/order';
|
||||
import type {
|
||||
TradeOrderDetailRespVO,
|
||||
TradeOrderStatusRespVo,
|
||||
} from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../order-info';
|
||||
import { type BtnType, renderBaseInfoOrder } from './config';
|
||||
import styles from './index.module.less';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const BasicInfo: React.FC<{ data?: TradeOrderBaseInfo; id: number }> = (
|
||||
props,
|
||||
) => {
|
||||
const { data } = props;
|
||||
const { Text } = Typography;
|
||||
const BasicInfo: React.FC<ItemConfig<TradeOrderDetailRespVO>> = (props) => {
|
||||
const { data, loading } = props;
|
||||
const [orderStatus, setOrderStatus] = useState<number>(0);
|
||||
const [statusList, setStatusList] = useState<TradeOrderStatusRespVo[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setOrderStatus(Number(data.orderStatus));
|
||||
setStatusList(data?.statusList || []);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
@@ -27,22 +40,24 @@ const BasicInfo: React.FC<{ data?: TradeOrderBaseInfo; id: number }> = (
|
||||
<Space size={16}>
|
||||
<div>
|
||||
<Text type="secondary">订单编号:</Text>
|
||||
<Text copyable>{data?.orderNo}</Text>
|
||||
<Text copyable>{data?.orderNum}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">订单类目:</Text>
|
||||
<Text>{data?.orderCategoryId}</Text>
|
||||
<Text>{data?.orderCategoryName}</Text>
|
||||
<Text>ID:</Text>
|
||||
<Text copyable>{data?.id}</Text>
|
||||
<Divider type="vertical" />
|
||||
<Text copyable>{data?.orderCategoryId}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">订单来源:</Text>
|
||||
<Text>{data?.orderCategoryName}</Text>
|
||||
<Text>{data?.orderTerminal}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Space>
|
||||
<Avatar size={20} src={data?.userAvatar} />
|
||||
<Text>{data?.userInfo}</Text>
|
||||
</div>
|
||||
<Text>{data?.userName || data?.userNickName}</Text>
|
||||
<Text>{data?.userMobile}</Text>
|
||||
</Space>
|
||||
</Space>
|
||||
);
|
||||
}, [data]);
|
||||
@@ -65,128 +80,184 @@ const BasicInfo: React.FC<{ data?: TradeOrderBaseInfo; id: number }> = (
|
||||
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="基本信息">
|
||||
{data ? (
|
||||
<Card title="基本信息" loading={loading}>
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
{data ? (
|
||||
<ProCard
|
||||
size="small"
|
||||
title={renderTitle()}
|
||||
bordered
|
||||
headerBordered
|
||||
gutter={8}
|
||||
className="order-info-card"
|
||||
>
|
||||
<ProCard colSpan="300px">
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 10,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{renderOrderStatus}
|
||||
</div>
|
||||
</ProCard>
|
||||
<ProCard layout="center">
|
||||
<RcResizeObserver
|
||||
key="resize-observer"
|
||||
onResize={(offset) => {
|
||||
setResponsive(offset.width < 460);
|
||||
}}
|
||||
>
|
||||
<Steps
|
||||
size="small"
|
||||
progressDot
|
||||
style={{ width: '100%' }}
|
||||
current={statusList.length}
|
||||
direction={responsive ? 'vertical' : 'horizontal'}
|
||||
items={[
|
||||
{
|
||||
title: `创建订单`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{dayjs(data.createTime).format('YYYY-MM-DD')}
|
||||
{dayjs(data.createTime).format('HH:mm:ss')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingPayment].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingPayment
|
||||
? '(已付款)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{dayjs(data.createTime).format('YYYY-MM-DD')}
|
||||
{dayjs(data.createTime).format('HH:mm:ss')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingConfirmation]
|
||||
.label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingConfirmation
|
||||
? '(已确定)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{/* {dayjs(data.finishTime).format("YYYY-MM-DD")}
|
||||
{dayjs(data.finishTime).format("HH:mm:ss")} */}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingService].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingService
|
||||
? '(已开始)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{/* {dayjs(data.finishTime).format("YYYY-MM-DD")}
|
||||
{dayjs(data.finishTime).format("HH:mm:ss")} */}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingAcceptance].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingAcceptance
|
||||
? '(已验收)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{/* {dayjs(data.finishTime).format("YYYY-MM-DD")}
|
||||
{dayjs(data.finishTime).format("HH:mm:ss")} */}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '完成',
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{dayjs(data.finishTime).format('YYYY-MM-DD')}
|
||||
{dayjs(data.finishTime).format('HH:mm:ss')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</RcResizeObserver>
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
) : (
|
||||
<Empty />
|
||||
)}
|
||||
<ProCard
|
||||
size="small"
|
||||
title={renderTitle()}
|
||||
bordered
|
||||
headerBordered
|
||||
title="订单付款信息"
|
||||
gutter={8}
|
||||
className="order-info-card"
|
||||
extra={<Button size="small">财务状态:{data?.financeStatus}</Button>}
|
||||
>
|
||||
<ProCard colSpan="300px">
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 10,
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{renderOrderStatus}
|
||||
</div>
|
||||
<ProCard>
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">订单总价:</Text>
|
||||
<Text>{data?.price}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">优惠总额:</Text>
|
||||
<Text>{data?.discountPrice}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">实付金额:</Text>
|
||||
<Text>{data?.payPrice}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">累计退款金额:</Text>
|
||||
<Text>{data?.refundPrice}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">最终实收金额:</Text>
|
||||
<Text>{data?.livePrice}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
</ProCard>
|
||||
<ProCard layout="center">
|
||||
<RcResizeObserver
|
||||
key="resize-observer"
|
||||
onResize={(offset) => {
|
||||
setResponsive(offset.width < 460);
|
||||
}}
|
||||
>
|
||||
<Steps
|
||||
size="small"
|
||||
progressDot
|
||||
style={{ width: '100%' }}
|
||||
current={orderStatus / 10}
|
||||
direction={responsive ? 'vertical' : 'horizontal'}
|
||||
items={[
|
||||
{
|
||||
title: `创建订单`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{dayjs(data.createTime).format('YYYY-MM-DD')}
|
||||
{dayjs(data.createTime).format('HH:mm:ss')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingPayment].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingPayment
|
||||
? '(已付款)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{dayjs(data.createTime).format('YYYY-MM-DD')}
|
||||
{dayjs(data.createTime).format('HH:mm:ss')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingConfirmation].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingConfirmation
|
||||
? '(已确定)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{/* {dayjs(data.finishTime).format("YYYY-MM-DD")}
|
||||
{dayjs(data.finishTime).format("HH:mm:ss")} */}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingService].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingService
|
||||
? '(已开始)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{/* {dayjs(data.finishTime).format("YYYY-MM-DD")}
|
||||
{dayjs(data.finishTime).format("HH:mm:ss")} */}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: `${
|
||||
OrderStatusLabels[OrderStatus.PendingAcceptance].label
|
||||
} ${
|
||||
orderStatus > OrderStatus.PendingAcceptance
|
||||
? '(已验收)'
|
||||
: ''
|
||||
}`,
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{/* {dayjs(data.finishTime).format("YYYY-MM-DD")}
|
||||
{dayjs(data.finishTime).format("HH:mm:ss")} */}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '完成',
|
||||
description: (
|
||||
<Space direction="vertical" size={0}>
|
||||
{dayjs(data.finishTime).format('YYYY-MM-DD')}
|
||||
{dayjs(data.finishTime).format('HH:mm:ss')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</RcResizeObserver>
|
||||
<ProCard>
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">支付方式:</Text>
|
||||
<Text>{data?.payType}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">支付渠道:</Text>
|
||||
<Text>{data?.payChannelCode}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">支付时间:</Text>
|
||||
<Text>{data?.payTime}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">交易流水:</Text>
|
||||
<Text>{data?.payOrderId}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
) : (
|
||||
<Empty />
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,30 +9,10 @@ import {
|
||||
OrderStatusLabels,
|
||||
} from '@/constants/trade';
|
||||
import type { DeptVO } from '@/services/system/dept';
|
||||
import type { TradeOrderBaseInfo } from '@/services/trade/order';
|
||||
import type { TradeOrderDetailRespVO } from '@/services/trade/order';
|
||||
|
||||
const { Title, Text, Paragraph } = Typography;
|
||||
|
||||
export const baseOrderColumns: ProColumns<DeptVO>[] = [
|
||||
{
|
||||
title: '商品',
|
||||
dataIndex: 'name',
|
||||
width: '33.33%',
|
||||
render: (_, record) => (
|
||||
<Tag color={record.status === 1 ? 'green' : 'red'}>{record.name}</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '服务',
|
||||
dataIndex: 'leaderUserId',
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: '财务',
|
||||
dataIndex: 'sort',
|
||||
hideInSearch: true,
|
||||
},
|
||||
];
|
||||
const sharedOnCell = (_: DeptVO, index?: number) => {
|
||||
if (index === 3) {
|
||||
return { colSpan: 0 };
|
||||
@@ -77,17 +57,17 @@ export const surchargeInfoColumns: ProColumns<DeptVO>[] = [
|
||||
export type BtnType = 'sales' | 'confirm';
|
||||
|
||||
export const renderBaseInfoOrder = (
|
||||
data: TradeOrderBaseInfo,
|
||||
data: TradeOrderDetailRespVO,
|
||||
handleClick: (type: BtnType) => void,
|
||||
): React.ReactNode => {
|
||||
const orderStatusObj =
|
||||
OrderStatusLabels[data.orderStatus as unknown as OrderStatus];
|
||||
const orderStatusObj = data.orderStatus
|
||||
? OrderStatusLabels[data.orderStatus as unknown as OrderStatus]
|
||||
: { color: 'default', label: '未知' };
|
||||
|
||||
console.log(orderStatusObj, data);
|
||||
return (
|
||||
<>
|
||||
<Title
|
||||
type={(orderStatusObj.color as BaseType) || ''}
|
||||
type={(orderStatusObj?.color as BaseType) || ''}
|
||||
level={4}
|
||||
style={{ margin: 0 }}
|
||||
>
|
||||
@@ -101,7 +81,7 @@ export const renderBaseInfoOrder = (
|
||||
Number(data.orderStatus) === OrderStatus.Refunded && (
|
||||
<Paragraph>
|
||||
<Text type="secondary">退款时间:</Text>
|
||||
<Text>退款时间</Text>
|
||||
<Text>{data.refundTime}</Text>
|
||||
</Paragraph>
|
||||
)}
|
||||
{data.orderStatus &&
|
||||
|
||||
20
src/pages/trade/order/detail/component/info/extend-cost.tsx
Normal file
20
src/pages/trade/order/detail/component/info/extend-cost.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Card } from 'antd';
|
||||
import React from 'react';
|
||||
import type { TradeExtendCostInfo } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../order-info';
|
||||
import styles from './index.module.less';
|
||||
import ExtendCost from './uis/pets/extend-cost';
|
||||
|
||||
const EntendCostInfo: React.FC<ItemConfig<TradeExtendCostInfo[]>> = (props) => {
|
||||
const { data = [], orderCategoryId } = props;
|
||||
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="服务信息">
|
||||
{orderCategoryId === 1 && <ExtendCost data={data} />}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(EntendCostInfo);
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import type { TradeExtendServeInfo } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../order-info';
|
||||
import styles from './index.module.less';
|
||||
import ExtendServicePets from './uis/pets/extend-service';
|
||||
|
||||
const ExtendService: React.FC<ItemConfig<TradeExtendServeInfo[][]>> = (
|
||||
props,
|
||||
) => {
|
||||
const { data = [], orderCategoryId } = props;
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
{orderCategoryId === 1 && <ExtendServicePets data={data} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ExtendService);
|
||||
@@ -2,6 +2,7 @@
|
||||
:global {
|
||||
.ant-pro-card-header {
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
min-height: 41px;
|
||||
}
|
||||
.ant-pro-card-col {
|
||||
flex: 1 auto;
|
||||
@@ -21,10 +22,13 @@
|
||||
.ant-pro-card-body {
|
||||
padding: 0px;
|
||||
}
|
||||
.ant-steps-item-icon {
|
||||
height: 8px !important;
|
||||
line-height: 8px !important;
|
||||
.ant-steps-dot {
|
||||
.ant-steps-item-icon {
|
||||
height: 8px !important;
|
||||
line-height: 8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-steps-item-active {
|
||||
.ant-steps-icon-dot {
|
||||
height: 10px !important;
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { Button, Card, Image, Space, Tag, Typography } from 'antd';
|
||||
import React, { useCallback } from 'react';
|
||||
import type { TradeProductInfo } from '@/services/trade/order';
|
||||
|
||||
import { fallback } from '@/constants/antd/image';
|
||||
import type { Item } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../order-info';
|
||||
import styles from './index.module.less';
|
||||
|
||||
const { Text, Paragraph } = Typography;
|
||||
const ProdInfo: React.FC<{ data?: TradeProductInfo; id: number }> = (props) => {
|
||||
const { data = {}, id } = props;
|
||||
const renderTitle = useCallback(() => {
|
||||
const ProdInfo: React.FC<ItemConfig<Item[]>> = (props) => {
|
||||
const { data = [] } = props;
|
||||
const renderTitle = useCallback((item: Item) => {
|
||||
return (
|
||||
<Space style={{ height: '100%' }} size={16}>
|
||||
<Paragraph className="order-paragraph">百业到家</Paragraph>
|
||||
<Paragraph className="order-paragraph">{item.shopName}</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary"> 商品 ID:</Text>
|
||||
<Text copyable>8877777</Text>
|
||||
<Text copyable>{item.spuId}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">SKU ID:</Text>
|
||||
<Text copyable>8877777</Text>
|
||||
<Text copyable>{item.skuId}</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
);
|
||||
@@ -26,109 +27,119 @@ const ProdInfo: React.FC<{ data?: TradeProductInfo; id: number }> = (props) => {
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="商品信息">
|
||||
<ProCard
|
||||
size="small"
|
||||
title={renderTitle()}
|
||||
bordered
|
||||
headerBordered
|
||||
gutter={8}
|
||||
extra={<Button size="small">交易快照</Button>}
|
||||
>
|
||||
{data?.map((item) => (
|
||||
<ProCard
|
||||
layout="default"
|
||||
colSpan={'50%'}
|
||||
style={{ borderRight: '1px solid rgba(5,5,5,0.06)' }}
|
||||
key={item.id}
|
||||
size="small"
|
||||
title={renderTitle(item)}
|
||||
bordered
|
||||
headerBordered
|
||||
gutter={8}
|
||||
extra={<Button size="small">交易快照</Button>}
|
||||
>
|
||||
<Space>
|
||||
<Image
|
||||
width={64}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
<div>
|
||||
<Text>商品名称</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text>规格:</Text>
|
||||
<Text type="secondary"> 标准,单独火化,基础清洁</Text>
|
||||
</Paragraph>
|
||||
<Space wrap size={0} direction="horizontal">
|
||||
<Paragraph
|
||||
className="order-paragraph"
|
||||
style={{ marginRight: 16 }}
|
||||
>
|
||||
<Text type="secondary">数量:</Text>
|
||||
<Text> 1</Text>
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
className="order-paragraph"
|
||||
style={{ marginRight: 16 }}
|
||||
>
|
||||
<Text type="secondary">单价:</Text>
|
||||
<Text> ¥100 件</Text>
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
className="order-paragraph"
|
||||
style={{ marginRight: 16 }}
|
||||
>
|
||||
<Text type="secondary">到手价:</Text>
|
||||
<Text> ¥80 件</Text>
|
||||
</Paragraph>
|
||||
<ProCard
|
||||
layout="default"
|
||||
colSpan={'50%'}
|
||||
style={{ borderRight: '1px solid rgba(5,5,5,0.06)' }}
|
||||
>
|
||||
<Space>
|
||||
<Image width={64} src={item.shopLogo} fallback={fallback} />
|
||||
<div>
|
||||
<Text>{item.shopName}</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">成本价:</Text>
|
||||
<Text> ¥50 件/-</Text>
|
||||
<Text>规格:</Text>
|
||||
<Text type="secondary"> {item.skuName}</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</div>
|
||||
</Space>
|
||||
<Paragraph style={{ marginTop: 16 }}>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">商品描述:</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品
|
||||
<Space wrap size={0} direction="horizontal">
|
||||
<Paragraph
|
||||
className="order-paragraph"
|
||||
style={{ marginRight: 16 }}
|
||||
>
|
||||
<Text type="secondary">数量:</Text>
|
||||
<Text> {item.count}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
className="order-paragraph"
|
||||
style={{ marginRight: 16 }}
|
||||
>
|
||||
<Text type="secondary">单价:</Text>
|
||||
<Text>
|
||||
¥{item.price}
|
||||
{item.unit}
|
||||
</Text>
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
className="order-paragraph"
|
||||
style={{ marginRight: 16 }}
|
||||
>
|
||||
<Text type="secondary">到手价:</Text>
|
||||
<Text>
|
||||
{' '}
|
||||
¥{item.handedPrice} {item.unit}
|
||||
</Text>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">成本价:</Text>
|
||||
<Text>
|
||||
{' '}
|
||||
¥{item.expensePrice} {item.unit}/-
|
||||
</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</div>
|
||||
</Space>
|
||||
<Paragraph style={{ marginTop: 16 }}>
|
||||
{item.properties}
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
<Tag>标签</Tag>
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">商品描述:</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
{item.serveContent}
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
</ProCard>
|
||||
<ProCard
|
||||
style={{
|
||||
borderRight: '1px solid rgba(5,5,5,0.06)',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<Space direction="vertical">
|
||||
<Text>付款信息</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</ProCard>
|
||||
<ProCard>
|
||||
<Space direction="vertical">
|
||||
<Text>退款信息</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">累计退款金额:</Text>
|
||||
<Text>¥{item.refundPrice}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">累计退款数量:</Text>
|
||||
<Text>{item.refundCount}</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
<ProCard
|
||||
style={{
|
||||
borderRight: '1px solid rgba(5,5,5,0.06)',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<Space direction="vertical">
|
||||
<Text>付款信息</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</ProCard>
|
||||
<ProCard>
|
||||
<Space direction="vertical">
|
||||
<Text>退款信息</Text>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">累计退款金额:</Text>
|
||||
<Text>¥500</Text>
|
||||
</Paragraph>
|
||||
<Paragraph className="order-paragraph">
|
||||
<Text type="secondary">累计退款数量:</Text>
|
||||
<Text>1</Text>
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
))}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { Card, Space } from 'antd';
|
||||
import React from 'react';
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import {
|
||||
type DeptReqVO,
|
||||
type DeptVO,
|
||||
getDeptPage,
|
||||
} from '@/services/system/dept';
|
||||
import type { TradeExtendCostInfo } from '@/services/trade/order';
|
||||
import { baseOrderColumns } from '../../../config';
|
||||
import styles from './index.module.less';
|
||||
|
||||
const SelectInfo: React.FC<{ data?: TradeExtendCostInfo; id: number }> = (
|
||||
props,
|
||||
) => {
|
||||
const { data = {}, id } = props;
|
||||
const onFetch = async (
|
||||
params: DeptReqVO & {
|
||||
pageSize?: number;
|
||||
current?: number;
|
||||
},
|
||||
) => {
|
||||
const data = await getDeptPage({
|
||||
...params,
|
||||
pageNo: params.current,
|
||||
pageSize: params.pageSize,
|
||||
});
|
||||
return {
|
||||
data: data,
|
||||
success: true,
|
||||
total: data.total,
|
||||
};
|
||||
};
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="可选服务">
|
||||
<Space direction="vertical" style={{ width: '100%' }} size={16}>
|
||||
<ProCard split="vertical" bordered>
|
||||
<ProCard size="small" title="服务" headerBordered>
|
||||
1111
|
||||
</ProCard>
|
||||
<ProCard size="small" title="付款信息" headerBordered>
|
||||
1111
|
||||
</ProCard>
|
||||
<ProCard size="small" title="退款信息" headerBordered>
|
||||
1111
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
|
||||
<EnhancedProTable<DeptVO>
|
||||
columns={baseOrderColumns}
|
||||
request={onFetch}
|
||||
showIndex={false}
|
||||
size="small"
|
||||
search={false}
|
||||
showActions={false}
|
||||
showSelection={false}
|
||||
bordered
|
||||
pagination={false}
|
||||
/>
|
||||
|
||||
<ProCard split="vertical" bordered>
|
||||
<ProCard size="small" title="纪念品" headerBordered>
|
||||
1111
|
||||
</ProCard>
|
||||
<ProCard size="small" title="付款信息" headerBordered>
|
||||
1111
|
||||
</ProCard>
|
||||
<ProCard size="small" title="退款摘要" headerBordered>
|
||||
1111
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
</Space>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(SelectInfo);
|
||||
@@ -1,102 +1,11 @@
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { Button, Card, Image, Space, Typography } from 'antd';
|
||||
import React from 'react';
|
||||
import type { TradeServeInfo } from '@/services/trade/order';
|
||||
import styles from './index.module.less';
|
||||
import type { TradeServeInfo } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../order-info';
|
||||
import ServicePetUI from './uis/pets/service';
|
||||
|
||||
const { Text, Paragraph } = Typography;
|
||||
const ServiceInfo: React.FC<{ data?: TradeServeInfo; id: number }> = (
|
||||
props,
|
||||
) => {
|
||||
const { data = {}, id } = props;
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="服务信息">
|
||||
<ProCard split="vertical">
|
||||
<ProCard
|
||||
title="遗体信息"
|
||||
extra={<Button size="small">修改记录</Button>}
|
||||
size="small"
|
||||
colSpan="30%"
|
||||
headerBordered
|
||||
>
|
||||
<Paragraph>
|
||||
<Text type="secondary">姓名:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">宠物品种:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">体型/体重:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">离世时间:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">离世原因:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">遗体照片:</Text>
|
||||
<Space wrap>
|
||||
<Image
|
||||
width={48}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
<Image
|
||||
width={48}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
<Image
|
||||
width={48}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
<Image
|
||||
width={48}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
<Image
|
||||
width={48}
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
/>
|
||||
</Space>
|
||||
</Paragraph>
|
||||
</ProCard>
|
||||
<ProCard
|
||||
size="small"
|
||||
title="预约信息"
|
||||
headerBordered
|
||||
extra={<Button size="small">修改记录</Button>}
|
||||
>
|
||||
<Paragraph>
|
||||
<Text type="secondary">离世时间:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">更改规则:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">预约时间:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">用户备注:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">客服备注:</Text>
|
||||
<Text>钱多多</Text>
|
||||
</Paragraph>
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
const ServiceInfo: React.FC<ItemConfig<TradeServeInfo>> = (props) => {
|
||||
const { data = {}, orderCategoryId } = props;
|
||||
return <>{orderCategoryId === 1 && <ServicePetUI data={data} />}</>; //宠物服务ui
|
||||
};
|
||||
|
||||
export default React.memo(ServiceInfo);
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Card } from 'antd';
|
||||
import React from 'react';
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import {
|
||||
type DeptReqVO,
|
||||
type DeptVO,
|
||||
getDeptPage,
|
||||
} from '@/services/system/dept';
|
||||
import type { TradeExtendServeInfo } from '@/services/trade/order';
|
||||
import { surchargeInfoColumns } from './config';
|
||||
import styles from './index.module.less';
|
||||
|
||||
const SurchargeInfo: React.FC<{ data?: TradeExtendServeInfo; id: number }> = (
|
||||
props,
|
||||
) => {
|
||||
const { data, id } = props;
|
||||
const onFetch = async (
|
||||
params: DeptReqVO & {
|
||||
pageSize?: number;
|
||||
current?: number;
|
||||
},
|
||||
) => {
|
||||
const data = await getDeptPage({
|
||||
...params,
|
||||
pageNo: params.current,
|
||||
pageSize: params.pageSize,
|
||||
});
|
||||
return {
|
||||
data: data,
|
||||
success: true,
|
||||
total: data.total,
|
||||
};
|
||||
};
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="服务信息">
|
||||
<EnhancedProTable<DeptVO>
|
||||
columns={surchargeInfoColumns}
|
||||
request={onFetch}
|
||||
showIndex={false}
|
||||
size="small"
|
||||
search={false}
|
||||
showActions={false}
|
||||
showSelection={false}
|
||||
bordered
|
||||
pagination={false}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(SurchargeInfo);
|
||||
233
src/pages/trade/order/detail/component/info/uis/pets/config.tsx
Normal file
233
src/pages/trade/order/detail/component/info/uis/pets/config.tsx
Normal file
@@ -0,0 +1,233 @@
|
||||
import type { ProColumns } from '@ant-design/pro-components';
|
||||
import { Image, Space, Typography } from 'antd';
|
||||
import { fallback } from '@/constants/antd/image';
|
||||
import type {
|
||||
TradeExtendCostInfo,
|
||||
TradeExtendServeInfo,
|
||||
} from '@/services/trade/order/detail';
|
||||
|
||||
const { Text } = Typography;
|
||||
const sharedOnCell = (record: TradeExtendServeInfo) => {
|
||||
if (record.deliveryType) {
|
||||
return { colSpan: 0 };
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
export const baseOrderColumns: ProColumns<TradeExtendServeInfo>[] = [
|
||||
{
|
||||
title: '服务',
|
||||
dataIndex: 'serve',
|
||||
width: '33.33%',
|
||||
onCell: (record) => {
|
||||
if (record.deliveryType) {
|
||||
return {
|
||||
colSpan: 3,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
},
|
||||
render: (_, record) => {
|
||||
if (record.deliveryType) {
|
||||
return (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">配送方式:</Text>
|
||||
<Text>{record.deliveryType}</Text>
|
||||
</div>
|
||||
{record.receiveUser && (
|
||||
<div>
|
||||
<Text type="secondary">收货人:</Text>
|
||||
<Text>{record.receiveUser}</Text>
|
||||
</div>
|
||||
)}
|
||||
{record.sendUser && (
|
||||
<div>
|
||||
<Text type="secondary">提货人:</Text>
|
||||
<Text>{record.sendUser}</Text>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<Text type="secondary">手机号码:</Text>
|
||||
<Text>{record?.userMobile}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">地址信息:</Text>
|
||||
<Text>{record.address}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
);
|
||||
} else if (record.tempType === 3) {
|
||||
return (
|
||||
<div>
|
||||
<Text type="secondary">{record.serveTitle}:</Text>
|
||||
<Text>{record.serveType}</Text>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Space size={8} direction="vertical">
|
||||
{record.serve?.map((serve, index) => (
|
||||
<Space size={8} key={`${index}-${Math.random()}`}>
|
||||
<Image
|
||||
src={serve.serveUrl}
|
||||
width={50}
|
||||
height={50}
|
||||
fallback={fallback}
|
||||
/>
|
||||
<div>
|
||||
<div>{serve.serveName}</div>
|
||||
<Text type="secondary">{serve.serveDesc}</Text>
|
||||
<div>
|
||||
<Text type="secondary">数量:</Text>
|
||||
<Text>{serve.count}</Text>
|
||||
<Text type="secondary">单价:</Text>
|
||||
<Text>{serve.price}</Text>
|
||||
<Text type="secondary">到手价:</Text>
|
||||
<Text>{serve.handPrice}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</Space>
|
||||
))}
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '付款信息',
|
||||
dataIndex: 'payPrice',
|
||||
hideInSearch: true,
|
||||
onCell: sharedOnCell,
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">商品总价:</Text>
|
||||
<Text>{record.totalPrice}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">优惠金额:</Text>
|
||||
<Text>{record.discountPrice}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">实付金额:</Text>
|
||||
<Text>{record.payPrice}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '退款信息',
|
||||
dataIndex: 'refundMoney',
|
||||
hideInSearch: true,
|
||||
onCell: sharedOnCell,
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">累计退款金额:</Text>
|
||||
<Text>{record.refundMoney}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">累计退款数量:</Text>
|
||||
<Text>{record.refundCount}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export const extendCost: ProColumns<TradeExtendCostInfo>[] = [
|
||||
{
|
||||
title: '服务附加费',
|
||||
dataIndex: 'serveExtFee',
|
||||
},
|
||||
{
|
||||
title: '费用详情',
|
||||
dataIndex: 'leaderUserId',
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">费用名称:</Text>
|
||||
<Text>{record.costName}</Text>
|
||||
</div>
|
||||
{record.serveArea && (
|
||||
<div>
|
||||
<Text type="secondary">可服务区域:</Text>
|
||||
<Text>{record.serveArea}</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{record.targetArea && (
|
||||
<div>
|
||||
<Text type="secondary">目标区域:</Text>
|
||||
<Text>{record.targetArea}</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{record.weight && (
|
||||
<div>
|
||||
<Text type="secondary">体型/体重:</Text>
|
||||
<Text>{record.weight}</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{record.respTime && (
|
||||
<div>
|
||||
<Text type="secondary">响应时间:</Text>
|
||||
<Text>{record.respTime}</Text>
|
||||
</div>
|
||||
)}
|
||||
{record.respMode && (
|
||||
<div>
|
||||
<Text type="secondary">响应模式:</Text>
|
||||
<Text>{record.respMode || '-'}</Text>
|
||||
</div>
|
||||
)}
|
||||
{record.chargeTime && (
|
||||
<div>
|
||||
<Text type="secondary">收费时段:</Text>
|
||||
<Text>{record.chargeTime}</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Text type="secondary">收费方式:</Text>
|
||||
<Text>{record.chargeType || '-'}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '付款信息',
|
||||
dataIndex: 'payInfo',
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">服务总价:</Text>
|
||||
<Text>¥{record.payInfo?.totalPrice || 0}</Text>
|
||||
</div>
|
||||
<div>
|
||||
<Text type="secondary">优惠金额:</Text>
|
||||
<Text>¥{record.payInfo?.discountPrice || 0}</Text>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text type="secondary">实付金额:</Text>
|
||||
<Text>¥{record.payInfo?.payPrice || 0}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '退款信息',
|
||||
dataIndex: 'refundPrice',
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical">
|
||||
<div>
|
||||
<Text type="secondary">累计退款金额:</Text>
|
||||
<Text>¥{record.refundPrice || 0}</Text>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import type { TradeExtendCostInfo } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../../../order-info';
|
||||
import { extendCost } from './config';
|
||||
|
||||
const ExtendCost: React.FC<ItemConfig<TradeExtendCostInfo[]>> = (props) => {
|
||||
const { data } = props;
|
||||
return (
|
||||
<EnhancedProTable<TradeExtendCostInfo>
|
||||
columns={extendCost}
|
||||
dataSource={data}
|
||||
showIndex={false}
|
||||
size="small"
|
||||
search={false}
|
||||
showActions={false}
|
||||
showSelection={false}
|
||||
bordered
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ExtendCost);
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Card } from 'antd';
|
||||
import React from 'react';
|
||||
import EnhancedProTable from '@/components/EnhancedProTable';
|
||||
import type { TradeExtendServeInfo } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../../../order-info';
|
||||
import { baseOrderColumns } from './config';
|
||||
|
||||
const ExtendServicePet: React.FC<ItemConfig<TradeExtendServeInfo[][]>> = (
|
||||
props,
|
||||
) => {
|
||||
const { data = [] } = props;
|
||||
return (
|
||||
<Card title="可选服务">
|
||||
<div style={{ display: 'flex', gap: '16px', flexDirection: 'column' }}>
|
||||
{data.map((item, index) => (
|
||||
<EnhancedProTable<TradeExtendServeInfo>
|
||||
key={`${index}-${Math.random()}`}
|
||||
columns={baseOrderColumns}
|
||||
dataSource={item}
|
||||
showIndex={false}
|
||||
size="small"
|
||||
search={false}
|
||||
showActions={false}
|
||||
showSelection={false}
|
||||
bordered
|
||||
pagination={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ExtendServicePet);
|
||||
106
src/pages/trade/order/detail/component/info/uis/pets/service.tsx
Normal file
106
src/pages/trade/order/detail/component/info/uis/pets/service.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import { ClockCircleOutlined, EnvironmentOutlined } from '@ant-design/icons';
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { Button, Card, Image, Space, Timeline, Typography } from 'antd';
|
||||
import React from 'react';
|
||||
import { fallback } from '@/constants/antd/image';
|
||||
import type { TradeServeInfo } from '@/services/trade/order/detail';
|
||||
import type { ItemConfig } from '../../../../order-info';
|
||||
import styles from '../../index.module.less';
|
||||
|
||||
const { Text, Paragraph } = Typography;
|
||||
const ServicePetUI: React.FC<ItemConfig<TradeServeInfo>> = (props) => {
|
||||
const { data = {} } = props;
|
||||
const { boneInfo, subInfo } = data;
|
||||
return (
|
||||
<div className={styles['order-info']}>
|
||||
<Card title="服务信息">
|
||||
<ProCard split="vertical" bordered>
|
||||
<ProCard title="遗体信息" size="small" colSpan="30%" headerBordered>
|
||||
<Paragraph>
|
||||
<Text type="secondary">姓名:</Text>
|
||||
<Text>{boneInfo?.petName}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">宠物品种:</Text>
|
||||
<Text>{boneInfo?.petType}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">体型/体重:</Text>
|
||||
<Text>{boneInfo?.weight}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">离世时间:</Text>
|
||||
<Text>{boneInfo?.diedTime}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">离世原因:</Text>
|
||||
<Text>{boneInfo?.diedReason}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">遗体照片:</Text>
|
||||
<Space wrap>
|
||||
{data.boneInfo?.boneUrl?.map((item: string, index: number) => (
|
||||
<Image
|
||||
width={48}
|
||||
src={item}
|
||||
key={`${index}-${Math.random()}`}
|
||||
fallback={fallback}
|
||||
/>
|
||||
))}
|
||||
</Space>
|
||||
</Paragraph>
|
||||
</ProCard>
|
||||
<ProCard
|
||||
size="small"
|
||||
title="预约信息"
|
||||
headerBordered
|
||||
extra={<Button size="small">修改记录</Button>}
|
||||
>
|
||||
<Space size={100}>
|
||||
<div>
|
||||
<Paragraph>
|
||||
<Text type="secondary">预约类型:</Text>
|
||||
<Text>{subInfo?.subType}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">更改规则:</Text>
|
||||
<Text>{subInfo?.changeRule}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">预约时间:</Text>
|
||||
<Text>{subInfo?.subOrder}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">用户备注:</Text>
|
||||
<Text>{subInfo?.userRemark}</Text>
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Text type="secondary">客服备注:</Text>
|
||||
<Text>{subInfo?.merchantRemark}</Text>
|
||||
</Paragraph>
|
||||
</div>
|
||||
<Timeline
|
||||
items={[
|
||||
{
|
||||
dot: (
|
||||
<ClockCircleOutlined className="timeline-clock-icon" />
|
||||
),
|
||||
color: 'green',
|
||||
children: subInfo?.pickUpAddress,
|
||||
},
|
||||
{
|
||||
dot: <EnvironmentOutlined />,
|
||||
children: subInfo?.pickUpAddress,
|
||||
color: 'red',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Space>
|
||||
</ProCard>
|
||||
</ProCard>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ServicePetUI);
|
||||
@@ -3,34 +3,60 @@ import React, { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
getTradeOrderDetail,
|
||||
type TradeOrderDetailRespVO,
|
||||
type TradeOrderPageRespVO,
|
||||
} from '@/services/trade/order';
|
||||
import BasicInfo from './component/info/basic-info'; //基本信息(通版)
|
||||
import ExtendCostInfo from './component/info/extend-cost'; //服务附加费(殡葬专属字段)
|
||||
import ExtendService from './component/info/extend-service'; //可选服务(殡葬专属字段)
|
||||
import ProdInfo from './component/info/prod-info'; //商品信息(通版)
|
||||
import SelectInfo from './component/info/select-info'; //可选服务(殡葬专属字段)
|
||||
import ServiceInfo from './component/info/service-info';
|
||||
import SurchargeInfo from './component/info/surcharge-info'; //服务附加费(殡葬专属字段)
|
||||
|
||||
const OrderDetail: React.FC<{ data?: TradeOrderDetailRespVO }> = (props) => {
|
||||
export interface ItemConfig<T> {
|
||||
data?: T;
|
||||
loading?: boolean;
|
||||
orderCategoryId?: number;
|
||||
}
|
||||
const OrderDetail: React.FC<{ data?: TradeOrderPageRespVO }> = (props) => {
|
||||
const { data } = props;
|
||||
const [detais, setDetails] = useState<TradeOrderDetailRespVO>();
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const fetch = useCallback(async () => {
|
||||
if (data?.id) {
|
||||
const res = await getTradeOrderDetail(data.id);
|
||||
setDetails(res);
|
||||
try {
|
||||
setLoading(true);
|
||||
if (data?.id) {
|
||||
const res = await getTradeOrderDetail(data.id);
|
||||
setDetails(res);
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [data]);
|
||||
}, [data?.id]);
|
||||
useEffect(() => {
|
||||
fetch();
|
||||
}, [data]);
|
||||
}, [data?.id]);
|
||||
|
||||
return (
|
||||
<Space direction="vertical" size={24} style={{ width: '100%' }}>
|
||||
<BasicInfo data={detais?.tradeOrderInfoBase} id={data?.id} />
|
||||
<ProdInfo data={detais?.tradeProductInfo} id={data?.id} />
|
||||
<ServiceInfo data={detais?.tradeServeInfo} id={data?.id} />
|
||||
<SelectInfo data={detais?.tradeExtendCostInfo} id={data?.id} />
|
||||
<SurchargeInfo data={detais?.tradeExtendServeInfo} id={data?.id} />
|
||||
<BasicInfo data={detais} loading={loading} />
|
||||
<ProdInfo data={detais?.items} />
|
||||
{detais?.tradeServeInfo && (
|
||||
<ServiceInfo
|
||||
data={detais.tradeServeInfo}
|
||||
orderCategoryId={detais?.orderCategoryId}
|
||||
/>
|
||||
)}
|
||||
{detais?.tradeExtendServeInfo && (
|
||||
<ExtendService
|
||||
data={detais.tradeExtendServeInfo}
|
||||
orderCategoryId={detais?.orderCategoryId}
|
||||
/>
|
||||
)}
|
||||
{detais?.tradeExtendCostInfo && (
|
||||
<ExtendCostInfo
|
||||
data={detais?.tradeExtendCostInfo}
|
||||
orderCategoryId={detais?.orderCategoryId}
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -23,8 +23,6 @@ import { baseOrderColumns } from './config';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
import { DownOutlined, UpOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import PopconfirmForm, {
|
||||
type PopconfirmFormRef,
|
||||
@@ -50,8 +48,8 @@ const OrderListItem: React.FC<{ orderStatus: number }> = (props) => {
|
||||
const popconfirmFormRef = useRef<PopconfirmFormRef>(null);
|
||||
const onFetch = async (
|
||||
params: TradeReq & {
|
||||
pageSize?: number;
|
||||
current?: number;
|
||||
pageSize: number;
|
||||
current: number;
|
||||
},
|
||||
) => {
|
||||
const data = await getTradeOrderPage({
|
||||
@@ -68,10 +66,13 @@ const OrderListItem: React.FC<{ orderStatus: number }> = (props) => {
|
||||
};
|
||||
};
|
||||
|
||||
const handleDetail = useCallback((record: TradeOrderPageRespVO) => {
|
||||
setModalData(record);
|
||||
configurableDrawerRef.current?.open();
|
||||
}, []);
|
||||
const handleDetail = useCallback(
|
||||
(record: TradeOrderPageRespVO) => {
|
||||
setModalData(record);
|
||||
configurableDrawerRef.current?.open(record);
|
||||
},
|
||||
[modalData],
|
||||
);
|
||||
|
||||
const handleOrder = useCallback((id?: number) => {
|
||||
console.log(id, '取消订单');
|
||||
@@ -107,10 +108,10 @@ const OrderListItem: React.FC<{ orderStatus: number }> = (props) => {
|
||||
<a key="cancel" onClick={() => handleOrder(record.id)}>
|
||||
取消订单
|
||||
</a>
|
||||
<a key="cancel" onClick={() => handleOrder(record.id)}>
|
||||
<a key="order" onClick={() => handleOrder(record.id)}>
|
||||
开始服务
|
||||
</a>
|
||||
<a key="cancel" onClick={() => handleOrder(record.id)}>
|
||||
<a key="sale" onClick={() => handleOrder(record.id)}>
|
||||
新建售后
|
||||
</a>
|
||||
<a key="detail" onClick={() => handleDetail(record)}>
|
||||
@@ -186,9 +187,9 @@ const OrderListItem: React.FC<{ orderStatus: number }> = (props) => {
|
||||
<span>{record.orderNum}</span>
|
||||
<span> {record.payType}</span>
|
||||
<Space>
|
||||
<Avatar icon={<UserOutlined />} />
|
||||
<Avatar icon={<UserOutlined />} src={record.shopLogo} />
|
||||
{/* <Image src={record.picUrl} width={64} /> */}
|
||||
百业到家旗舰店
|
||||
{record.shopName || '-'}
|
||||
</Space>
|
||||
<Space>
|
||||
{record.userAvatar ? (
|
||||
@@ -211,7 +212,6 @@ const OrderListItem: React.FC<{ orderStatus: number }> = (props) => {
|
||||
header: {
|
||||
cell: (props: any) => {
|
||||
const { children, ...restProps } = props;
|
||||
console.log(restProps, children);
|
||||
return <th {...restProps}>{children}</th>;
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user