Compare commits

...

2 Commits

Author SHA1 Message Date
shenyifei
f183da70ee feat(notification): 实现消息通知功能并优化移动端布局
- 添加消息模板管理组件,支持模板分类、触发事件、标题内容等配置
- 实现消息接收者管理,包含未读消息计数和消息状态跟踪
- 集成通知消息下拉菜单,显示最新未读消息列表
- 添加消息模板变量系统,支持动态内容替换
- 优化移动端响应式布局,在BoxProductList中调整列宽和图片展示
- 移除PaymentTask和PaymentTaskPay中的冗余表格列配置
- 更新国际化文件,添加消息通知相关文案配置
- 修改全局样式,隐藏页面滚动条并优化代码块显示样式
2026-01-15 16:27:11 +08:00
shenyifei
f5feec84e3 feat(biz): 添加供应商发票功能并优化表格组件
- 在BizProvider中新增supplierInvoice类型支持
- 添加SupplierInvoiceList组件用于显示供应商发票信息
- 为经销商显示添加市场/超市标识区分
- 更新公司支付账户模态框类型定义以支持业务值类型
- 优化订单成本列表中的公司字段显示方式
- 在订单供应商列表中新增发票上传状态显示
- 为订单供应商模态框添加开票状态逻辑处理
- 更新多个模态框的列配置以支持业务值类型
- 调整选择模态框布局大小和分页配置
- 移除支付记录列表的编辑删除功能
- 优化订单供应商选择列表的发票相关字段显示
2026-01-14 11:45:56 +08:00
39 changed files with 3432 additions and 703 deletions

View File

