Commit 1110969596811032526bf1a1c58167aba3294d11

Authored by 曾国涛
2 parents 78b8312b 16b6a350

Merge branch 'znh' of http://39.108.227.113:8001/zhusen/canrd-erp-front into znh

# Conflicts:
#	src/pages/Order/index.tsx
.umirc.ts
... ... @@ -49,7 +49,7 @@ export default defineConfig({
49 49 path: '/orderReport',
50 50 component: './OrderReport',
51 51 icon: 'LineChartOutlined',
52   - access: 'canReadAdmin',
  52 + access: 'canReadAdminAndFinance',
53 53 },
54 54 {
55 55 name: '发票管理',
... ...
src/app.ts
... ... @@ -6,6 +6,8 @@ import '@inspir/assembly-css/dist/special.css';
6 6 import { message } from 'antd';
7 7 import { RESPONSE_CODE } from './constants/enum';
8 8  
  9 +import { RunTimeLayoutConfig } from '@umijs/max';
  10 +import GlobleHeader from './components/UserHeader';
9 11 import './style/global.css';
10 12 import { getUserInfo } from './utils';
11 13  
... ... @@ -15,19 +17,29 @@ export async function getInitialState() {
15 17 return getUserInfo();
16 18 }
17 19  
18   -export const layout = () => {
  20 +export const layout: RunTimeLayoutConfig = () => {
19 21 return {
20   - menu: {
21   - locale: false,
22   - // header: true,
23   - headerRender: true,
24   - // rightContentRender: () => <RightContent />,
25   - // footerRender: () => <Footer />,
26   - },
27   - collapsed: true,
28   - // breakpoint:false
  22 + headerRender: GlobleHeader,
  23 + siderWidth: '190px',
  24 +
  25 + layout: 'mix',
  26 +
  27 + // 其他属性见:https://procomponents.ant.design/components/layout#prolayout
29 28 };
30 29 };
  30 +// export const layout = () => {
  31 +// return {
  32 +// menu: {
  33 +// locale: false,
  34 +// header: GlobleHeader,
  35 +// headerRender:GlobleHeader,
  36 +// rightContentRender: () => GlobleHeader,
  37 +// // footerRender: () => <Footer />,
  38 +// },
  39 +// // collapsed: true,
  40 +// // breakpoint:false
  41 +// };
  42 +// };
31 43  
32 44 export const request: RequestConfig = {
33 45 // 错误处理
... ...
src/assets/logo/logo.png 0 → 100644

4.17 KB

src/components/UserHeader/index.less 0 → 100644
  1 +@import (reference) '~antd/es/style/themes/index';
  2 +
  3 +@pro-header-hover-bg: rgba(0, 0, 0, 0.025);
  4 +
  5 +.menu {
  6 + :global(.anticon) {
  7 + margin-right: 8px;
  8 + }
  9 +
  10 + :global(.ant-dropdown-menu-item) {
  11 + min-width: 160px;
  12 + }
  13 +}
  14 +
  15 +.right {
  16 + display: flex;
  17 + float: right;
  18 + height: 48px;
  19 + margin-left: auto;
  20 + overflow: hidden;
  21 +
  22 + .action {
  23 + display: flex;
  24 + align-items: center;
  25 + height: 48px;
  26 + padding: 0 12px;
  27 + cursor: pointer;
  28 + transition: all 0.3s;
  29 +
  30 + > span {
  31 + vertical-align: middle;
  32 + }
  33 +
  34 + &:hover {
  35 + background: @pro-header-hover-bg;
  36 + }
  37 +
  38 + &:global(.opened) {
  39 + background: @pro-header-hover-bg;
  40 + }
  41 + }
  42 +
  43 + .search {
  44 + padding: 0 12px;
  45 +
  46 + &:hover {
  47 + background: transparent;
  48 + }
  49 + }
  50 +
  51 + .account {
  52 + .avatar {
  53 + margin-right: 8px;
  54 + color: @primary-color;
  55 + vertical-align: top;
  56 + background: rgba(255, 255, 255, 85%);
  57 + }
  58 + }
  59 +}
  60 +
  61 +.dark {
  62 + .action {
  63 + &:hover {
  64 + background: #252a3d;
  65 + }
  66 +
  67 + &:global(.opened) {
  68 + background: #252a3d;
  69 + }
  70 + }
  71 +}
  72 +
  73 +@media only screen and (max-width: @screen-md) {
  74 + :global(.ant-divider-vertical) {
  75 + vertical-align: unset;
  76 + }
  77 +
  78 + .name {
  79 + display: none;
  80 + }
  81 +
  82 + .right {
  83 + position: absolute;
  84 + top: 0;
  85 + right: 12px;
  86 +
  87 + .account {
  88 + .avatar {
  89 + margin-right: 0;
  90 + }
  91 + }
  92 +
  93 + .search {
  94 + display: none;
  95 + }
  96 + }
  97 +}
... ...
src/components/UserHeader/index.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import MessageListDrawer from '@/pages/Order/components/MessageListDrawer';
  3 +import { postOrderErpMessageGetUnreadNum } from '@/services';
  4 +import { getUserInfo } from '@/utils';
  5 +import { BellOutlined, EllipsisOutlined } from '@ant-design/icons';
  6 +import { history } from '@umijs/max';
  7 +import { Avatar, Badge, Button, Dropdown, Space, Tag } from 'antd';
  8 +import { useEffect, useState } from 'react';
  9 +
  10 +const userInfo = getUserInfo();
  11 +
  12 +const GlobleHeader = () => {
  13 + const [unreadMsgNum, setUnreadMsgNum] = useState(0);
  14 + const [messageListDrawerVisible, setMessageListDrawerVisible] =
  15 + useState<boolean>(false);
  16 + /**
  17 + * 打开消息弹窗
  18 + */
  19 + function openMessageDrawer() {
  20 + setMessageListDrawerVisible(true);
  21 + }
  22 +
  23 + /**
  24 + * 获取当前用户未读消息条数
  25 + */
  26 + async function getUnreadMessageNum() {
  27 + let res = await postOrderErpMessageGetUnreadNum();
  28 + if (res && res.result === RESPONSE_CODE.SUCCESS) {
  29 + setUnreadMsgNum(res.data);
  30 + }
  31 + }
  32 +
  33 + useEffect(() => {
  34 + //未读消息条数
  35 + getUnreadMessageNum();
  36 + }, []);
  37 + return (
  38 + <>
  39 + <Space className="flex flex-row items-center justify-between ml-4 mr-4">
  40 + {/* left extra start */}
  41 + <Space className="flex flex-row items-center">
  42 + <Avatar
  43 + size="large"
  44 + src={<img src={require('@/assets/logo/logo.png')} alt="canrd" />}
  45 + />
  46 + <span className="text-lg font-semibold">订单管理系统</span>
  47 + </Space>
  48 + {/* left extra end */}
  49 +
  50 + {/* right extra start */}
  51 + <Space>
  52 + <Badge
  53 + key="message"
  54 + count={unreadMsgNum}
  55 + className="hover:cursor-pointer top-1"
  56 + >
  57 + <BellOutlined
  58 + style={{ fontSize: '24px' }}
  59 + onClick={openMessageDrawer}
  60 + />
  61 + </Badge>
  62 + <Avatar
  63 + key="0"
  64 + style={{ verticalAlign: 'middle', marginLeft: '10px' }}
  65 + size="large"
  66 + >
  67 + {userInfo?.roleSmallVO?.name}
  68 + </Avatar>
  69 + <Tag key="nickName">{userInfo?.username}</Tag>
  70 + <Dropdown
  71 + key="dropdown"
  72 + trigger={['click']}
  73 + menu={{
  74 + items: [
  75 + {
  76 + label: '退出登录',
  77 + key: '1',
  78 + onClick: () => {
  79 + localStorage.removeItem('token');
  80 + history.push('/login');
  81 + },
  82 + },
  83 + // {
  84 + // label: '修改密码',
  85 + // key: '2',
  86 + // },
  87 + ],
  88 + }}
  89 + >
  90 + <Button key="4" style={{ padding: '0 8px' }}>
  91 + <EllipsisOutlined />
  92 + </Button>
  93 + </Dropdown>
  94 + </Space>
  95 + {/* right extra end */}
  96 + </Space>
  97 +
  98 + {messageListDrawerVisible && (
  99 + <MessageListDrawer
  100 + setVisible={(val: any) => {
  101 + setMessageListDrawerVisible(val);
  102 + getUnreadMessageNum();
  103 + }}
  104 + />
  105 + )}
  106 + </>
  107 + );
  108 +};
  109 +
  110 +export default GlobleHeader;
... ...
src/pages/Invoice/index.tsx
... ... @@ -15,15 +15,9 @@ import {
15 15 } from '@/services';
16 16 import { enumValueToLabel, formatDateTime } from '@/utils';
17 17 import { formatDate } from '@/utils/time';
18   -import { getUserInfo } from '@/utils/user';
19   -import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
20   -import {
21   - ActionType,
22   - PageContainer,
23   - ProTable,
24   -} from '@ant-design/pro-components';
25   -import { history } from '@umijs/max';
26   -import { Avatar, Button, Dropdown, Tabs, Tag, message } from 'antd';
  18 +import { PlusOutlined } from '@ant-design/icons';
  19 +import { ActionType, ProTable } from '@ant-design/pro-components';
  20 +import { Button, Tabs, message } from 'antd';
27 21 import { useRef, useState } from 'react';
28 22 import { INVOCING_STATUS, PAYEE_OPTIONS } from '../Order/constant';
29 23 import BankImportModal from './components/BankImportModal';
... ... @@ -37,8 +31,6 @@ const InvoicePage = () =&gt; {
37 31 useState(false);
38 32 const [invoiceId, setInvoiceId] = useState(undefined);
39 33  
40   - const userInfo = getUserInfo();
41   -
42 34 const reloadInvoiceTable = () => {
43 35 invoiceActionRef.current?.reload();
44 36 };
... ... @@ -420,55 +412,18 @@ const InvoicePage = () =&gt; {
420 412 },
421 413 ];
422 414 return (
423   - <>
424   - <PageContainer
425   - className="invoice-index"
426   - header={{
427   - title: '发票管理',
428   - extra: [
429   - <Avatar key="0" style={{ verticalAlign: 'middle' }} size="large">
430   - {userInfo?.username}
431   - </Avatar>,
432   - <Tag key="nickName">{userInfo?.nickName}</Tag>,
433   - <Dropdown
434   - key="dropdown"
435   - trigger={['click']}
436   - menu={{
437   - items: [
438   - {
439   - label: '退出登录',
440   - key: '1',
441   - onClick: () => {
442   - localStorage.removeItem('token');
443   - history.push('/login');
444   - },
445   - },
446   - // {
447   - // label: '修改密码',
448   - // key: '2',
449   - // },
450   - ],
451   - }}
452   - >
453   - <Button key="4" style={{ padding: '0 8px' }}>
454   - <EllipsisOutlined />
455   - </Button>
456   - </Dropdown>,
457   - ],
  415 + <div className="invoice-index">
  416 + <Tabs
  417 + defaultActiveKey="1"
  418 + items={tabsItems}
  419 + onChange={(value) => {
  420 + if (value === 1) {
  421 + invoiceActionRef.current?.reload();
  422 + } else {
  423 + bankActionRef.current?.reload();
  424 + }
458 425 }}
459   - >
460   - <Tabs
461   - defaultActiveKey="1"
462   - items={tabsItems}
463   - onChange={(value) => {
464   - if (value === 1) {
465   - invoiceActionRef.current?.reload();
466   - } else {
467   - bankActionRef.current?.reload();
468   - }
469   - }}
470   - />
471   - </PageContainer>
  426 + />
472 427  
473 428 {bankImportModalVisible ? (
474 429 <BankImportModal
... ... @@ -495,7 +450,7 @@ const InvoicePage = () =&gt; {
495 450 ) : (
496 451 ''
497 452 )}
498   - </>
  453 + </div>
499 454 );
500 455 };
501 456  
... ...
src/pages/Order/components/ApplyForInvoicingModal.tsx
... ... @@ -3,7 +3,6 @@ import { postServiceOrderApplyInvoicing } from &#39;@/services&#39;;
3 3 import { enumToSelect, getAliYunOSSFileNameFromUrl } from '@/utils';
4 4 import {
5 5 ModalForm,
6   - ProFormDatePicker,
7 6 ProFormSelect,
8 7 ProFormTextArea,
9 8 ProFormUploadDragger,
... ... @@ -172,13 +171,13 @@ export default ({
172 171 }}
173 172 />
174 173  
175   - <ProFormDatePicker
  174 + {/* <ProFormDatePicker
176 175 key="deadline"
177 176 label="期望开票时间"
178 177 name="deadline"
179 178 rules={[{ required: isUrgent === 'true', message: '期望开票时间必填' }]}
180 179 hidden={isUrgent !== 'true'}
181   - />
  180 + /> */}
182 181  
183 182 <ProFormTextArea
184 183 key="invoicingUrgentCause"
... ...
src/pages/Order/components/OrderDrawer.tsx
... ... @@ -1388,7 +1388,6 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1388 1388 name="parameters"
1389 1389 label="商品参数"
1390 1390 placeholder="请输入商品参数"
1391   - rules={[{ required: true, message: '商品参数必填' }]}
1392 1391 disabled={
1393 1392 productParametersDisabledFlagList[listMeta.index] !==
1394 1393 false || optType('after-sales-check')
... ...
src/pages/Order/components/ProcureConvertModal.tsx
... ... @@ -44,7 +44,7 @@ export default ({ setVisible, subOrders, onClose }) =&gt; {
44 44 submitTimeout={2000}
45 45 onFinish={async (values) => {
46 46 let data;
47   - if (values.procureName === 'warehouseKeeper') {
  47 + if (values.procureName === '仓库') {
48 48 //转给仓库
49 49 data = await postServiceOrderProcureConvertWarehouseKeeper({
50 50 data: {
... ... @@ -82,7 +82,6 @@ export default ({ setVisible, subOrders, onClose }) =&gt; {
82 82 let options = res.data?.map((item) => {
83 83 return { label: item, value: item };
84 84 });
85   - options.push({ label: '仓库', value: 'warehouseKeeper' });
86 85 return options;
87 86 }}
88 87 />
... ...
src/pages/Order/constant.ts
1 1 import { postServiceOrderQueryCustomerInformation } from '@/services';
2   -import { enumToProTableEnumValue, getUserInfo } from '@/utils';
  2 +import { enumToProTableEnumValue } from '@/utils';
3 3 import { getReceivingCompanyOptions, isSupplier } from '@/utils/order';
4 4 export const COMFIR_RECEIPT_IMAGES_NUMBER = 3;
5 5  
... ... @@ -7,6 +7,7 @@ export const PAYMENT_CHANNEL_OPTIONS = {
7 7 ALIPAY: '支付宝',
8 8 WECHAT: '微信',
9 9 BANK_TRANSFER: '银行转账',
  10 + BALANCE: '预存款',
10 11 };
11 12  
12 13 export const RECEIPTS_RECORD_TYPES = {
... ... @@ -25,7 +26,7 @@ export const PAYMENT_METHOD_OPTIONS = {
25 26 PLATFORM_SETTLEMENT: '平台结算',
26 27 CASH_ON_DELIVERY: '货到付款',
27 28 HIRE_PURCHASE: '分期付款',
28   - PAYMENT_RECEIPT:'已回款'
  29 + PAYMENT_RECEIPT: '已回款',
29 30 };
30 31  
31 32 export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = {
... ... @@ -153,7 +154,7 @@ export const POST_AUDIT_OPTIONS = {
153 154 export const PAYMENT_RECEIPTS_STATUS_OPTIONS = {
154 155 WAIT_AUDIT: '回款待审核',
155 156 AUDIT_PASS: '回款已审核',
156   - AUDIT_NOTPASS: '回款审核失败'
  157 + AUDIT_NOTPASS: '回款审核失败',
157 158 };
158 159  
159 160 export const ORDER_STATUS_OPTIONS = {
... ... @@ -190,8 +191,8 @@ export const MODIFIED_AUDIT_STATUS_OPTIONS = {
190 191 * 采购筛选订单的主要订单状态
191 192 */
192 193 export const PROCURE_PRIMARY_ORDER_STATUS_OPTIONS = {
193   - PROCURE_UN_PROCESS: isSupplier()?'未审核':'采购未审核',
194   - PROCURE_WAIT_SHIP: isSupplier()?'待发货':'采购待发货',
  194 + PROCURE_UN_PROCESS: isSupplier() ? '未审核' : '采购未审核',
  195 + PROCURE_WAIT_SHIP: isSupplier() ? '待发货' : '采购待发货',
195 196 SHIPPED: '已发货',
196 197 };
197 198  
... ... @@ -253,10 +254,10 @@ export const TAGS_COLOR = new Map&lt;string, string&gt;([
253 254 ['PARTIAL_INVOICING', 'processing'],
254 255 ['URGENT_INVOICE_AUDITING', 'warning'],
255 256 ['APPLY_FOR_INVOICING', 'processing'],
256   - ['AUDIT_FAILURE','error'],
257   - ['WAIT_AUDIT','warning'],
258   - ['AUDIT_PASS','success'],
259   - ['AUDIT_NOTPASS','error']
  257 + ['AUDIT_FAILURE', 'error'],
  258 + ['WAIT_AUDIT', 'warning'],
  259 + ['AUDIT_PASS', 'success'],
  260 + ['AUDIT_NOTPASS', 'error'],
260 261 ]);
261 262 export const SALES_CODE_OPTIONS = [
262 263 { label: 'D-Linda', value: 'D-Linda' },
... ... @@ -380,6 +381,7 @@ export const HISTORY_OPT_TYPE = new Map&lt;string, string&gt;([
380 381 ['warehouse_audit', '仓库审核'],
381 382 ['post_audit', '后置审核'],
382 383 ['applyModify', '申请修改订单信息'],
  384 + ['OUTSIDE_SYSTEM_PUSH', '外部系统推送了本订单'],
383 385 ]);
384 386  
385 387 export const MAIN_ORDER_COLUMNS = [
... ...
src/pages/Order/index.tsx
... ... @@ -3,7 +3,6 @@ import { RESPONSE_CODE } from &#39;@/constants/enum&#39;;
3 3 import {
4 4 postKingdeeRepSalBillOutbound,
5 5 postKingdeeRepSalOrderSave,
6   - postOrderErpMessageGetUnreadNum,
7 6 postServiceOrderCancelSend,
8 7 postServiceOrderNoNeedSend,
9 8 postServiceOrderOrderCancel,
... ... @@ -24,35 +23,34 @@ import {
24 23 getAliYunOSSFileNameFromUrl,
25 24 isImageName,
26 25 } from '@/utils';
27   -import { getReceivingCompanyOptions, isSupplier } from '@/utils/order';
  26 +import {
  27 + getReceivingCompanyOptions,
  28 + isExaminer,
  29 + isSupplier,
  30 +} from '@/utils/order';
28 31 import { getUserInfo } from '@/utils/user';
29 32 import {
30   - BellOutlined,
31 33 ClockCircleTwoTone,
32 34 ContainerTwoTone,
33 35 CopyOutlined,
34 36 CopyTwoTone,
35 37 DownOutlined,
36 38 EditTwoTone,
37   - EllipsisOutlined,
38 39 QuestionCircleOutlined,
39 40 } from '@ant-design/icons';
40 41 import {
41 42 ActionType,
42   - PageContainer,
43 43 ProColumns,
44 44 ProFormInstance,
45 45 ProTable,
46 46 } from '@ant-design/pro-components';
47   -import { history } from '@umijs/max';
48 47 import {
49   - Avatar,
50   - Badge,
51 48 Button,
52 49 Checkbox,
53 50 Divider,
54 51 Dropdown,
55 52 Flex,
  53 + FloatButton,
56 54 Image,
57 55 MenuProps,
58 56 Modal,
... ... @@ -81,7 +79,6 @@ import FinancialReceiptsModal from &#39;./components/FinancialReceiptsModal&#39;;
81 79 import HistoryModal from './components/HistoryModal';
82 80 import ImagesViewerModal from './components/ImagesViewerModal';
83 81 import ImportModal from './components/ImportModal';
84   -import MessageListDrawer from './components/MessageListDrawer';
85 82 import ModifiedDiffModal from './components/ModifiedDiffModal';
86 83 import OrderDrawer from './components/OrderDrawer';
87 84 import OrderNotesEditModal from './components/OrderNotesEditModal';
... ... @@ -152,8 +149,6 @@ const OrderPage = () =&gt; {
152 149 useState<boolean>(false);
153 150 const [productionTimeModalVisible, setProductionTimeModalVisible] =
154 151 useState<boolean>(false);
155   - const [messageListDrawerVisible, setMessageListDrawerVisible] =
156   - useState<boolean>(false);
157 152 const [deliverVisible, setDeliverVisible] = useState<boolean>(false);
158 153 const [deliverInfoDrawerVisible, setDeliverInfoDrawerVisible] =
159 154 useState<boolean>(false);
... ... @@ -179,7 +174,6 @@ const OrderPage = () =&gt; {
179 174 const [currentOptMainId, setCurrentMainId] = useState<any>(undefined); //当前操作对象的主订单id
180 175 const [curretnOptSubId, setCurretnOptSubId] = useState<any>(undefined); //当前操作对象的子订单id
181 176 const [subOrderCount, setSubOrderCount] = useState(0);
182   - const [unreadMsgNum, setUnreadMsgNum] = useState(0);
183 177 const [sorted, setSorted] = useState(false);
184 178 const mainTableRef = useRef<ActionType>();
185 179 const mainTableFormRef = useRef<ProFormInstance>();
... ... @@ -278,13 +272,6 @@ const OrderPage = () =&gt; {
278 272 }
279 273  
280 274 /**
281   - * 打开消息弹窗
282   - */
283   - function openMessageDrawer() {
284   - setMessageListDrawerVisible(true);
285   - }
286   -
287   - /**
288 275 * 财务是否选中排序
289 276 * @param e
290 277 */
... ... @@ -1260,8 +1247,9 @@ const OrderPage = () =&gt; {
1260 1247 optRecord.orderStatus === 'SHIPPED' ? (
1261 1248 <MyToolTip
1262 1249 title={
1263   - optRecord.serialNumber
1264   - ? enumValueToLabel(
  1250 + optRecord.serialNumber === undefined
  1251 + ? '暂无物流信息'
  1252 + : enumValueToLabel(
1265 1253 optRecord.logisticsMethod,
1266 1254 LOGISTICS_STATUS_OPTIONS,
1267 1255 ) +
... ... @@ -1269,9 +1257,6 @@ const OrderPage = () =&gt; {
1269 1257 optRecord.serialNumber +
1270 1258 ' ' +
1271 1259 optRecord.logisticsNotes
1272   - : optRecord.deliverType
1273   - ? '自行派送'
1274   - : '暂无物流信息'
1275 1260 }
1276 1261 content={
1277 1262 <Button type="link" size="small" style={{ padding: 0 }}>
... ... @@ -2209,36 +2194,42 @@ const OrderPage = () =&gt; {
2209 2194 ) : (
2210 2195 ''
2211 2196 )}
2212   - <span
2213   - className="hover:cursor-pointer"
2214   - onClick={() => {
2215   - copyToClipboard(record.customerName);
2216   - message.info('收货人复制成功:' + record.customerName);
2217   - }}
  2197 + <div
  2198 + title={record.institution}
  2199 + className="whitespace-no-wrap overflow-hidden overflow-ellipsis max-w-[150px]"
2218 2200 >
2219   - <span className="text-[#8C8C8C]">收货人:</span>
2220   - <span className="text-slate-700">
2221   - {record.customerName + ' '}
2222   -
2223   - {!isSupplier() ? (
2224   - <Tooltip className="order-tooltip" title="详情">
2225   - <ContainerTwoTone
2226   - className="hover:curcor-pointer"
2227   - onClick={() => {
2228   - createOptObject(null, record.id);
2229   - setDeliverInfoDrawerVisible(true);
2230   - }}
2231   - />
2232   - </Tooltip>
2233   - ) : (
2234   - ''
2235   - )}
  2201 + <span
  2202 + className="hover:cursor-pointer"
  2203 + onClick={() => {
  2204 + copyToClipboard(record.customerName);
  2205 + message.info('收货人复制成功:' + record.customerName);
  2206 + }}
  2207 + >
  2208 + <span className="text-[#8C8C8C]">收货人:</span>
  2209 + <span className="text-slate-700">
  2210 + {record.customerName + ' '}
  2211 +
  2212 + {!isSupplier() ? (
  2213 + <Tooltip className="order-tooltip" title="详情">
  2214 + <ContainerTwoTone
  2215 + className="hover:curcor-pointer"
  2216 + onClick={() => {
  2217 + createOptObject(null, record.id);
  2218 + setDeliverInfoDrawerVisible(true);
  2219 + }}
  2220 + />
  2221 + </Tooltip>
  2222 + ) : (
  2223 + ''
  2224 + )}
  2225 + </span>
2236 2226 </span>
2237   - </span>
  2227 + </div>
  2228 +
2238 2229 {isSupplier() ? (
2239 2230 <div
2240 2231 title={record.customerShippingAddress}
2241   - className="whitespace-no-wrap overflow-hidden overflow-ellipsis max-w-[500px] hover:cursor-pointer"
  2232 + className="whitespace-no-wrap overflow-hidden overflow-ellipsis max-w-[400px] hover:cursor-pointer"
2242 2233 onClick={() => {
2243 2234 copyToClipboard(record.customerShippingAddress);
2244 2235 message.info(
... ... @@ -3498,10 +3489,31 @@ const OrderPage = () =&gt; {
3498 3489 const mainOrdersColumns: ProColumns<OrderType>[] = MAIN_ORDER_COLUMNS.map(
3499 3490 (item) => {
3500 3491 //首能账号只能搜索订单编号
3501   - let canSearchIndex = ['id', 'salesCode', 'subNotes', 'orderStatus'];
  3492 + let canSearchIndex = [
  3493 + 'id',
  3494 + 'salesCode',
  3495 + 'subNotes',
  3496 + 'orderStatus',
  3497 + 'createTime',
  3498 + ];
3502 3499 if (isSupplier() && !canSearchIndex.includes(item.dataIndex)) {
3503 3500 item.search = false;
3504 3501 }
  3502 +
  3503 + canSearchIndex = [
  3504 + 'id',
  3505 + 'salesCode',
  3506 + 'customerName',
  3507 + 'institution',
  3508 + 'productName',
  3509 + 'orderStatus',
  3510 + 'createTime',
  3511 + ];
  3512 +
  3513 + if (isExaminer() && !canSearchIndex.includes(item.dataIndex)) {
  3514 + item.search = false;
  3515 + }
  3516 +
3505 3517 if (item.dataIndex === 'name') {
3506 3518 return {
3507 3519 ...item,
... ... @@ -3719,6 +3731,15 @@ const OrderPage = () =&gt; {
3719 3731 setOrderCheckType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT);
3720 3732 },
3721 3733 },
  3734 + {
  3735 + label: '加急开票审核',
  3736 + key: '4',
  3737 + onClick: async () => {
  3738 + setIsMainOrder(true);
  3739 + setCheckVisible(true);
  3740 + setOrderCheckType(CHECK_TYPE.URGENT_INVOICE_AUDITING);
  3741 + },
  3742 + },
3722 3743 ];
3723 3744  
3724 3745 const auditProps = {
... ... @@ -3891,16 +3912,6 @@ const OrderPage = () =&gt; {
3891 3912 return toolBtns;
3892 3913 }
3893 3914  
3894   - /**
3895   - * 获取当前用户未读消息条数
3896   - */
3897   - async function getUnreadMessageNum() {
3898   - let res = await postOrderErpMessageGetUnreadNum();
3899   - if (res && res.result === RESPONSE_CODE.SUCCESS) {
3900   - setUnreadMsgNum(res.data);
3901   - }
3902   - }
3903   -
3904 3915 useEffect(() => {
3905 3916 // 使用URLSearchParams来解析查询参数
3906 3917 const params = new URLSearchParams(location.search);
... ... @@ -3908,62 +3919,10 @@ const OrderPage = () =&gt; {
3908 3919 if (id) {
3909 3920 mainTableFormRef.current?.setFieldValue('id', id);
3910 3921 }
3911   -
3912   - //未读消息条数
3913   - getUnreadMessageNum();
3914 3922 }, []);
3915 3923  
3916 3924 return (
3917   - <PageContainer
3918   - className="order-page-container"
3919   - header={{
3920   - title: '订单管理',
3921   - extra: [
3922   - <Badge
3923   - key="message"
3924   - count={unreadMsgNum}
3925   - className="hover:cursor-pointer"
3926   - >
3927   - <BellOutlined
3928   - style={{ fontSize: '24px' }}
3929   - onClick={openMessageDrawer}
3930   - />
3931   - </Badge>,
3932   - <Avatar
3933   - key="0"
3934   - style={{ verticalAlign: 'middle', marginLeft: '10px' }}
3935   - size="large"
3936   - >
3937   - {userInfo?.username}
3938   - </Avatar>,
3939   - <Tag key="nickName">{userInfo?.nickName}</Tag>,
3940   - <Dropdown
3941   - key="dropdown"
3942   - trigger={['click']}
3943   - menu={{
3944   - items: [
3945   - {
3946   - label: '退出登录',
3947   - key: '1',
3948   - onClick: () => {
3949   - localStorage.removeItem('token');
3950   - history.push('/login');
3951   - },
3952   - },
3953   - // {
3954   - // label: '修改密码',
3955   - // key: '2',
3956   - // },
3957   - ],
3958   - }}
3959   - >
3960   - <Button key="4" style={{ padding: '0 8px' }}>
3961   - <EllipsisOutlined />
3962   - </Button>
3963   - </Dropdown>,
3964   - ],
3965   - }}
3966   - >
  3925 + <div className="order-page-container">
3967 3926 <div id="resizeDiv"></div>
3968 3927 <ProTable
3969 3928 id="main-table"
... ... @@ -4504,16 +4463,9 @@ const OrderPage = () =&gt; {
4504 4463 />
4505 4464 )}
4506 4465  
4507   - {messageListDrawerVisible && (
4508   - <MessageListDrawer
4509   - setVisible={(val: any) => {
4510   - setMessageListDrawerVisible(val);
4511   - getUnreadMessageNum();
4512   - }}
4513   - />
4514   - )}
4515 4466 {contextHolder}
4516   - </PageContainer>
  4467 + <FloatButton.BackTop visibilityHeight={0} />
  4468 + </div>
4517 4469 );
4518 4470 };
4519 4471  
... ...
src/pages/OrderReport/index.tsx
... ... @@ -3,33 +3,19 @@ import {
3 3 postServiceOrderQuerySalesCode,
4 4 } from '@/services';
5 5 import { enumToSelect } from '@/utils';
6   -import { getUserInfo } from '@/utils/user';
7   -import { EllipsisOutlined } from '@ant-design/icons';
8 6 import {
9   - PageContainer,
10 7 ProCard,
11 8 ProFormCheckbox,
12 9 ProFormDigit,
13 10 ProFormSelect,
14 11 QueryFilter,
15 12 } from '@ant-design/pro-components';
16   -import {
17   - Avatar,
18   - Button,
19   - Dropdown,
20   - Form,
21   - Segmented,
22   - Space,
23   - Spin,
24   - Tag,
25   -} from 'antd';
  13 +import { Form, Segmented, Space, Spin } from 'antd';
26 14 import { useEffect, useState } from 'react';
27 15 import { PRODUCT_BELONG_DEPARTMENT_OPTIONS } from '../Order/constant';
28 16 import OrderDualAxes from './components/OrderDualAxes';
29 17 import OrderStatisticCard from './components/OrderStatisticCard';
30 18 import './index.less';
31   -const userInfo = getUserInfo();
32   -
33 19 const OrderReportPage = () => {
34 20 const [salesCodeOptions, setSalesCodeOptions] = useState([]);
35 21  
... ... @@ -124,41 +110,7 @@ const OrderReportPage = () =&gt; {
124 110 // },
125 111 // ];
126 112 return (
127   - <PageContainer
128   - header={{
129   - title: '订单汇总',
130   - extra: [
131   - <Avatar key="0" style={{ verticalAlign: 'middle' }} size="large">
132   - {userInfo?.username}
133   - </Avatar>,
134   - <Tag key="nickName">{userInfo?.nickName}</Tag>,
135   - <Dropdown
136   - key="dropdown"
137   - trigger={['click']}
138   - menu={{
139   - items: [
140   - {
141   - label: '退出登录',
142   - key: '1',
143   - onClick: () => {
144   - localStorage.removeItem('token');
145   - history.push('/login');
146   - },
147   - },
148   - // {
149   - // label: '修改密码',
150   - // key: '2',
151   - // },
152   - ],
153   - }}
154   - >
155   - <Button key="4" style={{ padding: '0 8px' }}>
156   - <EllipsisOutlined />
157   - </Button>
158   - </Dropdown>,
159   - ],
160   - }}
161   - >
  113 + <div>
162 114 <Space direction="vertical" size="middle" className="flex">
163 115 <Spin spinning={loading}>
164 116 <OrderStatisticCard
... ... @@ -235,7 +187,7 @@ const OrderReportPage = () =&gt; {
235 187 </Spin>
236 188 </ProCard>
237 189 </Space>
238   - </PageContainer>
  190 + </div>
239 191 );
240 192 };
241 193  
... ...
src/pages/Prepaid/index.tsx 0 → 100644
  1 +import ButtonConfirm from '@/components/ButtomConfirm';
  2 +import EllipsisDiv from '@/components/Div/EllipsisDiv';
  3 +import { RESPONSE_CODE } from '@/constants/enum';
  4 +import {} from '@/pages/Invoice/constant';
  5 +import {
  6 + postCanrdApiUserList,
  7 + postPrepaidDelete,
  8 + postPrepaidList,
  9 +} from '@/services';
  10 +import { enumValueToLabel, formatDateTime } from '@/utils';
  11 +import { PlusOutlined } from '@ant-design/icons';
  12 +import { ActionType, ProTable } from '@ant-design/pro-components';
  13 +import { Button, Divider, Image, Tabs, message } from 'antd';
  14 +import { cloneDeep } from 'lodash';
  15 +import React, { useRef, useState } from 'react';
  16 +import CheckModal from '../Order/components/CheckModal';
  17 +import { CHECK_TYPE } from '../Order/constant';
  18 +import BalanceChangeRecordsModal from './components/BalanceChangeRecordsModal';
  19 +import RechargePrepaymentModal from './components/RechargePrepaymentModal';
  20 +import {
  21 + ACCOUNT_COLUMNS,
  22 + PREPAID_STATUS_OPTIONS,
  23 + SALES_RECHARGE_PREPAYMENT_COLUMNS,
  24 +} from './constant';
  25 +import './index.less';
  26 +const PrepaidPage = () => {
  27 + const prepaidActionRef = useRef<ActionType>();
  28 + const accountActionRef = useRef<ActionType>();
  29 + const [rechargePrepaymentModalVisible, setRechargePrepaymentModalVisible] =
  30 + useState(false);
  31 + const [currentOptPrepaymentObj, setCurrentOptPrepaymentObj] = useState(null);
  32 + const [currentOptUserObj, setCurrentOptUserObj] = useState(null);
  33 + const [checkVisible, setCheckVisible] = useState(false);
  34 + const [
  35 + balanceChangeRecordsModalVisible,
  36 + setBalanceChangeRecordsModalVisible,
  37 + ] = useState(false);
  38 +
  39 + const reloadPrepaidTable = () => {
  40 + prepaidActionRef.current?.reload();
  41 + };
  42 +
  43 + const reloadAccountTable = () => {
  44 + accountActionRef.current?.reload();
  45 + };
  46 +
  47 + const getTableCellText = (target: any) => {
  48 + if (!target) {
  49 + return '';
  50 + }
  51 +
  52 + if (target.props) {
  53 + return target.props.text;
  54 + }
  55 +
  56 + return target;
  57 + };
  58 +
  59 + /**
  60 + * 加载发票列表表格的各个列格式
  61 + */
  62 + const prepaidColumnsInit = () => {
  63 + let columns = SALES_RECHARGE_PREPAYMENT_COLUMNS.map((item) => {
  64 + let newItem = { ...item };
  65 + let dataIndex = item.dataIndex;
  66 +
  67 + newItem.render = (text, record) => {
  68 + let textValue = record[dataIndex];
  69 +
  70 + if (dataIndex === 'status') {
  71 + textValue = enumValueToLabel(textValue, PREPAID_STATUS_OPTIONS);
  72 + }
  73 +
  74 + if (dataIndex.endsWith('Time')) {
  75 + textValue = formatDateTime(textValue);
  76 + }
  77 +
  78 + if (
  79 + dataIndex === 'proofImages' &&
  80 + textValue !== null &&
  81 + textValue !== undefined
  82 + ) {
  83 + console.log(textValue);
  84 + return (
  85 + <Image.PreviewGroup
  86 + className="mr-10"
  87 + preview={{
  88 + onChange: (current, prev) =>
  89 + console.log(`current index: ${current}, prev index: ${prev}`),
  90 + }}
  91 + >
  92 + {textValue.map((item, index) => (
  93 + <React.Fragment key={index}>
  94 + {index > 0 ? <Divider type="vertical" /> : ''}
  95 + <Image
  96 + className="max-h-[35px] max-w-[45px]"
  97 + src={item}
  98 + title={item}
  99 + />{' '}
  100 + </React.Fragment>
  101 + ))}
  102 + </Image.PreviewGroup>
  103 + );
  104 + }
  105 +
  106 + return <EllipsisDiv text={textValue} />;
  107 + };
  108 +
  109 + return newItem;
  110 + });
  111 +
  112 + columns.push({
  113 + title: '操作',
  114 + valueType: 'option',
  115 + key: 'option',
  116 + fixed: 'right',
  117 + width: 120,
  118 + render: (text, record) => {
  119 + let btns = [];
  120 + let opts = record.operations;
  121 + if (opts?.includes('modify')) {
  122 + btns.push(
  123 + <Button
  124 + className="p-0"
  125 + key="modify"
  126 + type="link"
  127 + onClick={() => {
  128 + setRechargePrepaymentModalVisible(true);
  129 + setCurrentOptPrepaymentObj(cloneDeep(record));
  130 + }}
  131 + >
  132 + 编辑
  133 + </Button>,
  134 + );
  135 + }
  136 +
  137 + if (opts?.includes('audit')) {
  138 + btns.push(
  139 + <Button
  140 + className="p-0"
  141 + key="view"
  142 + type="link"
  143 + onClick={() => {
  144 + setCurrentOptPrepaymentObj(record);
  145 + setCheckVisible(true);
  146 + }}
  147 + >
  148 + 审核
  149 + </Button>,
  150 + );
  151 + }
  152 +
  153 + if (opts?.includes('delete')) {
  154 + btns.push(
  155 + <ButtonConfirm
  156 + key="delete"
  157 + className="p-0"
  158 + title={'确认删除编号为[ ' + record.id + ' ]的预存记录吗?'}
  159 + text="删除"
  160 + onConfirm={async () => {
  161 + let res = await postPrepaidDelete({
  162 + data: { ids: [record.id] },
  163 + });
  164 + if (res && res.result === RESPONSE_CODE.SUCCESS) {
  165 + message.success(res.message);
  166 + reloadPrepaidTable();
  167 + }
  168 + }}
  169 + />,
  170 + );
  171 + }
  172 + return btns;
  173 + },
  174 + });
  175 +
  176 + return columns;
  177 + };
  178 +
  179 + const accountColumnsInit = () => {
  180 + let columns = ACCOUNT_COLUMNS.map((item) => {
  181 + let newItem = { ...item };
  182 + let dataIndex = item.dataIndex;
  183 +
  184 + newItem.render = (text, record) => {
  185 + let textValue = record[dataIndex];
  186 + return <EllipsisDiv text={getTableCellText(textValue)} />;
  187 + };
  188 +
  189 + return newItem;
  190 + });
  191 +
  192 + columns.push({
  193 + title: '操作',
  194 + valueType: 'option',
  195 + key: 'option',
  196 + fixed: 'right',
  197 + width: 120,
  198 + render: (text, record) => {
  199 + let btns = [];
  200 + btns.push(
  201 + <Button
  202 + className="p-0"
  203 + key="view"
  204 + type="link"
  205 + onClick={() => {
  206 + setCurrentOptUserObj(record);
  207 + setBalanceChangeRecordsModalVisible(true);
  208 + }}
  209 + >
  210 + 消费记录
  211 + </Button>,
  212 + );
  213 + return btns;
  214 + },
  215 + });
  216 +
  217 + return columns;
  218 + };
  219 +
  220 + const tabsItems = [
  221 + {
  222 + key: 1,
  223 + label: '预存管理',
  224 + children: (
  225 + <ProTable
  226 + columns={prepaidColumnsInit()}
  227 + actionRef={prepaidActionRef}
  228 + cardBordered
  229 + pagination={{
  230 + pageSize: 10,
  231 + }}
  232 + request={async (params) => {
  233 + const res = await postPrepaidList({
  234 + data: { ...params },
  235 + });
  236 + return {
  237 + data: res?.data?.data || [],
  238 + total: res?.data?.total || 0,
  239 + };
  240 + }}
  241 + columnsState={{
  242 + persistenceKey: 'pro-table-singe-prepaid',
  243 + persistenceType: 'localStorage',
  244 + defaultValue: {
  245 + option: { fixed: 'right', disable: true },
  246 + },
  247 + onChange(value) {
  248 + console.log('value: ', value);
  249 + },
  250 + }}
  251 + rowKey="id"
  252 + search={{
  253 + labelWidth: 'auto',
  254 + }}
  255 + options={{
  256 + setting: {
  257 + listsHeight: 400,
  258 + },
  259 + }}
  260 + form={{}}
  261 + dateFormatter="string"
  262 + headerTitle="预存管理"
  263 + scroll={{ x: 1400 }}
  264 + toolBarRender={() => [
  265 + <Button
  266 + key="button"
  267 + icon={<PlusOutlined />}
  268 + onClick={() => {
  269 + setCurrentOptPrepaymentObj(null);
  270 + setRechargePrepaymentModalVisible(true);
  271 + }}
  272 + type="primary"
  273 + >
  274 + 新建
  275 + </Button>,
  276 + ]}
  277 + />
  278 + ),
  279 + },
  280 + {
  281 + key: 2,
  282 + label: '账号列表',
  283 + children: (
  284 + <ProTable
  285 + columns={accountColumnsInit()}
  286 + actionRef={accountActionRef}
  287 + cardBordered
  288 + pagination={{
  289 + pageSize: 10,
  290 + }}
  291 + request={async (params) => {
  292 + const res = await postCanrdApiUserList({
  293 + data: { ...params },
  294 + });
  295 + return {
  296 + data: res?.data?.data || [],
  297 + total: res?.data?.total || 0,
  298 + };
  299 + }}
  300 + columnsState={{
  301 + persistenceKey: 'pro-table-singe-account',
  302 + persistenceType: 'localStorage',
  303 + defaultValue: {
  304 + option: { fixed: 'right', disable: true },
  305 + },
  306 + onChange(value) {
  307 + console.log('value: ', value);
  308 + },
  309 + }}
  310 + rowKey="id"
  311 + search={{
  312 + labelWidth: 'auto',
  313 + }}
  314 + options={{
  315 + setting: {
  316 + listsHeight: 400,
  317 + },
  318 + }}
  319 + form={{}}
  320 + dateFormatter="string"
  321 + headerTitle="账号列表"
  322 + scroll={{ x: 1400 }}
  323 + toolBarRender={() => []}
  324 + />
  325 + ),
  326 + },
  327 + ];
  328 + return (
  329 + <div className="prepaid-index">
  330 + <Tabs
  331 + defaultActiveKey="1"
  332 + items={tabsItems}
  333 + onChange={(value) => {
  334 + if (value === '1') {
  335 + reloadPrepaidTable();
  336 + } else {
  337 + reloadAccountTable();
  338 + }
  339 + }}
  340 + />
  341 +
  342 + {rechargePrepaymentModalVisible && (
  343 + <RechargePrepaymentModal
  344 + setVisible={setRechargePrepaymentModalVisible}
  345 + onClose={() => {
  346 + setRechargePrepaymentModalVisible(false);
  347 + reloadPrepaidTable();
  348 + }}
  349 + prepaymentObject={currentOptPrepaymentObj}
  350 + />
  351 + )}
  352 +
  353 + {checkVisible && (
  354 + <CheckModal
  355 + setCheckVisible={(val: boolean) => {
  356 + setCheckVisible(val);
  357 + }}
  358 + data={[currentOptPrepaymentObj]}
  359 + subOrders={[currentOptPrepaymentObj]}
  360 + orderCheckType={CHECK_TYPE.PREPAID_AUDIT}
  361 + openOrderDrawer={false}
  362 + onClose={() => {
  363 + setCheckVisible(false);
  364 + reloadPrepaidTable();
  365 + }}
  366 + />
  367 + )}
  368 +
  369 + {balanceChangeRecordsModalVisible && (
  370 + <BalanceChangeRecordsModal
  371 + setVisible={(val: boolean) => {
  372 + setBalanceChangeRecordsModalVisible(val);
  373 + }}
  374 + userInfoObj={currentOptUserObj}
  375 + onClose={() => {
  376 + setBalanceChangeRecordsModalVisible(false);
  377 + }}
  378 + />
  379 + )}
  380 + </div>
  381 + );
  382 +};
  383 +
  384 +export default PrepaidPage;
... ...
src/utils/order.ts
... ... @@ -6,10 +6,18 @@ export function getReceivingCompanyOptions(PAYEE_OPTIONS: any) {
6 6 return payeeOptions;
7 7 }
8 8  
9   -export function isSupplier(){
  9 +export function isSupplier() {
10 10 let userInfo = getUserInfo();
11   - if(userInfo){
12   - return ['首能','枭源'].includes(userInfo.username);
  11 + if (userInfo) {
  12 + return ['首能', '枭源'].includes(userInfo.username);
  13 + }
  14 + return false;
  15 +}
  16 +
  17 +export function isExaminer() {
  18 + let userInfo = getUserInfo();
  19 + if (userInfo) {
  20 + return userInfo.roleSmallVO?.code === 'examiner';
13 21 }
14 22 return false;
15 23 }
... ...