feat(dealer): 添加经销商分成比例调整功能

- 在经销商列表中显示分成比例是否可调整
- 新增开关控制分成比例是否允许调整
- 更新相关表单和字段定义以支持新功能
- 调整国际化文案以匹配新的业务逻辑
- 优化部分组件代码结构和依赖引用
This commit is contained in:
shenyifei 2025-11-21 14:28:44 +08:00
parent 42cbb0d7fc
commit 35fd2e8138
20 changed files with 734 additions and 185 deletions

View File

@ -141,7 +141,7 @@ export async function getInitialState(): Promise<InitialStateProps> {
let current: any;
const { data: channel } = await auth.channel.selectChannelByDomain({
domain: window.location.host,
domain: "operation.erp.qilincloud168.com",
});
const { data: userAuthVO } = await auth.user.userInfo();
@ -346,7 +346,6 @@ export const request: RequestConfig = {
'X-Requested-With': 'XMLHttpRequest',
'Xh-Platform-Id': '1769220738064285698',
},
// 错误处理: umi@3 的错误处理方案。
errorConfig: {
// 错误抛出
@ -433,6 +432,12 @@ export const request: RequestConfig = {
headers: any;
},
) => {
options.headers = {
...options.headers,
'Xh-Role-Slug': "operation",
};
console.debug('请求拦截器', url, options);
const apiUrl = '/api' + url;

View File

@ -80,6 +80,7 @@ export default function DealerList(props: IDealerListProps) {
<>
<CheckCircleOutlined style={{ color: '#52c41a' }} />
{record.shareRatio ? ` ${record.shareRatio}%` : ''}
{record.shareAdjusted ? '可调整' : '不可调整'}
</>
) : (
<CloseCircleOutlined style={{ color: '#ff4d4f' }} />
@ -178,7 +179,9 @@ export default function DealerList(props: IDealerListProps) {
})}
>
<span>
{intl.formatMessage({ id: intlPrefix + '.column.enableAccrualTax' })}
{intl.formatMessage({
id: intlPrefix + '.column.enableAccrualTax',
})}
</span>
</Tooltip>
),
@ -277,32 +280,45 @@ export default function DealerList(props: IDealerListProps) {
{({ enableShare }) => {
return (
enableShare && (
<ProFormDigit
key={'shareRatio'}
name={'shareRatio'}
label={intl.formatMessage({
id: intlPrefix + '.form.shareRatio.label',
})}
fieldProps={{
precision: 2,
step: 0.01,
min: 0,
max: 100,
suffix: '%',
}}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.shareRatio.placeholder',
})}
dependencies={['enableShare']}
rules={[
{
required: true,
message: intl.formatMessage({
id: intlPrefix + '.form.shareRatio.required',
}),
},
]}
/>
<>
<ProFormDigit
key={'shareRatio'}
name={'shareRatio'}
label={intl.formatMessage({
id: intlPrefix + '.form.shareRatio.label',
})}
fieldProps={{
precision: 2,
step: 0.01,
min: 0,
max: 100,
suffix: '%',
}}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.shareRatio.placeholder',
})}
dependencies={['enableShare']}
rules={[
{
required: true,
message: intl.formatMessage({
id: intlPrefix + '.form.shareRatio.required',
}),
},
]}
/>
<ProFormSwitch
key={'shareAdjusted'}
name={'shareAdjusted'}
label={intl.formatMessage({
id: intlPrefix + '.form.shareAdjusted.label',
})}
fieldProps={{
checkedChildren: intl.formatMessage({ id: 'common.yes' }),
unCheckedChildren: intl.formatMessage({ id: 'common.no' }),
}}
/>
</>
)
);
}}

View File