@ -2,17 +2,18 @@
// 全局初始化数据配置,用于 Layout 用户信息和权限初始化
// 更多信息见文档https://umijs.org/docs/api/runtime-config#getinitialstate
import { LeftMenu, SearchMenu, VersionChecker } from '@/components';
import {
LeftMenu,
NotificationMessage,
SearchMenu,
VersionChecker,
} from '@/components';
import Avatar from '@/layout/guide/Avatar';
import { auth } from '@/services';
import { Navigate } from '@@/exports';
import { RunTimeLayoutConfig } from '@@/plugin-layout/types';
import { RequestConfig } from '@@/plugin-request/request';
import {
InfoCircleFilled,
NotificationFilled,
QuestionCircleFilled,
} from '@ant-design/icons';
import { InfoCircleFilled, QuestionCircleFilled } from '@ant-design/icons';
import '@nutui/nutui-react/dist/style.scss';
import { history } from '@umijs/max';
import { Alert, Button, message, notification, Spin } from 'antd';
@ -302,13 +303,18 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
actionsRender: (props) => {
if (props.isMobile) return [];
if (typeof window === 'undefined') return [];
// 获取当前管理员ID
const adminVO = JSON.parse(window.localStorage.getItem('admin') || '{}');
const adminId = adminVO?.adminId;
return [
props.layout !== 'side' && document.body.clientWidth > 1400 ? (
<SearchMenu key={'SearchMenu'} menuData={props.menuData} />
) : undefined,
<InfoCircleFilled key="InfoCircleFilled" />,
<QuestionCircleFilled key="QuestionCircleFilled" />,
<NotificationFilled key="NotificationFilled" />,
<NotificationMessage key="NotificationMessage" adminId={adminId} />,
];
},
headerRender: (props, defaultDom) => {

View File

@ -268,16 +268,8 @@ export default function BoxProductList(props: IBoxProductListProps) {
{(value: RouteContextType) => {
const { isMobile } = value;
return (
<Row gutter={16}>
<Col
xs={24}
sm={24}
md={24}
lg={10}
xl={8}
xxl={6}
flex={isMobile ? 'auto' : '375px'}
>
<Row gutter={16} wrap={isMobile}>
<Col xs={24} sm={24} md={24} lg={10} xl={8} xxl={6}>
{/* 品牌列表 */}
<div
style={{
@ -343,8 +335,6 @@ export default function BoxProductList(props: IBoxProductListProps) {
style={{
objectFit: 'cover',
borderRadius: 8,
width: isMobile ? '100%' : 375,
height: 375,
cursor: 'pointer',
}}
alt={item.name}
@ -432,17 +422,17 @@ export default function BoxProductList(props: IBoxProductListProps) {
/>
</div>
</Col>
{boxBrand ? (
<Col xs={24} sm={24} md={24} flex={'auto'}>
<ProCard>
<div className={'text-lg font-medium'}>
{boxBrand?.name || '请从左侧选择一个品牌'}
</div>
</ProCard>
{defaultDom}
</Col>
) : (
<Col xs={24} sm={24} md={24} flex={'auto'}>
<Col flex={'auto'}>
{boxBrand ? (
<>
<ProCard>
<div className={'text-lg font-medium'}>
{boxBrand?.name || '请从左侧选择一个品牌'}
</div>
</ProCard>
{defaultDom}
</>
) : (
<ProCard>
<div className="flex flex-col items-center justify-center h-64">
<div className="text-gray-400 text-lg mb-4">
@ -455,8 +445,8 @@ export default function BoxProductList(props: IBoxProductListProps) {
/>
</div>
</ProCard>
</Col>
)}
)}
</Col>
</Row>
);
}}

View File

@ -11,6 +11,7 @@ import {
RemarkFormItem,
SupplierFarmerList,
SupplierFormItem,
SupplierInvoiceList,
UserFormItem,
UserList,
} from '@/components';
@ -43,7 +44,7 @@ export default function BizProvider(props: any) {
dealerId={dealerVO.dealerId}
trigger={() => (
<Space>
<a>{dealerVO.shortName}</a>
<a>{`${dealerVO?.dealerType === 'MARKET' ? '市场' : '超市'} | ${dealerVO?.shortName}`}</a>
</Space>
)}
/>
@ -95,6 +96,49 @@ export default function BizProvider(props: any) {
);
},
},
supplierInvoice: {
renderFormItem: (_, props) => {
return (
<ProFormSelect
{...props}
{...props?.fieldProps}
request={async (params) => {
const { data } =
await business.supplierInvoice.listSupplierInvoice({
supplierInvoiceListQry: {
...params,
},
});
return (
data?.map((item) => {
return {
label: `${item.supplierName} | ${item.invoiceSn}`,
value: item.supplierInvoiceId,
};
}) || []
);
}}
/>
);
},
render: (supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO) => {
return (
<SupplierInvoiceList
ghost={true}
mode={'detail'}
supplierInvoiceId={supplierInvoiceVO.supplierInvoiceId}
trigger={() => (
<Space>
<a>
{`${supplierInvoiceVO.supplierName} | ${supplierInvoiceVO.invoiceSn}`}
</a>
</Space>
)}
/>
);
},
},
orderCost: {
renderFormItem: (_, props) => {
return (

View File

@ -25,6 +25,7 @@ export type BizValueType =
| 'paymentTask'
| 'company'
| 'orderCost'
| 'supplierInvoice'
| 'supplier';
export type FormType = 'modal' | 'drawer' | 'step';
export type ModeType =

View File

@ -1,7 +1,6 @@
import { SelectModal } from '@/components';
import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -20,7 +19,10 @@ export interface ICompanyPaymentAccountModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.CompanyPaymentAccountVO>[];
extraColumns?: ProColumns<
BusinessAPI.CompanyPaymentAccountVO,
BizValueType
>[];
}
export default function CompanyPaymentAccountModal(
@ -61,97 +63,101 @@ export default function CompanyPaymentAccountModal(
const intlPrefix = 'companyPaymentAccount';
// 公司账户列配置
const companyAccountColumns: ProColumns<BusinessAPI.CompanyPaymentAccountVO>[] =
[
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountName',
}),
dataIndex: 'accountName',
key: 'accountName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.bankName',
}),
dataIndex: 'bankName',
key: 'bankName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.branchName',
}),
dataIndex: 'branchName',
key: 'branchName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountNumber',
}),
dataIndex: 'accountNumber',
key: 'accountNumber',
search: false,
ellipsis: true,
},
...(initExtraColumns || []),
];
const companyAccountColumns: ProColumns<
BusinessAPI.CompanyPaymentAccountVO,
BizValueType
>[] = [
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountName',
}),
dataIndex: 'accountName',
key: 'accountName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.bankName',
}),
dataIndex: 'bankName',
key: 'bankName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.branchName',
}),
dataIndex: 'branchName',
key: 'branchName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountNumber',
}),
dataIndex: 'accountNumber',
key: 'accountNumber',
search: false,
ellipsis: true,
},
...(initExtraColumns || []),
];
// 私人账户列配置
const privateAccountColumns: ProColumns<BusinessAPI.CompanyPaymentAccountVO>[] =
[
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountName',
const privateAccountColumns: ProColumns<
BusinessAPI.CompanyPaymentAccountVO,
BizValueType
>[] = [
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountName',
}),
dataIndex: 'accountName',
key: 'accountName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountType',
}),
dataIndex: 'accountType',
key: 'accountType',
valueType: 'select',
valueEnum: {
BANK_CARD: intl.formatMessage({
id: intlPrefix + '.column.accountType.enum.bankCard',
}),
dataIndex: 'accountName',
key: 'accountName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountType',
ALIPAY: intl.formatMessage({
id: intlPrefix + '.column.accountType.enum.alipay',
}),
dataIndex: 'accountType',
key: 'accountType',
valueType: 'select',
valueEnum: {
BANK_CARD: intl.formatMessage({
id: intlPrefix + '.column.accountType.enum.bankCard',
}),
ALIPAY: intl.formatMessage({
id: intlPrefix + '.column.accountType.enum.alipay',
}),
WECHAT: intl.formatMessage({
id: intlPrefix + '.column.accountType.enum.wechat',
}),
},
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.bankName',
WECHAT: intl.formatMessage({
id: intlPrefix + '.column.accountType.enum.wechat',
}),
dataIndex: 'bankName',
key: 'bankName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountNumber',
}),
dataIndex: 'accountNumber',
key: 'accountNumber',
search: false,
ellipsis: true,
},
...(initExtraColumns || []),
];
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.bankName',
}),
dataIndex: 'bankName',
key: 'bankName',
search: false,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.accountNumber',
}),
dataIndex: 'accountNumber',
key: 'accountNumber',
search: false,
ellipsis: true,
},
...(initExtraColumns || []),
];
// 根据 Tab 获取当前列配置
const getCurrentColumns = ():
| ProColumns<BusinessAPI.CompanyPaymentAccountVO>[]
| ProColumns<BusinessAPI.CompanyPaymentAccountVO, BizValueType>[]
| undefined => {
if (activeKey === 'COMPANY_ACCOUNT') {
return companyAccountColumns;
@ -226,10 +232,6 @@ export default function CompanyPaymentAccountModal(
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
const selectedRowsMap = new Map<
string,

View File

@ -1,7 +1,6 @@
import { DealerList, SelectModal } from '@/components';
import { BizValueType, DealerList, SelectModal } from '@/components';
import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -20,7 +19,7 @@ export interface IDealerModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.DealerVO>[];
extraColumns?: ProColumns<BusinessAPI.DealerVO, BizValueType>[];
}
export default function DealerModal(props: IDealerModalProps) {
@ -54,7 +53,7 @@ export default function DealerModal(props: IDealerModalProps) {
const intl = useIntl();
const intlPrefix = 'dealer';
const columns: ProColumns<BusinessAPI.DealerVO>[] = [
const columns: ProColumns<BusinessAPI.DealerVO, BizValueType>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.shortName' }),
dataIndex: 'shortName',
@ -134,10 +133,6 @@ export default function DealerModal(props: IDealerModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重,
const selectedRowsMap = new Map<string, BusinessAPI.DealerVO>();

View File

@ -1,7 +1,6 @@
import { Remark, SelectModal } from '@/components';
import { BizValueType, Remark, SelectModal } from '@/components';
import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import {
ActionType,
LightFilter,
@ -34,7 +33,7 @@ export default function MaterialModal(props: IMaterialModalProps) {
setFileList(initialFileList || []);
}, [initialFileList]);
const columns: ProColumns<BusinessAPI.MaterialVO>[] = [
const columns: ProColumns<BusinessAPI.MaterialVO, BizValueType>[] = [
{
title: '素材名称',
dataIndex: 'name',
@ -167,10 +166,6 @@ export default function MaterialModal(props: IMaterialModalProps) {
</LightFilter>
),
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
}}
onFinish={onFinish}
num={(maxCount || 1) - fileList.length}

View File

@ -1,3 +1,6 @@
import { BizValueType } from '@/components';
import BizProvider from '@/components/Biz/BizProvider';
import { pagination } from '@/utils/pagination';
import { ProTable, ProTableProps } from '@ant-design/pro-components';
import type { ParamsType } from '@ant-design/pro-provider';
import { Modal, ModalProps, type TableProps } from 'antd';
@ -18,7 +21,7 @@ export interface ISelectModalProps<
num?: number;
selectedList?: DataType[];
modalProps: ModalProps;
tableProps: ProTableProps<DataType, Params>;
tableProps: ProTableProps<DataType, Params, BizValueType>;
ghost?: boolean;
disabled?: (record: DataType) => boolean;
}
@ -113,56 +116,65 @@ const SelectModal = forwardRef<
const renderTable = () => {
return (
<ProTable<DataType, Params>
ghost={true}
search={false}
scroll={{ x: 'max-content' }}
onRow={(data) => ({
onClick: () => {
if (disabled?.(data)) {
return;
}
if (selectType === 'radio') {
setSelectedRowKeys([data[rowKey]]);
setSelectedList([data]);
}
if (selectType === 'checkbox') {
if (selectedList.length >= (num || 1)) {
<BizProvider>
<ProTable<DataType, Params, BizValueType>
ghost={true}
search={false}
scroll={{ x: 'max-content' }}
onRow={(data) => ({
onClick: () => {
if (disabled?.(data)) {
return;
}
if (selectedRowKeys.length === 0) {
if (selectType === 'radio') {
setSelectedRowKeys([data[rowKey]]);
setSelectedList([data]);
} else {
if (selectedRowKeys.includes(data[rowKey])) {
setSelectedRowKeys(
selectedRowKeys
.filter((v) => v !== data[rowKey])
.slice(0, num || 1),
);
setSelectedList(
selectedList
.filter((v) => v?.[rowKey] !== data[rowKey])
.slice(0, num || 1),
);
}
if (selectType === 'checkbox') {
if (selectedList.length >= (num || 1)) {
return;
}
if (selectedRowKeys.length === 0) {
setSelectedRowKeys([data[rowKey]]);
setSelectedList([data]);
} else {
setSelectedRowKeys(
[...selectedRowKeys, data[rowKey]].slice(0, num || 1),
);
setSelectedList([...selectedList, data].slice(0, num || 1));
if (selectedRowKeys.includes(data[rowKey])) {
setSelectedRowKeys(
selectedRowKeys
.filter((v) => v !== data[rowKey])
.slice(0, num || 1),
);
setSelectedList(
selectedList
.filter((v) => v?.[rowKey] !== data[rowKey])
.slice(0, num || 1),
);
} else {
setSelectedRowKeys(
[...selectedRowKeys, data[rowKey]].slice(0, num || 1),
);
setSelectedList(
[...selectedList, data].slice(0, num || 1),
);
}
}
}
}
if (ghost) {
onFinish([data]);
}
},
})}
rowSelection={rowSelection}
{...tableProps}
/>
if (ghost) {
onFinish([data]);
}
},
})}
rowSelection={rowSelection}
{...tableProps}
pagination={{
...pagination(),
position: ['bottomRight'],
defaultPageSize: 10,
}}
/>
</BizProvider>
);
};
@ -172,7 +184,7 @@ const SelectModal = forwardRef<
return (
<Modal
width={1000}
width={1200}
{...modalProps}
open={open}
onOk={async (event) => {

View File

@ -0,0 +1,157 @@
.bellIcon {
font-size: 20px;
cursor: pointer;
padding: 8px;
transition: all 0.3s;
color: rgba(0, 0, 0, 65%);
&:hover {
color: #1890ff;
}
}
// 确保红点样式明显
:global {
.ant-badge-count,
.ant-badge-dot {
box-shadow: 0 0 0 1px #fff;
}
}
.dropdownContent {
width: 380px;
max-height: 500px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 15%);
display: flex;
flex-direction: column;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #f0f0f0;
.title {
font-size: 16px;
font-weight: 500;
color: #262626;
}
.count {
font-size: 14px;
color: #ff4d4f;
}
}
.messageList {
flex: 1;
overflow-y: auto;
max-height: 400px;
padding: 8px;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 20%);
border-radius: 3px;
&:hover {
background-color: rgba(0, 0, 0, 30%);
}
}
}
.messageItem {
cursor: pointer;
padding: 12px 16px;
transition: background-color 0.3s;
border-bottom: none;
&:hover {
background-color: #f5f5f5;
}
&.unread {
background-color: #f6ffed;
}
}
.messageContent {
flex: 1;
}
.messageTitle {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #262626;
margin-bottom: 4px;
position: relative;
}
.unreadDot {
display: inline-block;
width: 6px;
height: 6px;
background-color: #ff4d4f;
border-radius: 50%;
margin-left: 8px;
}
.messageDesc {
font-size: 13px;
color: #595959;
line-height: 1.5;
margin-bottom: 4px;
display: box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.messageTime {
font-size: 12px;
color: #8c8c8c;
}
.loadingWrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 40px 0;
}
.emptyWrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 40px 0;
}
.footer {
display: flex;
justify-content: center;
align-items: center;
padding: 12px 16px;
border-top: 1px solid #f0f0f0;
cursor: pointer;
transition: background-color 0.3s;
font-size: 14px;
color: #1890ff;
&:hover {
background-color: #f5f5f5;
}
span {
margin-right: 4px;
}
}

View File

@ -0,0 +1,189 @@
import { business } from '@/services';
import { BellOutlined, LoadingOutlined, MoreOutlined } from '@ant-design/icons';
import { history, useIntl } from '@umijs/max';
import { useRequest } from 'ahooks';
import { Badge, Dropdown, Empty, List, message, Spin } from 'antd';
import React, { useMemo, useState } from 'react';
import styles from './NotificationMessage.module.less';
interface NotificationMessageProps {
adminId?: string;
}
const NotificationMessage: React.FC<NotificationMessageProps> = ({
adminId,
}) => {
const intl = useIntl();
const [dropdownOpen, setDropdownOpen] = useState(false);
// 获取未读消息数量
const { data: unreadCountData, refresh: refreshUnreadCount } = useRequest(
() =>
business.messageReceiver.getUnreadCount({
messageReceiverUnreadCountQry: {
adminId: adminId || '',
},
}),
{
ready: !!adminId,
refreshDeps: [adminId],
},
);
const unreadCount = unreadCountData?.data || 0;
// 获取消息列表只获取前5条未读消息
const {
data: messageListData,
loading: messageListLoading,
refresh: refreshMessageList,
} = useRequest(
() =>
business.messageReceiver.pageMessageReceiver({
messageReceiverPageQry: {
pageIndex: 1,
pageSize: 5,
},
}),
{
ready: dropdownOpen && !!adminId,
refreshDeps: [dropdownOpen, adminId],
},
);
const messageList = messageListData?.data || [];
// 标记已读
const { run: markAsRead } = useRequest(
(messageReceiverId: string) =>
business.messageReceiver.markReadMessageReceiver({
messageReceiverId: messageReceiverId,
}),
{
manual: true,
onSuccess: () => {
refreshUnreadCount();
refreshMessageList();
},
onError: (error) => {
message.error(
intl.formatMessage({ id: 'notification.markReadFailed' }),
);
console.error('标记已读失败:', error);
},
},
);
// 点击消息项
const handleMessageClick = (item: BusinessAPI.MessageReceiverVO) => {
if (!item.isRead) {
markAsRead(item.messageReceiverId);
}
// 可以跳转到消息详情页面
// history.push(`/message/detail/${item.messageReceiverId}`);
};
// 查看更多消息
const handleViewMore = () => {
setDropdownOpen(false);
history.push('/message');
};
// 下拉菜单内容
const dropdownContent = useMemo(() => {
return (
<div className={styles.dropdownContent}>
<div className={styles.header}>
<span className={styles.title}>
{intl.formatMessage({ id: 'notification.title' })}
</span>
{unreadCount > 0 && (
<span className={styles.count}>
{intl.formatMessage(
{ id: 'notification.unreadCount' },
{ count: unreadCount },
)}
</span>
)}
</div>
<div className={styles.messageList}>
{messageListLoading ? (
<div className={styles.loadingWrapper}>
<Spin indicator={<LoadingOutlined spin />} />
</div>
) : messageList.length > 0 ? (
<List
dataSource={messageList}
renderItem={(item: BusinessAPI.MessageReceiverVO) => (
<List.Item
key={item.messageReceiverId}
className={`${styles.messageItem} ${
!item.isRead ? styles.unread : ''
}`}
onClick={() => handleMessageClick(item)}
>
<div className={styles.messageContent}>
<div className={styles.messageTitle}>
{item.messageVO?.title || '消息通知'}
{!item.isRead && <span className={styles.unreadDot} />}
</div>
<div className={styles.messageDesc}>
{item.messageVO?.content || ''}
</div>
<div className={styles.messageTime}>{item.createdAt}</div>
</div>
</List.Item>
)}
/>
) : (
<div className={styles.emptyWrapper}>
<Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={intl.formatMessage({
id: 'notification.noMessages',
})}
/>
</div>
)}
</div>
{messageList.length > 0 && (
<div className={styles.footer} onClick={handleViewMore}>
<span>{intl.formatMessage({ id: 'notification.viewMore' })}</span>
<MoreOutlined />
</div>
)}
</div>
);
}, [
messageList,
messageListLoading,
unreadCount,
intl,
markAsRead,
handleMessageClick,
handleViewMore,
]);
return (
<Dropdown
open={dropdownOpen}
onOpenChange={setDropdownOpen}
trigger={['click']}
placement="bottomRight"
dropdownRender={() => dropdownContent}
>
<Badge
count={unreadCount}
overflowCount={99}
size="small"
offset={[-5, 5]}
>
<BellOutlined className={styles.bellIcon} />
</Badge>
</Dropdown>
);
};
export default NotificationMessage;

View File

@ -0,0 +1,433 @@
import { BizContainer, BizValueType, ModeType } from '@/components';
import { business } from '@/services';
import { useIntl } from '@@/exports';
import {
ProColumns,
ProFormDependency,
ProFormItem,
ProFormSelect,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { Button, Space, Tag, Typography } from 'antd';
import React from 'react';
interface INotifyMessageTemplateListProps {
ghost?: boolean;
search?: boolean;
onValueChange?: () => void;
mode?: ModeType;
trigger?: () => React.ReactNode;
}
const variables = [
// 采购单
'经销商简称',
'车次号',
'车牌号',
'目的地',
'利润金额',
'瓜农姓名',
'瓜农货款',
'录入员姓名',
'录入员提审时间',
// 采购单审核
'审核员姓名',
'审核员审核时间',
'审核员驳回原因',
// 采购单审批
'审批员姓名',
'审批员审批时间',
'审批员驳回原因',
];
export default function NotifyMessageTemplateList(
props: INotifyMessageTemplateListProps,
) {
const {
ghost = false,
search = true,
mode = 'page',
trigger,
onValueChange,
} = props;
const intl = useIntl();
const intlPrefix = 'notifyMessageTemplate';
// 模板分类映射
const templateCategoryMap: Record<string, { label: string }> = {
PURCHASE_ORDER_MESSAGE_TEMPLATE: {
label: intl.formatMessage({
id: intlPrefix + '.templateCategory.purchaseOrderMessageTemplate',
}),
},
};
// 模板事件映射
const templateSceneMap: Record<string, { label: string }> = {
WAIT_AUDIT: {
label: intl.formatMessage({
id: intlPrefix + '.templateScene.waitAudit',
}),
},
WAIT_APPROVE: {
label: intl.formatMessage({
id: intlPrefix + '.templateScene.waitApprove',
}),
},
APPROVE_PASS: {
label: intl.formatMessage({
id: intlPrefix + '.templateScene.approvePass',
}),
},
AUDIT_REJECT: {
label: intl.formatMessage({
id: intlPrefix + '.templateScene.auditReject',
}),
},
APPROVE_REJECT: {
label: intl.formatMessage({
id: intlPrefix + '.templateScene.approveReject',
}),
},
};
// 表单上下文
const formContext = [
<ProFormText
key={'messageTemplateId'}
name={'messageTemplateId'}
hidden={true}
/>,
<ProFormSelect
key={'templateCategory'}
name={'templateCategory'}
label={intl.formatMessage({
id: intlPrefix + '.form.templateCategory.label',
})}
required={true}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.templateCategory.placeholder',
})}
rules={[
{
required: true,
message: intl.formatMessage({
id: intlPrefix + '.form.templateCategory.required',
}),
},
]}
options={Object.keys(templateCategoryMap).map((key) => ({
label: templateCategoryMap[key].label,
value: key,
}))}
/>,
<ProFormSelect
key={'templateScene'}
name={'templateScene'}
label={intl.formatMessage({
id: intlPrefix + '.form.templateScene.label',
})}
required={true}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.templateScene.placeholder',
})}
rules={[
{
required: true,
message: intl.formatMessage({
id: intlPrefix + '.form.templateScene.required',
}),
},
]}
options={Object.keys(templateSceneMap).map((key) => ({
label: templateSceneMap[key].label,
value: key,
}))}
/>,
<ProFormText
key={'titleTemplate'}
name={'titleTemplate'}
label={intl.formatMessage({
id: intlPrefix + '.form.titleTemplate.label',
})}
required={true}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.titleTemplate.placeholder',
})}
rules={[
{
required: true,
message: intl.formatMessage({
id: intlPrefix + '.form.titleTemplate.required',
}),
},
]}
/>,
<ProFormTextArea
key={'description'}
name={'description'}
label={intl.formatMessage({
id: intlPrefix + '.form.description.label',
})}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.description.placeholder',
})}
fieldProps={{
autoSize: { minRows: 3, maxRows: 6 },
showCount: true,
maxLength: 200,
}}
/>,
<ProFormTextArea
key={'contentTemplate'}
name={'contentTemplate'}
label={intl.formatMessage({
id: intlPrefix + '.form.contentTemplate.label',
})}
required={true}
placeholder={intl.formatMessage({
id: intlPrefix + '.form.contentTemplate.placeholder',
})}
rules={[
{
required: true,
message: intl.formatMessage({
id: intlPrefix + '.form.contentTemplate.required',
}),
},
]}
tooltip={intl.formatMessage({
id: intlPrefix + '.form.contentTemplate.tooltip',
})}
fieldProps={{
autoSize: { minRows: 5, maxRows: 10 },
showCount: true,
maxLength: 2000,
}}
/>,
<ProFormDependency key={'variables'} name={['contentTemplate']}>
{({ contentTemplate }, form) => (
<ProFormItem
style={{
width: '100%',
}}
label={'模板变量'}
tooltip={intl.formatMessage({
id: intlPrefix + '.form.contentTemplate.insertVariable',
})}
>
<>
{variables.length === 0 ? (
<Typography.Text type="secondary" className="text-sm">
{intl.formatMessage({
id: intlPrefix + '.form.contentTemplate.noVariables',
})}
</Typography.Text>
) : (
<Space wrap size={[8, 8]}>
{variables.map((variable: string) => (
<Button
key={variable}
type="dashed"
size="small"
onClick={() => {
form.setFieldValue(
'contentTemplate',
`${contentTemplate || ''}{{${variable}}}`,
);
}}
>
{`{{${variable}}}`}
</Button>
))}
</Space>
)}
</>
</ProFormItem>
)}
</ProFormDependency>,
<ProFormSelect
key={'roleIds'}
name={'roleIds'}
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,
})) ?? []
);
}}
/>,
];
const columns: ProColumns<BusinessAPI.MessageTemplateVO, BizValueType>[] = [
{
title: intl.formatMessage({
id: intlPrefix + '.column.templateCategory',
}),
dataIndex: 'templateCategory',
key: 'templateCategory',
valueType: 'select',
valueEnum: Object.entries(templateCategoryMap).reduce(
(acc, [key, value]) => ({
...acc,
[key]: { text: value.label },
}),
{},
),
render: (_, record) => {
const categoryInfo = templateCategoryMap[record.templateCategory];
return categoryInfo ? (
<Tag>{categoryInfo.label}</Tag>
) : (
<Tag>{record.templateCategory}</Tag>
);
},
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.templateScene',
}),
dataIndex: 'templateScene',
key: 'templateScene',
valueType: 'select',
valueEnum: Object.entries(templateSceneMap).reduce(
(acc, [key, value]) => ({
...acc,
[key]: { text: value.label },
}),
{},
),
render: (_, record) => {
const sceneInfo = templateSceneMap[record.templateScene];
return sceneInfo ? (
<Tag>{sceneInfo.label}</Tag>
) : (
<Tag>{record.templateScene}</Tag>
);
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.titleTemplate' }),
dataIndex: 'titleTemplate',
key: 'titleTemplate',
valueType: 'text',
ellipsis: true,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.contentTemplate' }),
dataIndex: 'contentTemplate',
key: 'contentTemplate',
valueType: 'text',
ellipsis: true,
render: (_, record) => {
return <pre>{record.contentTemplate}</pre>;
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.description' }),
dataIndex: 'description',
key: 'description',
valueType: 'text',
ellipsis: true,
search: false,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.role' }),
dataIndex: 'roleIds',
key: 'roleIds',
valueType: 'select',
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,
})) ?? []
);
},
},
];
const detailColumns: ProDescriptionsItemProps<
BusinessAPI.MessageTemplateVO,
BizValueType
>[] = columns as ProDescriptionsItemProps<
BusinessAPI.MessageTemplateVO,
BizValueType
>[];
return (
<BizContainer<
typeof business.messageTemplate,
BusinessAPI.MessageTemplateVO,
BusinessAPI.MessageTemplatePageQry
>
rowKey={'messageTemplateId'}
permission={'operation-notify-message-template'}
func={business.messageTemplate}
method={'messageTemplate'}
methodUpper={'MessageTemplate'}
intlPrefix={intlPrefix}
modeType={mode}
onValueChange={onValueChange}
container={{ ghost }}
remark={{
mode: 'editor',
}}
status={true}
page={{
fieldProps: {
bordered: true,
ghost,
//@ts-ignore
search,
},
columns,
options: () => [],
}}
create={{
formType: 'drawer',
formContext,
initValues: {
status: true,
},
}}
update={{
formType: 'drawer',
formContext,
}}
destroy={false}
detail={{
formType: 'drawer',
columns: detailColumns,
trigger,
}}
/>
);
}