@ -25,10 +25,10 @@ export default function DealerSelect(props: IUserSelectProps) {
label={intl.formatMessage({
id: 'form.dealerId.label',
})}
transform={(userVO) => {
transform={(dealerVO) => {
return {
userVO: userVO,
userId: userVO.userId,
dealerVO: dealerVO,
dealerId: dealerVO.dealerId,
};
}}
name={'dealerVO'}

View File

@ -0,0 +1,277 @@
import { BizContainer, BizValueType, ModeType } from '@/components';
import { business } from '@/services';
import { useIntl } from '@@/exports';
import {
ProColumns,
ProFormDatePicker,
ProFormDigit,
ProFormSelect,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { Tag } from 'antd';
import React from 'react';
interface IShipOrderListProps {
ghost?: boolean;
shipOrderId?: BusinessAPI.ShipOrderVO['shipOrderId'];
search?: boolean;
onValueChange?: () => void;
mode?: ModeType;
trigger?: () => React.ReactNode;
}
export default function ShipOrderList(props: IShipOrderListProps) {
const {
ghost = false,
shipOrderId,
search = true,
mode = 'page',
trigger,
onValueChange,
} = props;
const intl = useIntl();
const intlPrefix = 'shipOrder';
const columns: ProColumns<BusinessAPI.ShipOrderVO, BizValueType>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderSn' }),
dataIndex: 'orderSn',
key: 'orderSn',
renderText: (text: string) => <span className="font-medium">{text}</span>,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.dealerName' }),
dataIndex: 'dealerName',
key: 'dealerName',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.vehicleNo' }),
dataIndex: 'vehicleNo',
key: 'vehicleNo',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.shippingDate' }),
dataIndex: 'shippingDate',
key: 'shippingDate',
valueType: 'date',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.state' }),
dataIndex: 'state',
key: 'state',
valueType: 'select',
valueEnum: {
WAIT_PAYMENT: {
text: intl.formatMessage({
id: intlPrefix + '.column.state.waitPayment',
}),
status: 'Default',
},
PARTIAL_PAYMENT: {
text: intl.formatMessage({
id: intlPrefix + '.column.state.partialPayment',
}),
status: 'Processing',
},
FULL_PAYMENT: {
text: intl.formatMessage({
id: intlPrefix + '.column.state.fullPayment',
}),
status: 'Success',
},
REJECT_FINISH: {
text: intl.formatMessage({
id: intlPrefix + '.column.state.rejectFinish',
}),
status: 'Error',
},
FINISH: {
text: intl.formatMessage({ id: intlPrefix + '.column.state.finish' }),
status: 'Success',
},
},
render: (_, record) => {
const stateText = intl.formatMessage({
id: `${intlPrefix}.column.state.${record.state?.toLowerCase() || 'unknown'}`,
});
let color = 'default';
switch (record.state) {
case 'WAIT_PAYMENT':
color = 'default';
break;
case 'PARTIAL_PAYMENT':
color = 'processing';
break;
case 'FULL_PAYMENT':
color = 'success';
break;
case 'REJECT_FINISH':
color = 'error';
break;
case 'FINISH':
color = 'success';
break;
default:
color = 'default';
}
return <Tag color={color}>{stateText}</Tag>;
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.totalAmount' }),
dataIndex: 'totalAmount',
key: 'totalAmount',
valueType: 'money',
search: false,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.createdAt' }),
dataIndex: 'createdAt',
key: 'createdAt',
valueType: 'dateTime',
search: false,
},
];
const formContext = [
<ProFormText
key={'orderSn'}
name={'orderSn'}
label={intl.formatMessage({ id: intlPrefix + '.form.orderSn.label' })}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.orderSn.placeholder',
})}
/>,
<ProFormText
key={'dealerName'}
name={'dealerName'}
label={intl.formatMessage({ id: intlPrefix + '.form.dealerName.label' })}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.dealerName.placeholder',
})}
/>,
<ProFormDatePicker
key={'shippingDate'}
name={'shippingDate'}
label={intl.formatMessage({
id: intlPrefix + '.form.shippingDate.label',
})}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.shippingDate.placeholder',
})}
/>,
<ProFormText
key={'vehicleNo'}
name={'vehicleNo'}
label={intl.formatMessage({ id: intlPrefix + '.form.vehicleNo.label' })}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.vehicleNo.placeholder',
})}
/>,
<ProFormSelect
key={'state'}
name={'state'}
label={intl.formatMessage({ id: intlPrefix + '.form.state.label' })}
valueEnum={{
WAIT_PAYMENT: intl.formatMessage({
id: intlPrefix + '.column.state.waitPayment',
}),
PARTIAL_PAYMENT: intl.formatMessage({
id: intlPrefix + '.column.state.partialPayment',
}),
FULL_PAYMENT: intl.formatMessage({
id: intlPrefix + '.column.state.fullPayment',
}),
REJECT_FINISH: intl.formatMessage({
id: intlPrefix + '.column.state.rejectFinish',
}),
FINISH: intl.formatMessage({ id: intlPrefix + '.column.state.finish' }),
}}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.state.placeholder',
})}
/>,
<ProFormDigit
key={'totalAmount'}
name={'totalAmount'}
label={intl.formatMessage({ id: intlPrefix + '.form.totalAmount.label' })}
fieldProps={{
precision: 2,
step: 0.01,
}}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.totalAmount.placeholder',
})}
/>,
<ProFormTextArea
key={'remark'}
name={'remark'}
label={intl.formatMessage({ id: intlPrefix + '.form.remark.label' })}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.remark.placeholder',
})}
/>,
];
const detailColumns: ProDescriptionsItemProps<
BusinessAPI.ShipOrderVO,
BizValueType
>[] = columns as ProDescriptionsItemProps<
BusinessAPI.ShipOrderVO,
BizValueType
>[];
return (
<BizContainer<
typeof business.shipOrder,
BusinessAPI.ShipOrderVO,
BusinessAPI.ShipOrderPageQry,
BusinessAPI.ShipOrderCreateCmd,
BusinessAPI.ShipOrderUpdateCmd
>
rowKey={'shipOrderId'}
permission={'operation-ship-order'}
func={business.shipOrder}
method={'shipOrder'}
methodUpper={'ShipOrder'}
intlPrefix={intlPrefix}
modeType={mode}
onValueChange={onValueChange}
container={{
ghost,
}}
status={false}
page={{
fieldProps: {
bordered: true,
ghost,
//@ts-ignore
search,
},
columns,
}}
create={{
formType: 'drawer',
formContext,
initValues: {
status: true,
},
}}
update={{
formType: 'drawer',
formContext,
}}
destroy={{}}
detail={{
rowId: shipOrderId,
formType: 'drawer',
columns: detailColumns,
trigger,
}}
/>
);
}

View File

@ -0,0 +1 @@
export { default as ShipOrderList } from './ShipOrderList';

View File

@ -7,7 +7,6 @@ import {
ModeType,
RestPassword,
} from '@/components';
import { PERMISSION } from '@/constants';
import { business } from '@/services';
import { aesEncrypt } from '@/utils/aes';
import { formatParam } from '@/utils/formatParam';
@ -45,6 +44,7 @@ const EmployeeList: React.FC = (props: IEmployeeListProps) => {
title: intl.formatMessage({ id: intlPrefix + '.column.avatar' }),
dataIndex: 'avatar',
valueType: 'avatar',
search: false,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
@ -76,7 +76,7 @@ const EmployeeList: React.FC = (props: IEmployeeListProps) => {
});
return (
data?.data?.map((item: BusinessAPI.RoleVO) => ({
label: item.name,
label: item.platformVO?.platformName + '-' + item.name,
value: item.roleId,
})) ?? []
);
@ -301,7 +301,7 @@ const EmployeeList: React.FC = (props: IEmployeeListProps) => {
});
return (
data?.data?.map((item: BusinessAPI.RoleVO) => ({
label: item.name,
label: item.platformVO?.platformName + '-' + item.name,
value: item.roleId,
})) ?? []
);
@ -478,24 +478,24 @@ const EmployeeList: React.FC = (props: IEmployeeListProps) => {
columns,
options: (record, actionRef) => [
<RestPassword
key={PERMISSION.MDB_BUSINESS_EMPLOYEE_REST_PASSWORD}
permission={PERMISSION.MDB_BUSINESS_EMPLOYEE_REST_PASSWORD}
key={'RestPassword'}
permission={''}
onFinish={async () => {
await actionRef.current?.reload();
}}
employeeId={record.employeeId}
/>,
<EmployeeRoleUpdate
key={PERMISSION.MDB_BUSINESS_EMPLOYEE_ROLE_UPDATE}
permission={PERMISSION.MDB_BUSINESS_EMPLOYEE_ROLE_UPDATE}
key={'EmployeeRoleUpdate'}
permission={''}
onFinish={async () => {
await actionRef.current?.reload();
}}
employeeId={record.employeeId}
/>,
<EmployeeDisable
key={PERMISSION.MDB_BUSINESS_EMPLOYEE_ROLE_UPDATE + 1}
permission={PERMISSION.MDB_BUSINESS_EMPLOYEE_ROLE_UPDATE}
key={'EmployeeDisable'}
permission={''}
onFinish={async () => {
await actionRef.current?.reload();
}}

View File

@ -1,4 +1,4 @@
import { ButtonAccess } from '@/components';
import { ButtonAccess, SafeModal } from '@/components';
import { business } from '@/services';
import { formLayout } from '@/utils/formLayout';
import {
@ -7,7 +7,7 @@ import {
ProFormText,
} from '@ant-design/pro-components';
import { message } from 'antd';
import React from 'react';
import React, { useState } from 'react';
interface IEmployeeUpdateProps {
onFinish: () => void;
@ -17,70 +17,89 @@ interface IEmployeeUpdateProps {
const EmployeeRoleUpdate: React.FC<IEmployeeUpdateProps> = (props) => {
const { onFinish, employeeId, permission } = props;
const [openSafeModal, setOpenSafeModal] = useState<boolean>(false);
return (
<ModalForm<BusinessAPI.UserRoleUpdateCmd>
title="更新员工"
{...formLayout()}
grid={true}
trigger={
<ButtonAccess permission={permission} type={'link'}>
</ButtonAccess>
}
autoFocusFirstInput
modalProps={{
destroyOnHidden: true,
}}
submitTimeout={2000}
//@ts-ignore
request={async () => {
const { data } = await business.employee.showEmployee({
employeeShowQry: { employeeId: employeeId },
});
return {
...data,
employeeId: employeeId,
};
}}
onFinish={async (values) => {
const { success } = await business.employee.updateEmployeeRole(values);
if (success) {
message.success('更新员工角色成功');
onFinish();
return true;
}
}}
>
<ProFormText hidden={true} name={'userId'} />
<ProFormSelect
name={'roleId'}
label={'角色'}
placeholder="请选择角色"
required={true}
rules={[
{
required: true,
message: '请选择角色',
},
]}
showSearch={true}
fieldProps={{
mode: 'multiple',
autoFocus: true,
}}
request={async (params) => {
const data = await business.role.listRole({
roleListQry: params,
});
return (
data?.data?.map((item) => ({
label: item.name,
value: item.roleId,
})) ?? []
);
}}
<>
<SafeModal
open={openSafeModal}
onVisibleChange={(openSafeModal) => setOpenSafeModal(openSafeModal)}
/>
</ModalForm>
<ModalForm<BusinessAPI.UserRoleUpdateCmd>
title="更新员工"
{...formLayout()}
grid={true}
trigger={
<ButtonAccess permission={permission} type={'link'}>
</ButtonAccess>
}
autoFocusFirstInput
modalProps={{
destroyOnHidden: true,
}}
submitTimeout={2000}
//@ts-ignore
request={async () => {
const { data } = await business.employee.showEmployee({
employeeShowQry: { employeeId: employeeId },
});
return {
...data,
employeeId: employeeId,
};
}}
onFinish={async (values) => {
const { success, errCode } =
await business.employee.updateEmployeeRole({
...values,
cover: true,
});
if (success) {
if (success && errCode === '401') {
setOpenSafeModal(true);
return false;
}
message.success('更新员工角色成功');
onFinish();
return true;
}
}}
>
<ProFormText hidden={true} name={'userId'} />
<ProFormSelect
name={'roleIdList'}
label={'角色'}
placeholder="请选择角色"
required={true}
rules={[
{
required: true,
message: '请选择角色',
},
]}
showSearch={true}
fieldProps={{
mode: 'multiple',
}}
request={async (params) => {
const data = await business.role.listRole({
roleListQry: {
...params,
},
});
return (
data?.data?.map((item) => ({
label: item.platformVO?.platformName + '-' + item.name,
value: item.roleId,
})) ?? []
);
}}
/>
</ModalForm>
</>
);
};

View File

@ -10,16 +10,18 @@ import { useIntl } from '@@/exports';
import {
ProColumns,
ProFormDependency,
ProFormDigit,
ProFormRadio,
ProFormSelect,
ProFormText,
ProFormTreeSelect,
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { ProFormBizSelect, ProFormBizSelectHandles } from '@chageable/components';
import {
ProFormBizSelect,
ProFormBizSelectHandles,
} from '@chageable/components';
import { TreeSelect } from 'antd';
import React, { useRef } from 'react';
import React, { useEffect, useRef, useState } from 'react';
export interface IMenuListProps {
ghost?: boolean;
@ -125,7 +127,7 @@ export default function MenuList(props: IMenuListProps) {
})}
required={false}
name={'pid'}
dependencies={['appId']}
dependencies={['platformId']}
request={async (params) => {
const response = await business.menu.treeMenu(params);
return response.data || [];
@ -214,7 +216,7 @@ export default function MenuList(props: IMenuListProps) {
})}
required={false}
name={'pid'}
dependencies={['appId']}
dependencies={['platformId']}
request={async (params) => {
const response = await business.menu.treeMenu(params);
return response.data || [];
@ -320,7 +322,7 @@ export default function MenuList(props: IMenuListProps) {
})}
required={false}
name={'pid'}
dependencies={['appId']}
dependencies={['platformId']}
request={async (params) => {
const response = await business.menu.treeMenu(params);
return response.data || [];
@ -460,23 +462,6 @@ export default function MenuList(props: IMenuListProps) {
}),
dataIndex: 'path',
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.platformId',
}),
dataIndex: 'platformId',
valueType: 'select',
request: async (params) => await getPlatformList(params),
fieldProps: {
fetchDataOnSearch: false,
showSearch: true,
autoClearSearchValue: true,
fieldNames: {
label: 'platformName',
value: 'platformId',
},
},
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.type',
@ -519,6 +504,30 @@ export default function MenuList(props: IMenuListProps) {
BizValueType
>[] = columns as ProDescriptionsItemProps<BusinessAPI.MenuVO, BizValueType>[];
const [platformList, setPlatformList] = useState<BusinessAPI.PlatformVO[]>();
const [platformId, setPlatformId] =
useState<BusinessAPI.PlatformVO['platformId']>('');
const initPlatform = async () => {
const { data: platformList } = await business.platform.listPlatform({
platformListQry: {},
});
setPlatformList(platformList);
if (platformList) {
setPlatformId(platformList[0].platformId);
}
};
useEffect(() => {
initPlatform().then();
}, []);
if (!platformList) {
return;
}
const detailContext = (
menuVO: BusinessAPI.MenuVO,
onValueChange: () => void,
@ -557,6 +566,18 @@ export default function MenuList(props: IMenuListProps) {
onValueChange={onValueChange}
container={{
ghost,
fieldProps: {
tabActiveKey: platformId,
onTabChange: (platformId) => {
setPlatformId(platformId as BusinessAPI.PlatformVO['platformId']);
},
tabList: [
...platformList.map((platformVO) => ({
key: platformVO.platformId,
tab: platformVO.platformName,
})),
],
},
}}
page={{
fieldProps: {
@ -564,8 +585,10 @@ export default function MenuList(props: IMenuListProps) {
//@ts-ignore
search,
params: {
platformId: platformId,
...(menuVO && {
pid: menuVO.menuId,
platformId: menuVO.platformId,
}),
},
},
@ -580,8 +603,10 @@ export default function MenuList(props: IMenuListProps) {
childrenColumnName: 'routes',
},
params: {
platformId: platformId,
...(menuVO && {
pid: menuVO.menuId,
platformId: menuVO.platformId,
}),
},
},
@ -594,8 +619,10 @@ export default function MenuList(props: IMenuListProps) {
//@ts-ignore
search,
params: {
platformId: platformId,
...(menuVO && {
pid: menuVO.menuId,
platformId: menuVO.platformId,
}),
},
},
@ -606,6 +633,7 @@ export default function MenuList(props: IMenuListProps) {
formContext,
trigger,
initValues: {
platformId: platformId,
...(menuVO && {
pid: menuVO.menuId,
platformId: menuVO.platformId,

View File

@ -12,7 +12,7 @@ import {
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { TreeSelect } from 'antd';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
export interface IRoleListProps {
ghost?: boolean;
@ -36,6 +36,30 @@ export default function RoleList(props: IRoleListProps) {
const { getPlatformList } = useSearch();
const [menuTree, setMenuTree] = useState<BusinessAPI.TreeLong[]>();
const [platformList, setPlatformList] = useState<BusinessAPI.PlatformVO[]>();
const [platformId, setPlatformId] =
useState<BusinessAPI.PlatformVO['platformId']>('');
const initPlatform = async () => {
const { data: platformList } = await business.platform.listPlatform({
platformListQry: {},
});
setPlatformList(platformList);
if (platformList) {
setPlatformId(platformList[0].platformId);
}
};
useEffect(() => {
initPlatform().then();
}, []);
if (!platformList) {
return;
}
const formContext = [
<ProFormSelect
key={'platformId'}
@ -192,23 +216,6 @@ export default function RoleList(props: IRoleListProps) {
dataIndex: 'description',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.platformId',
}),
dataIndex: 'platformId',
valueType: 'select',
request: async (params) => await getPlatformList(params),
fieldProps: {
fetchDataOnSearch: false,
showSearch: true,
autoClearSearchValue: true,
fieldNames: {
label: 'platformName',
value: 'platformId',
},
},
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.createdAt',
@ -241,19 +248,35 @@ export default function RoleList(props: IRoleListProps) {
onValueChange={onValueChange}
container={{
ghost,
fieldProps: {
tabActiveKey: platformId,
onTabChange: (platformId) => {
setPlatformId(platformId as BusinessAPI.PlatformVO['platformId']);
},
tabList: [
...platformList.map((platformVO) => ({
key: platformVO.platformId,
tab: platformVO.platformName,
})),
],
},
}}
page={{
fieldProps: {
ghost,
//@ts-ignore
search,
params: {},
params: {
platformId: platformId,
},
},
columns,
}}
create={{
formType: 'drawer',
initValues: {},
initValues: {
platformId: platformId,
},
formContext,
trigger,
request: async (formData) => {

View File

@ -0,0 +1,47 @@
import { business } from '@/services';
import { formLayout } from '@/utils/formLayout';
import { ProForm, ProFormTextArea } from '@ant-design/pro-components';
import { Col, message, Row, Space } from 'antd';
export default function SmartRecognitionPromptConfig() {
return (
<ProForm
{...formLayout()}
request={async () => {
const { data } = await business.setting.showSetting({
settingShowQry: {
settingKey: 'SMART_RECOGNITION_PROMPT',
},
});
return {
...data?.settingValue,
};
}}
onFinish={async (values) => {
await business.setting.updateSetting({
settingKey: 'SMART_RECOGNITION_PROMPT',
settingValue: {
...values,
settingKey: 'SMART_RECOGNITION_PROMPT',
},
});
message.success('智能识别提示词');
}}
submitter={{
render: (_, dom) => {
return (
<Row>
<Col span={14} offset={4}>
<Space>{dom}</Space>
</Col>
</Row>
);
},
}}
>
<ProFormTextArea name="prompt" label="智能识别提示词" />
</ProForm>
);
}

View File

@ -9,3 +9,4 @@ export { default as WxMaSubscribeMessageConfig } from './WxMaSubscribeMessageCon
export { default as WxMpConfig } from './WxMpConfig';
export { default as WxMpMessagePushConfig } from './WxMpMessagePushConfig';
export { default as WxPayConfig } from './WxPayConfig';
export { default as SmartRecognitionPromptConfig } from './SmartRecognitionPromptConfig';

View File

@ -18,3 +18,4 @@ export * from './Role';
export * from './Setting';
export * from './User';
export * from './Purchase';
export * from './Delivery';

View File

@ -730,6 +730,9 @@ export default {
placeholder: '请输入诚信志远分成比例',
required: '请输入诚信志远分成比例',
},
shareAdjusted: {
label: '是否开启调整诚信志远分成比例',
},
freightCostFlag: {
label: '运费是否作为成本',
placeholder: '请选择运费是否作为成本',
@ -2315,4 +2318,77 @@ export default {
},
},
},
shipOrder: {
column: {
orderSn: '发货单编号',
dealerName: '经销商名称',
vehicleNo: '车次号',
shippingDate: '发货日期',
state: '状态',
'state.waitPayment': '待回款',
'state.partialPayment': '部分回款',
'state.fullPayment': '已回款',
'state.rejectFinish': '拒收完结',
'state.finish': '已完结',
totalAmount: '合计金额(元)',
createdAt: '创建时间',
option: '操作',
},
form: {
orderSn: {
label: '发货单编号',
placeholder: '请输入发货单编号',
},
dealerName: {
label: '经销商名称',
placeholder: '请输入经销商名称',
},
shippingDate: {
label: '发货日期',
placeholder: '请选择发货日期',
},
vehicleNo: {
label: '车次号',
placeholder: '请输入车次号',
},
state: {
label: '状态',
placeholder: '请选择状态',
},
totalAmount: {
label: '合计金额(元)',
placeholder: '请输入合计金额',
},
remark: {
label: '备注',
placeholder: '请输入备注',
},
},
modal: {
create: {
title: '创建发货单',
button: '创建发货单',
success: '创建发货单成功',
},
update: {
title: '更新发货单',
button: '编辑',
success: '更新发货单成功',
},
delete: {
success: '删除发货单成功',
button: '删除',
confirm: {
title: '确认删除',
content: '您确定要删除该发货单吗?',
okText: '确定',
cancelText: '取消',
},
},
view: {
title: '查看发货单',
button: '详情',
},
},
},
};

View File

@ -19,7 +19,6 @@ const useUser = () => {
return initialState?.currentAdmin;
} else {
window.localStorage.removeItem('user-data');
window.localStorage.removeItem('merchant-app-id');
window.location.href =
process.env.UMI_APP_SSO_LOGIN_URL +
@ -35,7 +34,6 @@ const useUser = () => {
if (response.success) {
window.localStorage.removeItem('user-data');
window.localStorage.removeItem('merchant-app-id');
window.location.href =
process.env.UMI_APP_SSO_LOGIN_URL +

View File

@ -0,0 +1,5 @@
import { ShipOrderList } from '@/components';
export default function Page() {
return <ShipOrderList />;
}

View File

@ -1,12 +1,12 @@
import {
PageContainer,
WxMaCodeUploadConfig,
WxMaMessagePushConfig,
WxMaSubscribeMessageConfig,
} from '@/components';
import { WxMaConfig } from '@/components/Setting';
import { ProCard } from '@ant-design/pro-components';
import { useState } from 'react';
import SmartRecognitionPromptConfig from '../components/Setting/SmartRecognitionPromptConfig';
export default function Page() {
const [activeKey, setActiveKey] = useState<string>('1');
@ -34,7 +34,7 @@ export default function Page() {
},
{
key: '4',
tab: '小程序上传',
tab: '智能识别',
},
],
}}
@ -59,7 +59,7 @@ export default function Page() {
{activeKey === '4' && (
<ProCard>
<WxMaCodeUploadConfig />
<SmartRecognitionPromptConfig />
</ProCard>
)}
</PageContainer>

View File

@ -1097,6 +1097,8 @@ declare namespace BusinessAPI {
enableCompanyRebate?: boolean;
/** 公司返点比例 */
companyRebateRatio?: number;
/** 是否可调整比例 */
shareAdjusted?: boolean;
};
type DealerDestroyCmd = {
@ -1413,6 +1415,8 @@ declare namespace BusinessAPI {
enableCompanyRebate?: boolean;
/** 公司返点比例 */
companyRebateRatio?: number;
/** 是否可调整比例 */
shareAdjusted?: boolean;
/** 发货单模板 */
deliveryTemplate?: string;
};
@ -1456,6 +1460,8 @@ declare namespace BusinessAPI {
enableCompanyRebate?: boolean;
/** 公司返点比例 */
companyRebateRatio?: number;
/** 是否可调整比例 */
shareAdjusted?: boolean;
};
type DealerWarehouseCreateCmd = {
@ -2528,6 +2534,8 @@ declare namespace BusinessAPI {
enableCompanyRebate?: boolean;
/** 公司返点比例 */
companyRebateRatio?: number;
/** 是否可调整比例 */
shareAdjusted?: boolean;
/** 税费补贴 */
taxSubsidy?: number;
/** 计提税金 */
@ -3424,6 +3432,8 @@ declare namespace BusinessAPI {
active?: number;
/** 产地负责人 */
originPrincipal?: string;
/** 工头 */
foreman?: string;
/** 备注 */
remark?: string;
/** 车辆信息 */
@ -3438,6 +3448,7 @@ declare namespace BusinessAPI {
orderPackageList: OrderPackage[];
/** 是否是暂存 */
draft: boolean;
/** 报价方式1_按毛重报价2_按净重报价 */
pricingMethod?: 'BY_GROSS_WEIGHT' | 'BY_NET_WEIGHT';
/** 公司信息 */
orderCompany: OrderCompany;
@ -3448,14 +3459,16 @@ declare namespace BusinessAPI {
type PurchaseOrderCountQry = {
/** 状态1_启用0_禁用 */
status?: boolean;
/** 订单状态: 0-草稿, 1-待审核, 2-待老板审核, 3-已发货(待付款), 4-已付款, 5-已完结 */
/** 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已驳回6_已撤回7_已关闭8_已完结 */
state?:
| 'DRAFT'
| 'WAITING_AUDIT'
| 'WAITING_BOSS_APPROVE'
| 'SHIPPING'
| 'WAITING_APPROVE'
| 'WAITING_SHIPMENT'
| 'SHIPPED'
| 'PAID'
| 'COMPLETED';
| 'COMPLETED'
| 'REJECTED';
};
type PurchaseOrderCreateCmd = {
@ -3465,6 +3478,8 @@ declare namespace BusinessAPI {
active?: number;
/** 产地负责人 */
originPrincipal?: string;
/** 工头 */
foreman?: string;
/** 备注 */
remark?: string;
/** 车辆信息 */
@ -3517,14 +3532,16 @@ declare namespace BusinessAPI {
vehicleNo?: string;
/** 采购订单编号 */
orderSn?: string;
/** 订单状态: 0-草稿, 1-待审核, 2-待老板审核, 3-已发货(待付款), 4-已付款, 5-已完结 */
/** 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已驳回6_已撤回7_已关闭8_已完结 */
state?:
| 'DRAFT'
| 'WAITING_AUDIT'
| 'WAITING_BOSS_APPROVE'
| 'SHIPPING'
| 'WAITING_APPROVE'
| 'WAITING_SHIPMENT'
| 'SHIPPED'
| 'PAID'
| 'COMPLETED';
| 'COMPLETED'
| 'REJECTED';
/** 供应商名称 */
supplierName?: string;
/** 经销商ID */
@ -3535,13 +3552,15 @@ declare namespace BusinessAPI {
type PurchaseOrderRejectApproveCmd = {
/** 采购订单ID */
orderId: string;
/** 驳回原因 */
/** 审核原因 */
rejectReason: string;
};
type PurchaseOrderRejectFinalCmd = {
/** 采购订单ID */
orderId: string;
/** 驳回原因 */
rejectReason: string;
};
type PurchaseOrderShowQry = {
@ -3580,6 +3599,8 @@ declare namespace BusinessAPI {
orderId: string;
/** 步骤标识 */
active?: number;
/** 工头 */
foreman?: string;
/** 采购订单费用信息 */
orderCostList: OrderCost[];
/** 采购订单包装箱信息 */
@ -3598,6 +3619,8 @@ declare namespace BusinessAPI {
active?: number;
/** 产地负责人 */
originPrincipal?: string;
/** 工头 */
foreman?: string;
/** 备注 */
remark?: string;
/** 车辆信息 */
@ -3623,6 +3646,8 @@ declare namespace BusinessAPI {
active?: number;
/** 产地负责人 */
originPrincipal?: string;
/** 工头 */
foreman?: string;
/** 报价方式1_按毛重报价2_按净重报价 */
pricingMethod?: 'BY_GROSS_WEIGHT' | 'BY_NET_WEIGHT';
/** 销售金额 */
@ -3643,14 +3668,16 @@ declare namespace BusinessAPI {
freightCharge?: number;
/** 瓜农数量 */
supplierCount?: number;
/** 订单状态: 0-草稿, 1-待审核, 2-待老板审核, 3-已发货(待付款), 4-已付款, 5-已完结 */
/** 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已驳回6_已撤回7_已关闭8_已完结 */
state?:
| 'DRAFT'
| 'WAITING_AUDIT'
| 'WAITING_BOSS_APPROVE'
| 'SHIPPING'
| 'WAITING_APPROVE'
| 'WAITING_SHIPMENT'
| 'SHIPPED'
| 'PAID'
| 'COMPLETED';
| 'COMPLETED'
| 'REJECTED';
/** 备注 */
remark?: string;
/** 创建人ID */
@ -3723,6 +3750,8 @@ declare namespace BusinessAPI {
roleIdList?: number[];
/** 平台Id */
platformId?: string;
/** 平台Id */
platformIdList?: string;
/** 角色类型 */
type?: number;
offset?: number;
@ -3783,6 +3812,8 @@ declare namespace BusinessAPI {
description?: string;
/** 平台id */
platformId: string;
/** 平台 */
platformVO?: PlatformVO;
/** 权限列表 */
permissionId: number[];
/** 菜单列表 */
@ -3810,7 +3841,8 @@ declare namespace BusinessAPI {
| 'CHARGING_PILE_PURCHASE_CONFIG'
| 'CUSTOM_THEME_CONFIG'
| 'CUSTOM_MENU_CONFIG'
| 'WX_CP_NOTIFY_CONFIG';
| 'WX_CP_NOTIFY_CONFIG'
| 'SMART_RECOGNITION_PROMPT';
};
type SettingUpdateCmd = {
@ -3832,13 +3864,15 @@ declare namespace BusinessAPI {
| 'CHARGING_PILE_PURCHASE_CONFIG'
| 'CUSTOM_THEME_CONFIG'
| 'CUSTOM_MENU_CONFIG'
| 'WX_CP_NOTIFY_CONFIG';
| 'WX_CP_NOTIFY_CONFIG'
| 'SMART_RECOGNITION_PROMPT';
/** 系统设置项内容 */
settingValue:
| AliPayConfigValue
| ChargingPilePurchaseConfig
| CustomMenuConfigValue
| CustomThemeConfigValue
| SmartRecognitionPromptValue
| TencentMapConfigValue
| WxCpNotifyConfigValue
| WxMaCodeUploadConfigValue
@ -3871,13 +3905,15 @@ declare namespace BusinessAPI {
| 'CHARGING_PILE_PURCHASE_CONFIG'
| 'CUSTOM_THEME_CONFIG'
| 'CUSTOM_MENU_CONFIG'
| 'WX_CP_NOTIFY_CONFIG';
| 'WX_CP_NOTIFY_CONFIG'
| 'SMART_RECOGNITION_PROMPT';
/** 系统设置项内容 */
settingValue:
| AliPayConfigValue
| ChargingPilePurchaseConfig
| CustomMenuConfigValue
| CustomThemeConfigValue
| SmartRecognitionPromptValue
| TencentMapConfigValue
| WxCpNotifyConfigValue
| WxMaCodeUploadConfigValue
@ -3940,6 +3976,10 @@ declare namespace BusinessAPI {
companyName?: string;
/** 备注 */
remark?: string;
/** 发货单明细 */
shipOrderItemList?: ShipOrderItem[];
/** 发货单包装信息 */
shipOrderPackageList?: ShipOrderPackage[];
};
type ShipOrderDestroyCmd = {
@ -3995,7 +4035,7 @@ declare namespace BusinessAPI {
};
type ShipOrderPackage = {
/** 发货单子项ID */
/** 发货单包装信息Id */
orderPackageId: string;
/** 发货单ID */
shipOrderId: string;
@ -4498,6 +4538,13 @@ declare namespace BusinessAPI {
data?: VehicleExtractionVO;
};
type SmartRecognitionPromptValue =
// #/components/schemas/SettingValue
SettingValue & {
/** 提示词 */
prompt?: string;
};
type SupplierCheckQry = {
pageSize?: number;
pageIndex?: number;

View File

@ -0,0 +1,19 @@
// 添加一个辅助函数用于分组
const groupBy = <T>(
array: T[],
keyFn: (item: T) => string,
): Record<string, T[]> => {
return array.reduce(
(groups, item) => {
const key = keyFn(item);
if (!groups[key]) {
groups[key] = [];
}
groups[key].push(item);
return groups;
},
{} as Record<string, T[]>,
);
};
export default groupBy;

View File

@ -1,14 +0,0 @@
export const replaceMerchantApp = async (merchantAppVO: API.MerchantAppVO) => {
window.localStorage.setItem('merchant-app-id', merchantAppVO.merchantAppId);
window.localStorage.setItem('app-plan-id', merchantAppVO.appPlanId);
// 历史记录清空
window.history.replaceState(null, '', '/');
// window.location.replace(
// merchantAppVO.appPlanVO.homePage +
// '?merchantAppId=' +
// merchantAppVO.merchantAppId,
// );
};

File diff suppressed because one or more lines are too long