View File

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

View File

@ -1,7 +1,6 @@
import {
BizContainer,
BizValueType,
CompanyList,
CostList,
ModeType,
OrderCostPay,
@ -128,33 +127,8 @@ export default function OrderCostList(props: IOrderCostListProps) {
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
dataIndex: 'orderCompany',
valueType: 'select',
request: async (params) => {
const { data } = await business.company.listCompany({
companyListQry: {
...params,
},
});
return (
data?.map((item) => {
return {
label: item.fullName,
value: item.companyId,
};
}) || []
);
},
render: (_, record) => {
return (
<CompanyList
ghost={true}
mode={'detail'}
companyId={record.orderCompany.companyId}
trigger={() => <a href={'#'}>{record.orderCompany.fullName}</a>}
/>
);
},
key: 'companyId',
valueType: 'company',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),

View File

@ -1,7 +1,6 @@
import { SelectModal } from '@/components';
import { BizValueType, DealerFormItem, SelectModal } from '@/components';
import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -21,7 +20,7 @@ export interface IOrderModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.OrderVO>[];
extraColumns?: ProColumns<BusinessAPI.OrderVO, BizValueType>[];
}
export default function OrderModal(props: IOrderModalProps) {
@ -41,7 +40,7 @@ export default function OrderModal(props: IOrderModalProps) {
const sessionKey = `orderList`;
const intl = useIntl();
const intlPrefix = 'order';
const [params, setParams] = useState<BusinessAPI.DealerPageQry>(
const [params, setParams] = useState<BusinessAPI.OrderPageQry>(
initParams || {},
);
@ -54,7 +53,7 @@ export default function OrderModal(props: IOrderModalProps) {
}
}, [initParams]);
const columns: ProColumns<BusinessAPI.OrderVO>[] = [
const columns: ProColumns<BusinessAPI.OrderVO, BizValueType>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.order' }),
key: 'orderId',
@ -176,10 +175,6 @@ export default function OrderModal(props: IOrderModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重,
const selectedRowsMap = new Map<string, BusinessAPI.OrderVO>();
@ -269,6 +264,22 @@ export default function OrderModal(props: IOrderModalProps) {
}}
>
{extraFilter}
<DealerFormItem
fieldProps={{
showSearch: true,
allowClear: true,
autoClearSearchValue: true,
}}
value={params.dealerId}
mode={'read'}
text={'选择经销商'}
onChange={(dealerId) => {
setParams({
...params,
dealerId: dealerId,
});
}}
/>
<ProFormSelect
label={'采购单状态'}
name={'state'}

View File

@ -288,7 +288,7 @@ export default function OrderShipList(props: IOrderShipListProps) {
},
companyVO: {
companyId: orderShip.companyId,
shortName: orderShip.companyName,
fullName: orderShip.companyName,
},
};
},

View File

@ -2,7 +2,6 @@ import { SelectModal } from '@/components';
import { business } from '@/services';
import { formatCurrency } from '@/utils/format';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -271,7 +270,7 @@ export default function OrderShipModal(props: IOrderShipModalProps) {
},
companyVO: {
companyId: orderShip.companyId,
shortName: orderShip.companyName,
fullName: orderShip.companyName,
},
};
}) || [],
@ -279,10 +278,6 @@ export default function OrderShipModal(props: IOrderShipModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
const selectedRowsMap = new Map<string, BusinessAPI.OrderShipVO>();
selectedRows.forEach((item: BusinessAPI.OrderShipVO) => {

View File

@ -2,7 +2,6 @@ import {
BizContainer,
BizValueType,
ButtonAccess,
CompanyList,
ModeType,
} from '@/components';
import { business } from '@/services';
@ -173,33 +172,8 @@ export default function OrderSupplierList(props: IOrderSupplierListProps) {
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
dataIndex: 'orderCompany',
valueType: 'select',
request: async (params) => {
const { data } = await business.company.listCompany({
companyListQry: {
...params,
},
});
return (
data?.map((item) => {
return {
label: item.fullName,
value: item.companyId,
};
}) || []
);
},
render: (_, record) => {
return (
<CompanyList
ghost={true}
mode={'detail'}
companyId={record.orderCompany.companyId}
trigger={() => <a href={'#'}>{record.orderCompany.fullName}</a>}
/>
);
},
key: 'companyId',
valueType: 'company',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),
@ -264,7 +238,7 @@ export default function OrderSupplierList(props: IOrderSupplierListProps) {
isPaid: activeKey! as any,
}),
poStates: ['COMPLETED'],
type: 'OTHER_STALL'
type: 'OTHER_STALL',
},
rowSelection: {
onChange: (_, selectedRows) => setSelectedRows(selectedRows),

View File

@ -2,7 +2,6 @@ import {
BizContainer,
BizValueType,
ButtonAccess,
CompanyList,
ModeType,
} from '@/components';
import { business } from '@/services';
@ -11,7 +10,7 @@ import { useIntl } from '@@/exports';
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
import { ProColumns } from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { Button, Image, Modal, Space } from 'antd';
import { Button, Image, Modal, Space, Tag } from 'antd';
import React, { useState } from 'react';
interface IOrderSupplierListProps {
@ -89,6 +88,49 @@ export default function OrderSupplierList(props: IOrderSupplierListProps) {
return record.invoiceAmount - record.depositAmount || 0;
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.supplierInvoice' }),
dataIndex: 'supplierInvoiceVO',
key: 'supplierInvoiceId',
search: false,
valueType: 'supplierInvoice',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceUpload' }),
dataIndex: 'invoiceUpload',
key: 'invoiceUpload',
search: false,
valueType: 'switch',
render: (_, record) => (
<Tag color={record.invoiceUpload ? 'green' : 'red'}>
{record.invoiceUpload
? intl.formatMessage({
id: intlPrefix + '.column.invoiceUpload.uploaded',
})
: intl.formatMessage({
id: intlPrefix + '.column.invoiceUpload.notUploaded',
})}
</Tag>
),
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.contractUpload' }),
dataIndex: 'contractUpload',
key: 'contractUpload',
search: false,
valueType: 'switch',
render: (_, record) => (
<Tag color={record.contractUpload ? 'green' : 'red'}>
{record.contractUpload
? intl.formatMessage({
id: intlPrefix + '.column.contractUpload.uploaded',
})
: intl.formatMessage({
id: intlPrefix + '.column.contractUpload.notUploaded',
})}
</Tag>
),
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.idCard',
@ -181,33 +223,8 @@ export default function OrderSupplierList(props: IOrderSupplierListProps) {
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
dataIndex: 'orderCompany',
valueType: 'select',
request: async (params) => {
const { data } = await business.company.listCompany({
companyListQry: {
...params,
},
});
return (
data?.map((item) => {
return {
label: item.fullName,
value: item.companyId,
};
}) || []
);
},
render: (_, record) => {
return (
<CompanyList
ghost={true}
mode={'detail'}
companyId={record.orderCompany.companyId}
trigger={() => <a href={'#'}>{record.orderCompany.fullName}</a>}
/>
);
},
key: 'companyId',
valueType: 'company',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),

View File

@ -1,14 +1,14 @@
import { SelectModal } from '@/components';
import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatBankCard, formatIdCard, formatPhone } from '@/utils/format';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
import {
ActionType,
LightFilter,
ProColumns,
ProFormDateRangePicker,
ProFormSelect,
} from '@ant-design/pro-components';
import { Alert, ModalProps, Row, Space, Tag } from 'antd';
@ -23,7 +23,7 @@ export interface IOrderSupplierModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.OrderSupplierVO>[];
extraColumns?: ProColumns<BusinessAPI.OrderSupplierVO, BizValueType>[];
}
export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
@ -60,19 +60,13 @@ export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
}
}, [initParams]);
const columns: ProColumns<BusinessAPI.OrderSupplierVO>[] = [
const columns: ProColumns<BusinessAPI.OrderSupplierVO, BizValueType>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.order' }),
dataIndex: 'orderVO',
key: 'orderId',
search: false,
render: (_, orderSupplierVO: BusinessAPI.OrderSupplierVO) => {
const orderVO = orderSupplierVO.orderVO;
return (
orderVO &&
`${orderVO.orderVehicle?.dealerName} | 第 ${orderVO.orderVehicle?.vehicleNo || '暂无'} 车 | ${orderVO.orderSn || '暂无'}`
);
},
valueType: 'order',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
@ -106,6 +100,82 @@ export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
return record.invoiceAmount - record.depositAmount || 0;
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.supplierInvoice' }),
dataIndex: 'supplierInvoiceVO',
key: 'supplierInvoiceId',
search: false,
valueType: 'supplierInvoice',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceUpload' }),
dataIndex: 'invoiceUpload',
key: 'invoiceUpload',
search: false,
valueType: 'switch',
render: (_, record) => (
<Tag color={record.invoiceUpload ? 'green' : 'red'}>
{record.invoiceUpload
? intl.formatMessage({
id: intlPrefix + '.column.invoiceUpload.uploaded',
})
: intl.formatMessage({
id: intlPrefix + '.column.invoiceUpload.notUploaded',
})}
</Tag>
),
},
{
title: '开票状态',
key: 'invoiceStatus',
render: (_, orderSupplierVO: BusinessAPI.OrderSupplierVO) => {
let invoiceStatus = 'NOT_INVOICE';
if (orderSupplierVO.invoiceUpload && orderSupplierVO.invoiceId) {
if (
orderSupplierVO.supplierId ===
orderSupplierVO.supplierInvoiceVO?.supplierId
) {
invoiceStatus = 'SELF';
}
if (
orderSupplierVO.supplierId !==
orderSupplierVO.supplierInvoiceVO?.supplierId
) {
invoiceStatus = 'AGENT';
}
} else {
invoiceStatus = 'NOT_INVOICE';
}
switch (invoiceStatus) {
case 'SELF':
return '自开票';
case 'AGENT':
return '代开票';
case 'NOT_INVOICE':
return '未开票';
default:
}
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.contractUpload' }),
dataIndex: 'contractUpload',
key: 'contractUpload',
search: false,
valueType: 'switch',
render: (_, record) => (
<Tag color={record.contractUpload ? 'green' : 'red'}>
{record.contractUpload
? intl.formatMessage({
id: intlPrefix + '.column.contractUpload.uploaded',
})
: intl.formatMessage({
id: intlPrefix + '.column.contractUpload.notUploaded',
})}
</Tag>
),
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.idCard',
@ -198,27 +268,6 @@ export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
</div>
),
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
dataIndex: ['orderCompany', 'companyId'],
valueType: 'select',
request: async (params) => {
const { data } = await business.company.listCompany({
companyListQry: {
...params,
},
});
return (
data?.map((item) => {
return {
label: item.fullName,
value: item.companyId,
};
}) || []
);
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),
dataIndex: 'isPaid',
@ -309,10 +358,6 @@ export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
const selectedRowsMap = new Map<
string,
@ -400,49 +445,48 @@ export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
}}
>
{extraFilter}
{/*<ProFormSelect*/}
{/* label={'供应商类型'}*/}
{/* name={'type'}*/}
{/* placeholder={'请选择供应商类型'}*/}
{/* valueEnum={{*/}
{/* FARMER: intl.formatMessage({*/}
{/* id: intlPrefix + '.column.type.farmer',*/}
{/* }),*/}
{/* STALL: intl.formatMessage({*/}
{/* id: intlPrefix + '.column.type.stall',*/}
{/* }),*/}
{/* OTHER_STALL: intl.formatMessage({*/}
{/* id: intlPrefix + '.column.type.otherStall',*/}
{/* }),*/}
{/* }}*/}
{/*<ProFormDateRangePicker*/}
{/* label={'发货时间'}*/}
{/* name={'shippingDate'}*/}
{/* placeholder={'请选择发货时间'}*/}
{/* fieldProps={{*/}
{/* showSearch: true,*/}
{/* allowClear: true,*/}
{/* autoClearSearchValue: true,*/}
{/* picker: 'date',*/}
{/* }}*/}
{/*/>*/}
<ProFormSelect
label={'是否付款'}
name={'isPaid'}
placeholder={'请选择是否付款'}
valueEnum={{
true: intl.formatMessage({
id: intlPrefix + '.column.isPaid.paid',
}),
false: intl.formatMessage({
id: intlPrefix + '.column.isPaid.unpaid',
}),
}}
<ProFormDateRangePicker
label={'开票时间'}
name={'invoiceDate'}
placeholder={'请选择开票时间'}
fieldProps={{
showSearch: true,
allowClear: true,
autoClearSearchValue: true,
picker: 'date',
}}
/>
{initParams?.isPaid === undefined && (
<ProFormSelect
label={'是否付款'}
name={'isPaid'}
placeholder={'请选择是否付款'}
valueEnum={{
true: intl.formatMessage({
id: intlPrefix + '.column.isPaid.paid',
}),
false: intl.formatMessage({
id: intlPrefix + '.column.isPaid.unpaid',
}),
}}
fieldProps={{
showSearch: true,
allowClear: true,
autoClearSearchValue: true,
}}
/>
)}
</LightFilter>
),
search: {
placeholder: '请输入供应商姓名',
placeholder: '请输入瓜农姓名',
onSearch: async (value: string) => {
setParams({
...params,

View File

@ -1,12 +1,12 @@
import { BizValueType, CompanyList } from '@/components';
import { BizValueType } from '@/components';
import BizProvider from '@/components/Biz/BizProvider';
import { business } from '@/services';
import { useIntl } from '@@/exports';
import {
ProColumns,
ProTable,
ProTableProps,
} from '@ant-design/pro-components';
import { Tag } from 'antd';
type IOrderSupplierSelectListProps = ProTableProps<
BusinessAPI.OrderSupplierVO,
@ -62,36 +62,85 @@ export default function OrderSupplierSelectList(
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
dataIndex: 'orderCompany',
valueType: 'select',
request: async (params) => {
const { data } = await business.company.listCompany({
companyListQry: {
...params,
},
});
title: intl.formatMessage({
id: intlPrefix + '.column.supplierInvoice',
}),
dataIndex: 'supplierInvoiceVO',
key: 'supplierInvoiceId',
search: false,
valueType: 'supplierInvoice',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceUpload' }),
dataIndex: 'invoiceUpload',
key: 'invoiceUpload',
search: false,
valueType: 'switch',
render: (_, record) => (
<Tag color={record.invoiceUpload ? 'green' : 'red'}>
{record.invoiceUpload
? intl.formatMessage({
id: intlPrefix + '.column.invoiceUpload.uploaded',
})
: intl.formatMessage({
id: intlPrefix + '.column.invoiceUpload.notUploaded',
})}
</Tag>
),
},
{
title: '开票状态',
key: 'invoiceStatus',
render: (_, orderSupplierVO: BusinessAPI.OrderSupplierVO) => {
let invoiceStatus = 'NOT_INVOICE';
if (orderSupplierVO.invoiceUpload && orderSupplierVO.invoiceId) {
if (
orderSupplierVO.supplierId ===
orderSupplierVO.supplierInvoiceVO?.supplierId
) {
invoiceStatus = 'SELF';
}
if (
orderSupplierVO.supplierId !==
orderSupplierVO.supplierInvoiceVO?.supplierId
) {
invoiceStatus = 'AGENT';
}
} else {
invoiceStatus = 'NOT_INVOICE';
}
return (
data?.map((item) => {
return {
label: item.fullName,
value: item.companyId,
};
}) || []
);
},
render: (_, record) => {
return (
<CompanyList
ghost={true}
mode={'detail'}
companyId={record.orderCompany.companyId}
trigger={() => <a href={'#'}>{record.orderCompany.fullName}</a>}
/>
);
switch (invoiceStatus) {
case 'SELF':
return '自开票';
case 'AGENT':
return '代开票';
case 'NOT_INVOICE':
return '未开票';
default:
}
},
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.contractUpload',
}),
dataIndex: 'contractUpload',
key: 'contractUpload',
search: false,
valueType: 'switch',
render: (_, record) => (
<Tag color={record.contractUpload ? 'green' : 'red'}>
{record.contractUpload
? intl.formatMessage({
id: intlPrefix + '.column.contractUpload.uploaded',
})
: intl.formatMessage({
id: intlPrefix + '.column.contractUpload.notUploaded',
})}
</Tag>
),
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),
dataIndex: 'isPaid',

View File

@ -381,11 +381,8 @@ export default function PaymentRecordList(props: IPaymentRecordListProps) {
},
}}
create={false}
update={{
formType: 'drawer',
formContext: [],
}}
destroy={{}}
update={false}
destroy={false}
detail={{
rowId: paymentRecordId,
formType: 'drawer',

View File

@ -3,8 +3,6 @@ import {
ButtonAccess,
InsertPosition,
OrderSupplierSelectList,
SupplierFarmerList,
SupplierInvoiceList,
SupplierSelect,
} from '@/components';
import OrderSupplierModal from '@/components/Order/OrderSupplierModal';
@ -22,7 +20,7 @@ import {
RouteContext,
RouteContextType,
} from '@ant-design/pro-components';
import { Button, Col, Image, message, Row, Space, Table, Tag } from 'antd';
import { Button, Col, Image, message, Row, Table, Tag } from 'antd';
import { useState } from 'react';
export interface IPaymentTaskCreateProps {
@ -245,96 +243,6 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
rowKey="orderSupplierId"
dataSource={selectedOrderSupplierList}
columns={[
{
title: '开票瓜农',
dataIndex: 'supplierInvoiceVO',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierFarmerList
ghost={true}
mode={'detail'}
supplierId={supplierInvoiceVO.supplierId}
trigger={() => (
<a>{supplierInvoiceVO.supplierName}</a>
)}
/>
)
);
},
},
{
title: '发票编码',
dataIndex: 'supplierInvoiceVO',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierInvoiceList
ghost={true}
mode={'detail'}
supplierInvoiceId={
supplierInvoiceVO.supplierInvoiceId
}
trigger={() => (
<Space>
<a>{supplierInvoiceVO.invoiceSn}</a>
</Space>
)}
/>
)
);
},
},
// 开票状态(自开票,代开票,未开票)
{
title: '开票状态',
key: 'invoiceStatus',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
let invoiceStatus = 'NOT_INVOICE';
if (
orderSupplierVO.invoiceUpload &&
orderSupplierVO.invoiceId
) {
if (
orderSupplierVO.supplierId ===
orderSupplierVO.supplierInvoiceVO?.supplierId
) {
invoiceStatus = 'SELF';
}
if (
orderSupplierVO.supplierId !==
orderSupplierVO.supplierInvoiceVO?.supplierId
) {
invoiceStatus = 'AGENT';
}
} else {
invoiceStatus = 'NOT_INVOICE';
}
switch (invoiceStatus) {
case 'SELF':
return '自开票';
case 'AGENT':
return '代开票';
case 'NOT_INVOICE':
return '未开票';
default:
}
},
},
{
title: '操作',
key: 'action',

View File

@ -7,8 +7,6 @@ import {
PaymentRecordList,
PaymentTaskCreate,
PaymentTaskPay,
SupplierFarmerList,
SupplierInvoiceList,
} from '@/components';
import { business } from '@/services';
import { calculateOrderSupplierStatistics } from '@/utils/calculateOrderSupplierStatistics';
@ -20,7 +18,7 @@ import {
StatisticCard,
} from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { Image, Space } from 'antd';
import { Image } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
interface IPaymentTaskListProps {
@ -254,59 +252,6 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
<OrderSupplierSelectList
rowKey="orderSupplierId"
dataSource={statistics.selfInvoiceList}
columns={[
{
title: '开票瓜农',
dataIndex: 'supplierInvoiceVO',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierFarmerList
ghost={true}
mode={'detail'}
supplierId={supplierInvoiceVO.supplierId}
trigger={() => (
<a>{supplierInvoiceVO.supplierName}</a>
)}
/>
)
);
},
},
{
title: '发票编码',
dataIndex: 'supplierInvoiceVO',
key: 'invoiceSn',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierInvoiceList
ghost={true}
mode={'detail'}
supplierInvoiceId={
supplierInvoiceVO.supplierInvoiceId
}
trigger={() => (
<Space>
<a>{supplierInvoiceVO.invoiceSn}</a>
</Space>
)}
/>
)
);
},
},
]}
pagination={false}
size="small"
/>
@ -331,59 +276,6 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
<OrderSupplierSelectList
rowKey="orderSupplierId"
dataSource={statistics.proxyInvoiceList}
columns={[
{
title: '开票瓜农',
dataIndex: 'supplierInvoiceVO',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierFarmerList
ghost={true}
mode={'detail'}
supplierId={supplierInvoiceVO.supplierId}
trigger={() => (
<a>{supplierInvoiceVO.supplierName}</a>
)}
/>
)
);
},
},
{
title: '发票编码',
dataIndex: 'supplierInvoiceVO',
key: 'invoiceSn',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierInvoiceList
ghost={true}
mode={'detail'}
supplierInvoiceId={
supplierInvoiceVO.supplierInvoiceId
}
trigger={() => (
<Space>
<a>{supplierInvoiceVO.invoiceSn}</a>
</Space>
)}
/>
)
);
},
},
]}
pagination={false}
size="small"
/>

View File

@ -1,7 +1,6 @@
import { SelectModal } from '@/components';
import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -20,7 +19,7 @@ export interface IPaymentTaskModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.PaymentTaskVO>[];
extraColumns?: ProColumns<BusinessAPI.PaymentTaskVO, BizValueType>[];
}
export default function PaymentTaskModal(props: IPaymentTaskModalProps) {
@ -54,7 +53,7 @@ export default function PaymentTaskModal(props: IPaymentTaskModalProps) {
const intl = useIntl();
const intlPrefix = 'paymentTask';
const columns: ProColumns<BusinessAPI.PaymentTaskVO>[] = [
const columns: ProColumns<BusinessAPI.PaymentTaskVO, BizValueType>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.taskName' }),
dataIndex: 'taskName',
@ -164,10 +163,6 @@ export default function PaymentTaskModal(props: IPaymentTaskModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重,
const selectedRowsMap = new Map<string, BusinessAPI.PaymentTaskVO>();

View File

@ -5,8 +5,6 @@ import {
InsertPosition,
OrderSupplierSelectList,
ProFormUploadMaterial,
SupplierFarmerList,
SupplierInvoiceList,
SupplierSelect,
} from '@/components';
import { business } from '@/services';
@ -23,9 +21,8 @@ import {
RouteContext,
RouteContextType,
} from '@ant-design/pro-components';
import { Col, message, Row, Space, Table } from 'antd';
import { Col, message, Row, Table } from 'antd';
import dayjs from 'dayjs';
import React from 'react';
export interface IPaymentTaskPayProps {
insertPosition?: InsertPosition;
@ -224,58 +221,6 @@ export default function PaymentTaskPay(props: IPaymentTaskPayProps) {
<OrderSupplierSelectList
rowKey="orderSupplierId"
dataSource={orderSupplierVOList || []}
columns={[
{
title: '开票瓜农',
dataIndex: 'supplierInvoiceVO',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierFarmerList
ghost={true}
mode={'detail'}
supplierId={supplierInvoiceVO.supplierId}
trigger={() => (
<a>{supplierInvoiceVO.supplierName}</a>
)}
/>
)
);
},
},
{
title: '发票编码',
dataIndex: 'supplierInvoiceVO',
render: (
_,
orderSupplierVO: BusinessAPI.OrderSupplierVO,
) => {
const supplierInvoiceVO =
orderSupplierVO.supplierInvoiceVO;
return (
supplierInvoiceVO && (
<SupplierInvoiceList
ghost={true}
mode={'detail'}
supplierInvoiceId={
supplierInvoiceVO.supplierInvoiceId
}
trigger={() => (
<Space>
<a>{supplierInvoiceVO.invoiceSn}</a>
</Space>
)}
/>
)
);
},
},
]}
pagination={false}
size="small"
summary={(pageData) => {

View File

@ -1,8 +1,7 @@
import { SelectModal } from '@/components';
import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatCurrency } from '@/utils/format';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -23,7 +22,10 @@ export interface IReconciliationInvoiceModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.ReconciliationInvoiceVO>[];
extraColumns?: ProColumns<
BusinessAPI.ReconciliationInvoiceVO,
BizValueType
>[];
}
export default function ReconciliationInvoiceModal(
@ -58,7 +60,10 @@ export default function ReconciliationInvoiceModal(
const intl = useIntl();
const intlPrefix = 'reconciliationInvoice';
const columns: ProColumns<BusinessAPI.ReconciliationInvoiceVO>[] = [
const columns: ProColumns<
BusinessAPI.ReconciliationInvoiceVO,
BizValueType
>[] = [
{
title: intl.formatMessage({
id: intlPrefix + '.column.invoiceSn',
@ -185,10 +190,6 @@ export default function ReconciliationInvoiceModal(
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重
const selectedRowsMap = new Map<

View File

@ -1,8 +1,7 @@
import { SelectModal } from '@/components';
import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatCurrency } from '@/utils/format';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
@ -22,7 +21,7 @@ export interface IReconciliationModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.ReconciliationVO>[];
extraColumns?: ProColumns<BusinessAPI.ReconciliationVO, BizValueType>[];
}
export default function ReconciliationModal(props: IReconciliationModalProps) {
@ -66,7 +65,7 @@ export default function ReconciliationModal(props: IReconciliationModalProps) {
PAID: '已回款',
};
const columns: ProColumns<BusinessAPI.ReconciliationVO>[] = [
const columns: ProColumns<BusinessAPI.ReconciliationVO, BizValueType>[] = [
{
title: intl.formatMessage({
id: intlPrefix + '.column.reconciliationSn',
@ -186,10 +185,6 @@ export default function ReconciliationModal(props: IReconciliationModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重
const selectedRowsMap = new Map<

View File

@ -14,6 +14,7 @@ import { DownloadOutlined, EyeOutlined } from '@ant-design/icons';
import { ProColumns } from '@ant-design/pro-components';
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import { Image, Modal, Space, Typography } from 'antd';
import dayjs from 'dayjs';
import React, { useState } from 'react';
const { Text } = Typography;
@ -69,21 +70,6 @@ export default function SupplierInvoiceList(props: ISupplierInvoiceListProps) {
dataIndex: 'supplierVO',
key: 'supplierId',
valueType: 'supplier',
render: (_, record) => {
return (
<SupplierFarmerList
key={record.supplierId}
ghost={true}
mode={'detail'}
supplierId={record.supplierId}
trigger={() => (
<Space>
<a>{record.supplierName}</a>
</Space>
)}
/>
);
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceAmount' }),
@ -102,8 +88,8 @@ export default function SupplierInvoiceList(props: ISupplierInvoiceListProps) {
{
title: intl.formatMessage({ id: intlPrefix + '.column.supplier' }),
dataIndex: 'supplier',
key: 'supplier',
search: false,
key: 'orderSupplierId',
valueType: 'supplier',
render: (_, record) => {
return record.orderSupplierInvoiceList?.map((item) => {
return (
@ -125,7 +111,8 @@ export default function SupplierInvoiceList(props: ISupplierInvoiceListProps) {
{
title: intl.formatMessage({ id: intlPrefix + '.column.order' }),
dataIndex: 'order',
search: false,
key: 'orderId',
valueType: 'order',
render: (_, record) => {
return record.orderSupplierInvoiceList?.map((item) => {
return (
@ -152,8 +139,15 @@ export default function SupplierInvoiceList(props: ISupplierInvoiceListProps) {
}),
dataIndex: 'registrationTime',
key: 'registrationTime',
valueType: 'dateTime',
search: false,
valueType: 'dateTimeRange',
render: (_, record) => {
return record.registrationTime
? dayjs(record.registrationTime).format('YYYY-MM-DD HH:mm')
: '';
},
fieldProps: {
placeholder: ['开始时间', '开始时间'],
},
},
];
@ -294,6 +288,15 @@ export default function SupplierInvoiceList(props: ISupplierInvoiceListProps) {
poStates: ['COMPLETED'],
},
},
convertValue: (value) => {
return {
...value,
supplierVO: {
supplierId: value.supplierId,
name: value.supplierName,
},
};
},
columns,
options: (supplierInvoiceVO) => {
return [

View File

@ -1,4 +1,4 @@
import { SelectModal } from '@/components';
import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatBankCard, formatIdCard, formatPhone } from '@/utils/format';
import { formatParam } from '@/utils/formatParam';
@ -23,7 +23,7 @@ export interface ISupplierModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.SupplierVO>[];
extraColumns?: ProColumns<BusinessAPI.SupplierVO, BizValueType>[];
}
export default function SupplierModal(props: ISupplierModalProps) {
@ -63,7 +63,7 @@ export default function SupplierModal(props: ISupplierModalProps) {
const intlPrefix =
props.params?.type === 'FARMER' ? 'supplierFarmer' : 'supplierStall';
const columns: ProColumns<BusinessAPI.SupplierVO>[] = [
const columns: ProColumns<BusinessAPI.SupplierVO, BizValueType>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
dataIndex: 'name',

View File

@ -1,7 +1,6 @@
import { SelectModal, UserList } from '@/components';
import { BizValueType, SelectModal, UserList } from '@/components';
import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import {
ActionType,
LightFilter,
@ -19,7 +18,7 @@ export interface IUserModalProps extends ModalProps {
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.UserVO>[];
extraColumns?: ProColumns<BusinessAPI.UserVO, BizValueType>[];
}
export default function UserModal(props: IUserModalProps) {
@ -50,7 +49,7 @@ export default function UserModal(props: IUserModalProps) {
}
}, [initParams]);
const columns: ProColumns<BusinessAPI.UserVO>[] = [
const columns: ProColumns<BusinessAPI.UserVO, BizValueType>[] = [
{
title: '客户昵称',
dataIndex: 'nickname',
@ -126,10 +125,6 @@ export default function UserModal(props: IUserModalProps) {
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重,
const selectedRowsMap = new Map<string, BusinessAPI.UserVO>();

View File

@ -21,6 +21,7 @@ export { default as LeftMenu } from './LeftMenu';
export * from './Material';
export * from './Menu';
export * from './Modal';
export * from './NotifyMessage';
export { SelectModal, TMapModal } from './Modal';
export * from './Order';
export * from './PaymentRecord';

View File

@ -9,6 +9,16 @@ body {
-ms-overflow-style: none; /* IE and Edge */
}
/* 隐藏整个页面的滚动条 */
html::-webkit-scrollbar {
display: none;
}
/* 或针对所有元素 */
*::-webkit-scrollbar {
display: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none; /* Chrome, Safari, Edge */
@ -81,3 +91,26 @@ body::-webkit-scrollbar {
display: none;
}
}
pre {
/* 基础样式 */
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 6px;
padding: 1rem;
margin: 0 !important;
/* 文本样式 */
font-family: Consolas, Monaco, 'Courier New', monospace;
font-size: 14px;
line-height: 1.5;
color: #333;
/* 滚动和溢出处理 */
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
/* 可选阴影效果 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 5%);
}

View File

@ -2219,6 +2219,13 @@ export default {
invoiceAmount: '应付金额(元)',
depositAmount: '已付定金(元)',
remainingAmount: '剩余金额(元)',
supplierInvoice: '发票信息',
invoiceUpload: '发票上传',
'invoiceUpload.uploaded': '已上传',
'invoiceUpload.notUploaded': '未上传',
contractUpload: '合同上传',
'contractUpload.uploaded': '已上传',
'contractUpload.notUploaded': '未上传',
order: '采购单',
orderCompany: '销售公司',
isPaid: '是否付款',
@ -2673,7 +2680,7 @@ export default {
totalAmount: '付款总金额(元)',
paidAmount: '已付金额(元)',
unpaidAmount: '未付金额(元)',
orderCount: '订单数量',
orderCount: '车数',
state: '付款状态',
'state.enum.pending': '待付款',
'state.enum.partial': '部分付款',
@ -2746,6 +2753,15 @@ export default {
paidCredentials: {
label: '付款凭证',
},
paidAt: {
label: '付款时间',
placeholder: '请选择付款时间',
},
paidAmount: {
label: '付款金额(元)',
placeholder: '请输入付款金额',
required: '付款金额为必填项',
},
},
modal: {
create: {
@ -2834,11 +2850,17 @@ export default {
paidAmount: '付款金额',
paidAt: '支付时间',
paidState: '支付状态',
remark: '备注',
remark: '支付备注',
paidCredentials: '支付凭证',
createdAt: '创建时间',
option: '操作',
},
form: {
remark: {
label: '付款备注',
placeholder: '请输入付款备注',
},
},
tab: {
all: '全部',
draft: '草稿',
@ -3306,4 +3328,111 @@ export default {
},
},
},
notifyMessageTemplate: {
column: {
templateCategory: '模板分类',
templateScene: '触发事件',
titleTemplate: '模板标题',
description: '模板描述',
contentTemplate: '内容模板',
role: '关联角色',
status: '状态',
'status.enum.enabled': '正常',
'status.enum.disabled': '禁用',
'status.placeholder': '请选择状态',
remark: '模板备注',
createdAt: '创建时间',
option: '操作',
},
templateCategory: {
purchaseOrderMessageTemplate: '采购单消息模板',
},
templateScene: {
waitAudit: '待审核',
waitApprove: '待审批',
approvePass: '审批通过',
auditReject: '审核驳回',
approveReject: '审批驳回',
},
form: {
templateCategory: {
label: '模板分类',
placeholder: '请选择模板分类',
required: '请选择模板分类',
},
templateScene: {
label: '触发事件',
placeholder: '请选择触发事件',
required: '请选择触发事件',
},
titleTemplate: {
label: '模板标题',
placeholder: '请输入模板标题',
required: '请输入模板标题',
},
contentTemplate: {
label: '内容模板',
placeholder: '请输入内容模板',
required: '请输入内容模板',
tooltip: '支持变量替换,如:{{车次号}}、{{提交人}}',
insertVariable: '选择变量插入到内容中',
noVariables: '请先在"模板变量"字段中定义变量',
},
description: {
label: '模板描述',
placeholder: '请输入模板描述',
},
variables: {
label: '模板变量',
placeholder: '请输入模板变量,多个变量用逗号分隔',
tooltip: '定义模板中可用的变量名orderId, dealerId',
},
role: {
label: '关联角色',
},
status: {
label: '状态',
placeholder: '请选择状态',
required: '请选择状态',
},
remark: {
label: '模板备注',
placeholder: '请输入模板备注',
},
},
modal: {
create: {
title: '新增消息模板',
button: '新增模板',
success: '新增成功',
},
update: {
title: '编辑消息模板',
button: '编辑',
success: '编辑成功',
},
view: {
title: '查看详情',
button: '详情',
},
delete: {
success: '删除成功',
button: '删除',
confirm: {
title: '确认删除',
content: '您确定要删除该消息模板吗?',
okText: '确定',
cancelText: '取消',
},
},
},
},
notification: {
title: '通知消息',
unreadCount: '{count}条未读',
noMessages: '暂无消息',
viewMore: '查看更多消息',
markReadSuccess: '标记已读成功',
markReadFailed: '标记已读失败',
},
};

View File

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

View File

@ -25,6 +25,8 @@ import * as giftBox from './giftBox';
import * as material from './material';
import * as materialCategory from './materialCategory';
import * as menu from './menu';
import * as messageReceiver from './messageReceiver';
import * as messageTemplate from './messageTemplate';
import * as order from './order';
import * as orderCost from './orderCost';
import * as orderRebate from './orderRebate';
@ -59,6 +61,8 @@ export default {
order,
orderSupplier,
orderShip,
messageTemplate,
messageReceiver,
menu,
material,
materialCategory,

View File

@ -0,0 +1,167 @@
// @ts-ignore
/* eslint-disable */
import request from '../request';
/** 创建消息接收 POST /operation/createMessageReceiver */
export async function createMessageReceiver(
body: BusinessAPI.MessageReceiverCreateCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageReceiverVO>(
'/operation/createMessageReceiver',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}
/** 消息接收删除 DELETE /operation/destroyMessageReceiver */
export async function destroyMessageReceiver(
body: BusinessAPI.MessageReceiverDestroyCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.Response>('/operation/destroyMessageReceiver', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 获取未读消息数量 GET /operation/getUnreadCount */
export async function getUnreadCount(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.getUnreadCountParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseInteger>(
'/operation/getUnreadCount',
{
method: 'GET',
params: {
...params,
messageReceiverUnreadCountQry: undefined,
...params['messageReceiverUnreadCountQry'],
},
...(options || {}),
},
);
}
/** 消息接收列表 GET /operation/listMessageReceiver */
export async function listMessageReceiver(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.listMessageReceiverParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.MultiResponseMessageReceiverVO>(
'/operation/listMessageReceiver',
{
method: 'GET',
params: {
...params,
messageReceiverListQry: undefined,
...params['messageReceiverListQry'],
},
...(options || {}),
},
);
}
/** 标记消息已读 POST /operation/markReadMessageReceiver */
export async function markReadMessageReceiver(
body: BusinessAPI.MessageReceiverMarkReadCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.Response>('/operation/markReadMessageReceiver', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 消息接收列表 GET /operation/pageMessageReceiver */
export async function pageMessageReceiver(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.pageMessageReceiverParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.PageResponseMessageReceiverVO>(
'/operation/pageMessageReceiver',
{
method: 'GET',
params: {
...params,
messageReceiverPageQry: undefined,
...params['messageReceiverPageQry'],
},
...(options || {}),
},
);
}
/** 消息接收详情 GET /operation/showMessageReceiver */
export async function showMessageReceiver(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.showMessageReceiverParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageReceiverVO>(
'/operation/showMessageReceiver',
{
method: 'GET',
params: {
...params,
messageReceiverShowQry: undefined,
...params['messageReceiverShowQry'],
},
...(options || {}),
},
);
}
/** 消息接收更新 PUT /operation/updateMessageReceiver */
export async function updateMessageReceiver(
body: BusinessAPI.MessageReceiverUpdateCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageReceiverVO>(
'/operation/updateMessageReceiver',
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}
/** 消息接收更新 PATCH /operation/updateMessageReceiver */
export async function updateMessageReceiver1(
body: BusinessAPI.MessageReceiverUpdateCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageReceiverVO>(
'/operation/updateMessageReceiver',
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}

View File

@ -0,0 +1,132 @@
// @ts-ignore
/* eslint-disable */
import request from '../request';
/** 创建消息模板 POST /operation/createMessageTemplate */
export async function createMessageTemplate(
body: BusinessAPI.MessageTemplateCreateCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageTemplateVO>(
'/operation/createMessageTemplate',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}
/** 消息模板删除 DELETE /operation/destroyMessageTemplate */
export async function destroyMessageTemplate(
body: BusinessAPI.MessageTemplateDestroyCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.Response>('/operation/destroyMessageTemplate', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 消息模板列表 GET /operation/listMessageTemplate */
export async function listMessageTemplate(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.listMessageTemplateParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.MultiResponseMessageTemplateVO>(
'/operation/listMessageTemplate',
{
method: 'GET',
params: {
...params,
messageTemplateListQry: undefined,
...params['messageTemplateListQry'],
},
...(options || {}),
},
);
}
/** 消息模板列表 GET /operation/pageMessageTemplate */
export async function pageMessageTemplate(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.pageMessageTemplateParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.PageResponseMessageTemplateVO>(
'/operation/pageMessageTemplate',
{
method: 'GET',
params: {
...params,
messageTemplatePageQry: undefined,
...params['messageTemplatePageQry'],
},
...(options || {}),
},
);
}
/** 消息模板详情 GET /operation/showMessageTemplate */
export async function showMessageTemplate(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: BusinessAPI.showMessageTemplateParams,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageTemplateVO>(
'/operation/showMessageTemplate',
{
method: 'GET',
params: {
...params,
messageTemplateShowQry: undefined,
...params['messageTemplateShowQry'],
},
...(options || {}),
},
);
}
/** 消息模板更新 PUT /operation/updateMessageTemplate */
export async function updateMessageTemplate(
body: BusinessAPI.MessageTemplateUpdateCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageTemplateVO>(
'/operation/updateMessageTemplate',
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}
/** 消息模板更新 PATCH /operation/updateMessageTemplate */
export async function updateMessageTemplate1(
body: BusinessAPI.MessageTemplateUpdateCmd,
options?: { [key: string]: any },
) {
return request<BusinessAPI.SingleResponseMessageTemplateVO>(
'/operation/updateMessageTemplate',
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}

View File

@ -2292,6 +2292,10 @@ declare namespace BusinessAPI {
lastVehicleNoQry: LastVehicleNoQry;
};
type getUnreadCountParams = {
messageReceiverUnreadCountQry: MessageReceiverUnreadCountQry;
};
type GiftBoxCreateCmd = {
/** 礼盒ID */
boxId: string;
@ -2469,6 +2473,14 @@ declare namespace BusinessAPI {
menuListQry: MenuListQry;
};
type listMessageReceiverParams = {
messageReceiverListQry: MessageReceiverListQry;
};
type listMessageTemplateParams = {
messageTemplateListQry: MessageTemplateListQry;
};
type listOrderParams = {
orderListQry: OrderListQry;
};
@ -2762,6 +2774,230 @@ declare namespace BusinessAPI {
createdAt?: string;
};
type MessageReceiverCreateCmd = {
/** 消息接收ID */
messageReceiverId: string;
/** 消息ID */
messageId: string;
/** 接收用户ID */
userId: string;
/** 是否已读 */
isRead?: boolean;
/** 已读时间 */
readAt: string;
/** 创建时间 */
createdAt?: string;
};
type MessageReceiverDestroyCmd = {
/** 消息接收ID */
messageReceiverId: string;
};
type MessageReceiverListQry = {
/** 状态1_启用0_禁用 */
status?: boolean;
/** 消息接收ID */
messageReceiverId?: string;
};
type MessageReceiverMarkReadCmd = {
/** 消息接收ID */
messageReceiverId: string;
};
type MessageReceiverPageQry = {
pageSize?: number;
pageIndex?: number;
orderBy?: string;
orderDirection?: string;
groupBy?: string;
needTotalCount?: boolean;
/** 自定义字段key */
customFieldKey?: string;
/** 自定义字段value */
customFieldValue?: string;
/** 备注 */
remark?: string;
/** 状态1_启用0_禁用 */
status?: boolean;
/** 消息接收ID */
messageReceiverId?: string;
offset?: number;
};
type MessageReceiverShowQry = {
/** 状态1_启用0_禁用 */
status?: boolean;
/** 消息接收ID */
messageReceiverId?: string;
};
type MessageReceiverUnreadCountQry = {
/** 管理员ID */
adminId: string;
};
type MessageReceiverUpdateCmd = {
/** 消息接收ID */
messageReceiverId: string;
/** 消息ID */
messageId: string;
/** 接收用户ID */
userId: string;
/** 是否已读 */
isRead?: boolean;
/** 已读时间 */
readAt: string;
/** 创建时间 */
createdAt?: string;
};
type MessageReceiverVO = {
/** 消息接收ID */
messageReceiverId: string;
/** 消息ID */
messageId: string;
/** 接收用户ID */
userId: string;
/** 是否已读 */
isRead?: boolean;
/** 已读时间 */
readAt: string;
/** 创建时间 */
createdAt?: string;
messageVO?: MessageVO;
};
type MessageTemplateCreateCmd = {
/** 模板ID */
messageTemplateId: string;
/** 模板分类1_采购单消息模板 */
templateCategory: 'PURCHASE_ORDER_MESSAGE_TEMPLATE';
/** 触发场景1_待审核2_待审批3_审批通过4_审核驳回5_审批驳回 */
templateScene:
| 'WAIT_AUDIT'
| 'WAIT_APPROVE'
| 'APPROVE_PASS'
| 'AUDIT_REJECT'
| 'APPROVE_REJECT';
/** 模板标题 */
titleTemplate?: string;
/** 内容模板 */
contentTemplate?: string;
/** 模板描述 */
description?: string;
/** 模板变量定义 */
variables?: string;
/** 通知角色 */
roleIds?: string[];
/** 备注 */
remark?: string;
/** 状态1_启用0_禁用 */
status: boolean;
/** 创建时间 */
createdAt?: string;
};
type MessageTemplateDestroyCmd = {
/** 消息模板ID */
messageTemplateId: string;
};
type MessageTemplateListQry = {
/** 状态1_启用0_禁用 */
status?: boolean;
/** 消息模板ID */
messageTemplateId?: string;
};
type MessageTemplatePageQry = {
pageSize?: number;
pageIndex?: number;
orderBy?: string;
orderDirection?: string;
groupBy?: string;
needTotalCount?: boolean;
/** 自定义字段key */
customFieldKey?: string;
/** 自定义字段value */
customFieldValue?: string;
/** 备注 */
remark?: string;
/** 状态1_启用0_禁用 */
status?: boolean;
/** 消息模板ID */
messageTemplateId?: string;
offset?: number;
};
type MessageTemplateShowQry = {
/** 状态1_启用0_禁用 */
status?: boolean;
/** 消息模板ID */
messageTemplateId?: string;
};
type MessageTemplateUpdateCmd = {
/** 消息模板ID */
messageTemplateId: string;
/** 模板分类1_采购单消息模板 */
templateCategory: 'PURCHASE_ORDER_MESSAGE_TEMPLATE';
/** 触发场景1_待审核2_待审批3_审批通过4_审核驳回5_审批驳回 */
templateScene:
| 'WAIT_AUDIT'
| 'WAIT_APPROVE'
| 'APPROVE_PASS'
| 'AUDIT_REJECT'
| 'APPROVE_REJECT';
/** 模板标题 */
titleTemplate?: string;
/** 内容模板 */
contentTemplate?: string;
/** 模板描述 */
description?: string;
/** 模板变量定义 */
variables?: string;
/** 通知角色 */
roleIds?: string[];
/** 备注 */
remark?: string;
/** 状态1_启用0_禁用 */
status: boolean;
/** 创建时间 */
createdAt?: string;
};
type MessageTemplateVO = {
/** 模板ID */
messageTemplateId: string;
/** 模板分类1_采购单消息模板 */
templateCategory: 'PURCHASE_ORDER_MESSAGE_TEMPLATE';
/** 触发场景1_待审核2_待审批3_审批通过4_审核驳回5_审批驳回 */
templateScene:
| 'WAIT_AUDIT'
| 'WAIT_APPROVE'
| 'APPROVE_PASS'
| 'AUDIT_REJECT'
| 'APPROVE_REJECT';
/** 模板标题 */
titleTemplate?: string;
/** 内容模板 */
contentTemplate?: string;
/** 模板描述 */
description?: string;
/** 模板变量定义 */
variables?: string;
/** 通知角色 */
roleIds?: string[];
/** 备注 */
remark?: string;
/** 状态1_启用0_禁用 */
status: boolean;
/** 创建时间 */
createdAt?: string;
};
type MultiResponseAgreementVO = {
success?: boolean;
errCode?: string;
@ -2933,6 +3169,24 @@ declare namespace BusinessAPI {
notEmpty?: boolean;
};
type MultiResponseMessageReceiverVO = {
success?: boolean;
errCode?: string;
errMessage?: string;
data?: MessageReceiverVO[];
empty?: boolean;
notEmpty?: boolean;
};
type MultiResponseMessageTemplateVO = {
success?: boolean;
errCode?: string;
errMessage?: string;
data?: MessageTemplateVO[];
empty?: boolean;
notEmpty?: boolean;
};
type MultiResponseOrderShipVO = {
success?: boolean;
errCode?: string;
@ -4137,12 +4391,14 @@ declare namespace BusinessAPI {
status?: boolean;
/** 订单供应商ID */
orderSupplierId?: string;
/** 名称 */
name?: string;
/** 订单ID */
orderId?: string;
/** 供应商id */
supplierId?: string;
/** 发货日期 */
deliveryTime?: string[];
shippingDate?: string[];
/** 瓜农发票上传 */
invoiceUpload?: boolean;
/** 订单状态 */
@ -4155,6 +4411,8 @@ declare namespace BusinessAPI {
type?: 'FARMER' | 'STALL' | 'OTHER_STALL';
/** 发票ID */
invoiceId?: string;
/** 发票日期 */
invoiceDate?: string[];
offset?: number;
};
@ -4467,6 +4725,14 @@ declare namespace BusinessAPI {
materialPageQry: MaterialPageQry;
};
type pageMessageReceiverParams = {
messageReceiverPageQry: MessageReceiverPageQry;
};
type pageMessageTemplateParams = {
messageTemplatePageQry: MessageTemplatePageQry;
};
type pageOrderCostParams = {
orderCostPageQry: OrderCostPageQry;
};
@ -4766,6 +5032,32 @@ declare namespace BusinessAPI {
totalPages?: number;
};
type PageResponseMessageReceiverVO = {
success?: boolean;
errCode?: string;
errMessage?: string;
totalCount?: number;
pageSize?: number;
pageIndex?: number;
data?: MessageReceiverVO[];
empty?: boolean;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseMessageTemplateVO = {
success?: boolean;
errCode?: string;
errMessage?: string;
totalCount?: number;
pageSize?: number;
pageIndex?: number;
data?: MessageTemplateVO[];
empty?: boolean;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseOrderCostVO = {
success?: boolean;
errCode?: string;
@ -5825,6 +6117,18 @@ declare namespace BusinessAPI {
status?: boolean;
/** 对账付款ID */
reconciliationPaymentId?: string;
/** 经销商ID */
dealerId?: string;
/** 公司ID */
companyId?: string;
/** 账户类型1_银行卡2_支付宝3_微信 */
accountType?: string;
/** 账户类别1_对公账户2_私人账户 */
accountCategory?: string;
/** 开户公司名称/支付宝昵称/微信号 */
accountName?: string;
/** 银行账号/支付宝账号/微信账号 */
accountNumber?: string;
offset?: number;
};
@ -5903,6 +6207,10 @@ declare namespace BusinessAPI {
remark?: string;
/** 创建时间 */
createdAt?: string;
/** 经销商 */
dealerVO?: DealerVO;
/** 公司 */
companyVO?: CompanyVO;
};
type ReconciliationShowQry = {
@ -6280,6 +6588,14 @@ declare namespace BusinessAPI {
menuShowQry: MenuShowQry;
};
type showMessageReceiverParams = {
messageReceiverShowQry: MessageReceiverShowQry;
};
type showMessageTemplateParams = {
messageTemplateShowQry: MessageTemplateShowQry;
};
type showOrderCostParams = {
orderCostShowQry: OrderCostShowQry;
};
@ -6484,6 +6800,13 @@ declare namespace BusinessAPI {
data?: GiftBoxVO;
};
type SingleResponseInteger = {
success?: boolean;
errCode?: string;
errMessage?: string;
data?: number;
};
type SingleResponseLong = {
success?: boolean;
errCode?: string;
@ -6505,6 +6828,20 @@ declare namespace BusinessAPI {
data?: MenuVO;
};
type SingleResponseMessageReceiverVO = {
success?: boolean;
errCode?: string;
errMessage?: string;
data?: MessageReceiverVO;
};
type SingleResponseMessageTemplateVO = {
success?: boolean;
errCode?: string;
errMessage?: string;
data?: MessageTemplateVO;
};
type SingleResponseOrderCostVO = {
success?: boolean;
errCode?: string;
@ -6769,6 +7106,12 @@ declare namespace BusinessAPI {
supplierId?: string;
/** 订单状态 */
poStates?: ('DRAFT' | 'AUDITING' | 'COMPLETED' | 'CLOSED')[];
/** 订单供应商ID */
orderSupplierId?: number;
/** 订单ID */
orderId?: number;
/** 登记时间 */
registrationTime?: string[];
offset?: number;
};
@ -7025,6 +7368,8 @@ declare namespace BusinessAPI {
status?: boolean;
/** 用户ID */
userIdList?: string[];
/** 角色ID */
roleIdList?: string[];
/** 用户名 */
name?: string;
};

File diff suppressed because it is too large Load Diff