Commit 44883077f48289f0b47a635b2a3cca3afbf97ee4

Authored by boyang
2 parents 1858be19 2ae24a7d

Merge remote-tracking branch 'remotes/origin/by' into warning

Showing 64 changed files with 3596 additions and 213 deletions

Too many changes to show.

To preserve performance only 64 of 94 files are displayed.

.umirc.ts
... ... @@ -29,7 +29,7 @@ export default defineConfig({
29 29 routes: [
30 30 {
31 31 path: '/',
32   - redirect: '/order',
  32 + redirect: '/order/order',
33 33 },
34 34 {
35 35 name: '登录',
... ... @@ -41,8 +41,24 @@ export default defineConfig({
41 41 {
42 42 name: '订单管理',
43 43 path: '/order',
44   - component: './Order',
45 44 icon: 'ProfileOutlined',
  45 + routes: [
  46 + {
  47 + name: '订单列表',
  48 + path: 'order',
  49 + component: './Order/Order',
  50 + },
  51 + {
  52 + name: '订单预警',
  53 + path: 'OrderWarning',
  54 + component: './Order/OrderWarning',
  55 + },
  56 + {
  57 + name: '预警白名单',
  58 + path: 'WarningWhitelist',
  59 + component: './Order/WarningWhitelist',
  60 + },
  61 + ],
46 62 },
47 63 {
48 64 name: '订单报表',
... ...
src/components/UserHeader/index.tsx
1 1 import { RESPONSE_CODE } from '@/constants/enum';
2   -import MessageListDrawer from '@/pages/Order/components/MessageListDrawer';
  2 +import MessageListDrawer from '@/pages/Order/Order/components/MessageListDrawer';
3 3 import { postOrderErpMessageGetUnreadNum } from '@/services';
4 4 import { getUserInfo } from '@/utils';
5 5 import { BellOutlined, EllipsisOutlined } from '@ant-design/icons';
... ...
src/pages/Instalment/components/checkModal/TableCheckModal.tsx
... ... @@ -55,7 +55,8 @@ export default ({ id, toReload, isShow }) => {
55 55 }
56 56 toReload();
57 57 }
58   - return;
  58 + props.submit();
  59 + return true;
59 60 }}
60 61 >
61 62 驳回
... ... @@ -91,7 +92,7 @@ export default ({ id, toReload, isShow }) => {
91 92 name="mark"
92 93 label="备注"
93 94 tooltip="请特别注意订单总金额与订单金额。"
94   - placeholder="请输入名称"
  95 + placeholder="如驳回请输入原因"
95 96 />
96 97 </ModalForm>
97 98 </Space>
... ...
src/pages/Instalment/components/checkModal/checkModal.tsx
... ... @@ -46,7 +46,7 @@ export default ({ id, toReload }) =&gt; {
46 46 message.success('操作成功');
47 47 }
48 48 toReload();
49   - return;
  49 + return true;
50 50 }}
51 51 >
52 52 驳回
... ... @@ -77,7 +77,7 @@ export default ({ id, toReload }) =&gt; {
77 77 name="mark"
78 78 label="备注"
79 79 tooltip="请特别注意订单总金额与订单金额。"
80   - placeholder="请输入名称"
  80 + placeholder="如驳回请输入原因"
81 81 />
82 82 </ModalForm>
83 83 </Space>
... ...
src/pages/Instalment/components/payWayDetail/payWayDetail.css
... ... @@ -10,6 +10,18 @@
10 10 margin-bottom: 0 !important;
11 11 }
12 12  
13   -.dataChoose {
14   - margin: 0;
  13 +.payway-detail-index td .ant-form-item css-nllxry {
  14 + margin-bottom: 0 !important;
  15 +}
  16 +
  17 +.payWaydataChoose {
  18 + margin: 0 !important;
  19 +}
  20 +
  21 +.ant-form-item css-nllxry {
  22 + margin-bottom: 0 !important;
  23 +}
  24 +
  25 +:where(.css-nllxry).ant-form-item {
  26 + margin-bottom: 0 !important;
15 27 }
... ...
src/pages/Instalment/components/payWayDetail/payWayDetail.less
... ... @@ -8,10 +8,22 @@
8 8 .css-dev-only-do-not-override-nllxry {
9 9 margin-bottom: 0 !important;
10 10 }
  11 +
  12 + .ant-form-item css-nllxry {
  13 + margin-bottom: 0 !important;
  14 + }
11 15 }
12 16  
13   -.dataChoose {
14   - margin: 0;
  17 +.payWaydataChoose {
  18 + margin: 0 !important;
  19 +}
  20 +
  21 +.ant-form-item css-nllxry {
  22 + margin-bottom: 0 !important;
  23 +}
  24 +
  25 +:where(.css-nllxry).ant-form-item {
  26 + margin-bottom: 0 !important;
15 27 }
16 28  
17 29 // .pay-way-detail-index td .css-dev-only-do-not-override-nllxry{
... ...
src/pages/Instalment/components/payWayDetail/payWayDetail.tsx
... ... @@ -212,7 +212,7 @@ export default ({ payBody, thisId, currtSave }) =&gt; {
212 212  
213 213 return (
214 214 <ProFormDatePicker
215   - className="dataChoose"
  215 + className="payWaydataChoose"
216 216 initialValue={record.payDate}
217 217 value={record.payDate}
218 218 placeholder={'请填写时间'}
... ...
src/pages/Order/components/AfterSalesDrawer.tsx renamed to src/pages/Order/Order/components/AfterSalesDrawer.tsx
... ... @@ -9,7 +9,7 @@ import {
9 9 ProFormUploadDragger,
10 10 } from '@ant-design/pro-components';
11 11 import { Form, message } from 'antd';
12   -import { AFTE_SALES_PLAN_OPTIONS } from '../constant';
  12 +import { AFTE_SALES_PLAN_OPTIONS } from '../../constant';
13 13 export default ({ setVisible, mainOrder, subOrders, onClose }) => {
14 14 let subOrderIds = subOrders?.map((item: { id: any }) => {
15 15 return item.id;
... ...
src/pages/Order/components/ApplyForInvoicingModal.tsx renamed to src/pages/Order/Order/components/ApplyForInvoicingModal.tsx
... ... @@ -10,7 +10,7 @@ import {
10 10 } from '@ant-design/pro-components';
11 11 import { Form, message } from 'antd';
12 12 import { useEffect, useState } from 'react';
13   -import { PAYEE_OPTIONS } from '../constant';
  13 +import { PAYEE_OPTIONS } from '../../constant';
14 14 export default ({
15 15 setCheckVisible,
16 16 isEdit,
... ...
src/pages/Order/components/AttachmentModal.tsx renamed to src/pages/Order/Order/components/AttachmentModal.tsx
src/pages/Order/components/BaseModal.tsx renamed to src/pages/Order/Order/components/BaseModal.tsx
src/pages/Order/components/CheckModal.tsx renamed to src/pages/Order/Order/components/CheckModal.tsx
... ... @@ -33,9 +33,9 @@ import {
33 33 AFTE_SALES_PLAN_OPTIONS,
34 34 CHECK_TYPE,
35 35 COMFIR_RECEIPT_IMAGES_NUMBER,
36   -} from '../constant';
  36 +} from '../../constant';
37 37 // import { cloneDeep } from 'lodash';
38   -import InvoiceSubOrderInfoTable from '@/pages/Order/components/InvoiceSubOrderInfoTable';
  38 +import InvoiceSubOrderInfoTable from '@/pages/Order/Order/components/InvoiceSubOrderInfoTable';
39 39 import { enumValueToLabel, transImageFile } from '@/utils';
40 40 import { PlusOutlined } from '@ant-design/icons';
41 41 import { cloneDeep } from 'lodash';
... ... @@ -236,8 +236,8 @@ export default ({
236 236 setPreviewOpen(true);
237 237 setPreviewTitle(
238 238 file.name ||
239   - file.originFileObj?.name ||
240   - file.url!.substring(file.url!.lastIndexOf('/') + 1),
  239 + file.originFileObj?.name ||
  240 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
241 241 );
242 242 };
243 243  
... ...
src/pages/Order/components/ConfirmReceiptModal.tsx renamed to src/pages/Order/Order/components/ConfirmReceiptModal.tsx
... ... @@ -5,7 +5,7 @@ import { Button, Modal, Upload, message } from &#39;antd&#39;;
5 5 import { RcFile, UploadFile, UploadProps } from 'antd/es/upload';
6 6 import { cloneDeep } from 'lodash';
7 7 import { useEffect, useRef, useState } from 'react';
8   -import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../constant';
  8 +import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant';
9 9 export default ({ data, onClose }) => {
10 10 const subIds = data?.map((item) => {
11 11 return item.id;
... ... @@ -107,8 +107,8 @@ export default ({ data, onClose }) =&gt; {
107 107 setPreviewOpen(true);
108 108 setPreviewTitle(
109 109 file.name ||
110   - file.originFileObj?.name ||
111   - file.url!.substring(file.url!.lastIndexOf('/') + 1),
  110 + file.originFileObj?.name ||
  111 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
112 112 );
113 113 };
114 114  
... ...
src/pages/Order/components/DeliverInfoDrawer.tsx renamed to src/pages/Order/Order/components/DeliverInfoDrawer.tsx
... ... @@ -3,7 +3,7 @@ import { enumValueToLabel } from &#39;@/utils&#39;;
3 3 import { getReceivingCompanyOptions } from '@/utils/order';
4 4 import { Col, Drawer, Row } from 'antd';
5 5 import { useEffect, useState } from 'react';
6   -import { PAYEE_OPTIONS } from '../constant';
  6 +import { PAYEE_OPTIONS } from '../../constant';
7 7  
8 8 export default ({ data, onClose }) => {
9 9 const [province, setProvince] = useState('');
... ...
src/pages/Order/components/DeliverModal.tsx renamed to src/pages/Order/Order/components/DeliverModal.tsx
... ... @@ -25,7 +25,7 @@ import {
25 25 } from 'antd';
26 26 import { cloneDeep } from 'lodash';
27 27 import { useEffect, useRef, useState } from 'react';
28   -import { CHECK_TYPE, LOGISTICS_STATUS_OPTIONS } from '../constant';
  28 +import { CHECK_TYPE, LOGISTICS_STATUS_OPTIONS } from '../../constant';
29 29  
30 30 const DeliverModal = ({
31 31 data: propsData,
... ... @@ -260,7 +260,7 @@ const DeliverModal = ({
260 260 serialNumber: item.serialNumber,
261 261 packageNumber:
262 262 item.packageNumber === null ||
263   - item.packageNumber === undefined
  263 + item.packageNumber === undefined
264 264 ? 1
265 265 : item.packageNumber,
266 266 logisticsNotes: item.logisticsNotes,
... ...
src/pages/Order/components/FinancialDrawer.tsx renamed to src/pages/Order/Order/components/FinancialDrawer.tsx
... ... @@ -15,7 +15,7 @@ import {
15 15 } from '@ant-design/pro-components';
16 16 import { Button, Form, message } from 'antd';
17 17 import { useEffect, useState } from 'react';
18   -import { INVOCING_STATUS_OPTIONS_OLD, PAYEE_OPTIONS } from '../constant';
  18 +import { INVOCING_STATUS_OPTIONS_OLD, PAYEE_OPTIONS } from '../../constant';
19 19  
20 20 export default ({
21 21 mainOrder,
... ... @@ -144,107 +144,107 @@ export default ({
144 144  
145 145 {invoicingStatus !== 'UN_INVOICE'
146 146 ? [
147   - <ProFormDatePicker
148   - key="invoicingTime"
149   - width="lg"
150   - name="invoicingTime"
151   - label="开票时间"
152   - disabled={isEdit}
153   - rules={[
154   - { required: !isEdit ? true : false, message: '这是必填项' },
155   - ]}
156   - initialValue={subOrders[0]?.invoicingTime}
157   - />,
158   - <ProFormText
159   - key="purchaser"
160   - width="lg"
161   - name="purchaser"
162   - label="抬头名称"
163   - disabled={isEdit}
164   - rules={[
165   - { required: !isEdit ? true : false, message: '这是必填项' },
166   - ]}
167   - initialValue={subOrders[0]?.purchaser}
168   - />,
169   - <ProFormDatePicker
170   - key="financialReceiptIssuanceTime"
171   - width="lg"
172   - name="financialReceiptIssuanceTime"
173   - label="开收据时间"
174   - initialValue={subOrders[0]?.financialReceiptIssuanceTime}
175   - />,
176   - <ProFormDatePicker
177   - key="collectMoneyTime"
178   - width="lg"
179   - name="collectMoneyTime"
180   - label="收款时间"
181   - initialValue={subOrders[0]?.collectMoneyTime}
182   - />,
183   - <ProFormText
184   - width="lg"
185   - key="invoiceNumber"
186   - name="invoiceNumber"
187   - label="发票号码"
188   - initialValue={subOrders[0]?.invoiceNumber}
189   - rules={[{ required: true, message: '发票号码必填' }]}
190   - />,
191   - <div
192   - key="salesChooseReceivingCompany"
193   - hidden={subOrders[0].receivingCompany === null}
  147 + <ProFormDatePicker
  148 + key="invoicingTime"
  149 + width="lg"
  150 + name="invoicingTime"
  151 + label="开票时间"
  152 + disabled={isEdit}
  153 + rules={[
  154 + { required: !isEdit ? true : false, message: '这是必填项' },
  155 + ]}
  156 + initialValue={subOrders[0]?.invoicingTime}
  157 + />,
  158 + <ProFormText
  159 + key="purchaser"
  160 + width="lg"
  161 + name="purchaser"
  162 + label="抬头名称"
  163 + disabled={isEdit}
  164 + rules={[
  165 + { required: !isEdit ? true : false, message: '这是必填项' },
  166 + ]}
  167 + initialValue={subOrders[0]?.purchaser}
  168 + />,
  169 + <ProFormDatePicker
  170 + key="financialReceiptIssuanceTime"
  171 + width="lg"
  172 + name="financialReceiptIssuanceTime"
  173 + label="开收据时间"
  174 + initialValue={subOrders[0]?.financialReceiptIssuanceTime}
  175 + />,
  176 + <ProFormDatePicker
  177 + key="collectMoneyTime"
  178 + width="lg"
  179 + name="collectMoneyTime"
  180 + label="收款时间"
  181 + initialValue={subOrders[0]?.collectMoneyTime}
  182 + />,
  183 + <ProFormText
  184 + width="lg"
  185 + key="invoiceNumber"
  186 + name="invoiceNumber"
  187 + label="发票号码"
  188 + initialValue={subOrders[0]?.invoiceNumber}
  189 + rules={[{ required: true, message: '发票号码必填' }]}
  190 + />,
  191 + <div
  192 + key="salesChooseReceivingCompany"
  193 + hidden={subOrders[0].receivingCompany === null}
  194 + >
  195 + <span className={'pl-2 text-xs text-gray-400'}>
  196 + 销售申请开票时选择了:
  197 + {enumValueToLabel(
  198 + subOrders[0].receivingCompany,
  199 + getReceivingCompanyOptions(PAYEE_OPTIONS),
  200 + )}
  201 + </span>
  202 + <span
  203 + hidden={subOrders[0].receivingCompany === 'ANY'}
  204 + className={
  205 + 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'
  206 + }
  207 + onClick={() => {
  208 + chooseReceivingCompany(subOrders[0].receivingCompany);
  209 + }}
194 210 >
195   - <span className={'pl-2 text-xs text-gray-400'}>
196   - 销售申请开票时选择了:
197   - {enumValueToLabel(
198   - subOrders[0].receivingCompany,
199   - getReceivingCompanyOptions(PAYEE_OPTIONS),
200   - )}
201   - </span>
202   - <span
203   - hidden={subOrders[0].receivingCompany === 'ANY'}
204   - className={
205   - 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'
206   - }
207   - onClick={() => {
208   - chooseReceivingCompany(subOrders[0].receivingCompany);
209   - }}
210   - >
211   - 选择
212   - </span>
213   - </div>,
214   - <ProFormSelect
215   - key="payee"
216   - placeholder="选择收款单位"
217   - name="payee"
218   - width="lg"
219   - showSearch
220   - label="收款单位"
221   - options={enumToSelect(PAYEE_OPTIONS)}
222   - initialValue={subOrders[0]?.payee}
223   - rules={[{ required: true, message: '收款单位必填' }]}
224   - />,
  211 + 选择
  212 + </span>
  213 + </div>,
  214 + <ProFormSelect
  215 + key="payee"
  216 + placeholder="选择收款单位"
  217 + name="payee"
  218 + width="lg"
  219 + showSearch
  220 + label="收款单位"
  221 + options={enumToSelect(PAYEE_OPTIONS)}
  222 + initialValue={subOrders[0]?.payee}
  223 + rules={[{ required: true, message: '收款单位必填' }]}
  224 + />,
225 225  
226   - <div id="total-payment" key="money">
227   - <ProFormDigit
228   - key="money"
229   - name="money"
230   - width="lg"
231   - label="金额"
232   - rules={[{ required: true, message: '金额必填' }]}
233   - tooltip="点击计算,合计所有子订单对应主订单总额"
234   - fieldProps={{
235   - addonAfter: (
236   - <Button
237   - className="rounded-l-none"
238   - type="primary"
239   - onClick={computeTotalPayment}
240   - >
241   - 计算
242   - </Button>
243   - ),
244   - }}
245   - />
246   - </div>,
247   - ]
  226 + <div id="total-payment" key="money">
  227 + <ProFormDigit
  228 + key="money"
  229 + name="money"
  230 + width="lg"
  231 + label="金额"
  232 + rules={[{ required: true, message: '金额必填' }]}
  233 + tooltip="点击计算,合计所有子订单对应主订单总额"
  234 + fieldProps={{
  235 + addonAfter: (
  236 + <Button
  237 + className="rounded-l-none"
  238 + type="primary"
  239 + onClick={computeTotalPayment}
  240 + >
  241 + 计算
  242 + </Button>
  243 + ),
  244 + }}
  245 + />
  246 + </div>,
  247 + ]
248 248 : ''}
249 249  
250 250 <ProFormSelect
... ...
src/pages/Order/components/FinancialEditDrawer.tsx renamed to src/pages/Order/Order/components/FinancialEditDrawer.tsx
... ... @@ -9,7 +9,7 @@ import {
9 9 } from '@ant-design/pro-components';
10 10 import { Form, message } from 'antd';
11 11 import { useEffect, useState } from 'react';
12   -import { INVOCING_STATUS_OPTIONS_OLD } from '../constant';
  12 +import { INVOCING_STATUS_OPTIONS_OLD } from '../../constant';
13 13  
14 14 export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) => {
15 15 const [invoicingStatus, setInvoicingStatus] = useState('');
... ... @@ -130,24 +130,24 @@ export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) =&gt; {
130 130 width="lg"
131 131 name="financialReceiptIssuanceTime"
132 132 label="开收据时间"
133   - // rules={[
134   - // {
135   - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
136   - // message: '开收据时间必填',
137   - // },
138   - // ]}
  133 + // rules={[
  134 + // {
  135 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  136 + // message: '开收据时间必填',
  137 + // },
  138 + // ]}
139 139 />
140 140 <ProFormDatePicker
141 141 key="collectMoneyTime"
142 142 width="lg"
143 143 name="collectMoneyTime"
144 144 label="收款时间"
145   - // rules={[
146   - // {
147   - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
148   - // message: '收款时间必填',
149   - // },
150   - // ]}
  145 + // rules={[
  146 + // {
  147 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  148 + // message: '收款时间必填',
  149 + // },
  150 + // ]}
151 151 />
152 152 </DrawerForm>
153 153 );
... ...
src/pages/Order/components/FinancialMergeDrawer.tsx renamed to src/pages/Order/Order/components/FinancialMergeDrawer.tsx
... ... @@ -9,7 +9,7 @@ import {
9 9 ProFormTextArea,
10 10 } from '@ant-design/pro-components';
11 11 import { Form, message } from 'antd';
12   -import { PAYEE_OPTIONS } from '../constant';
  12 +import { PAYEE_OPTIONS } from '../../constant';
13 13  
14 14 export default ({ dataList, setVisible, onClose }) => {
15 15 // let subOrderIds = dataList?.map((item) => {
... ...
src/pages/Order/components/FinancialReceiptsModal.tsx renamed to src/pages/Order/Order/components/FinancialReceiptsModal.tsx
src/pages/Order/components/HistoryModal.tsx renamed to src/pages/Order/Order/components/HistoryModal.tsx
src/pages/Order/components/ImagesViewerModal.tsx renamed to src/pages/Order/Order/components/ImagesViewerModal.tsx
src/pages/Order/components/ImportExpressBillModal.tsx renamed to src/pages/Order/Order/components/ImportExpressBillModal.tsx
src/pages/Order/components/ImportModal.tsx renamed to src/pages/Order/Order/components/ImportModal.tsx
src/pages/Order/components/InvoiceSubOrderInfoTable.tsx renamed to src/pages/Order/Order/components/InvoiceSubOrderInfoTable.tsx
src/pages/Order/components/InvoicingDrawerForm.tsx renamed to src/pages/Order/Order/components/InvoicingDrawerForm.tsx
src/pages/Order/components/KingdeeCustomerModal.tsx renamed to src/pages/Order/Order/components/KingdeeCustomerModal.tsx
src/pages/Order/components/LazySelect.tsx renamed to src/pages/Order/Order/components/LazySelect.tsx
src/pages/Order/components/MessageListDrawer.tsx renamed to src/pages/Order/Order/components/MessageListDrawer.tsx
src/pages/Order/components/ModifiedDiffModal.tsx renamed to src/pages/Order/Order/components/ModifiedDiffModal.tsx
... ... @@ -9,7 +9,7 @@ import {
9 9 PAYMENT_METHOD_OPTIONS,
10 10 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
11 11 SHIPPING_WAREHOUSE_OPTIONS,
12   -} from '../constant';
  12 +} from '../../constant';
13 13 import '../table.less';
14 14  
15 15 export default ({ setVisible, subOrders, mainOrder, onClose }) => {
... ... @@ -106,7 +106,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
106 106 onClick={() => {
107 107 window.open(
108 108 '/previewApi/onlinePreview?url=' +
109   - encodeURIComponent(Base64.encode(item)),
  109 + encodeURIComponent(Base64.encode(item)),
110 110 );
111 111 }}
112 112 >
... ...
src/pages/Order/components/OrderDrawer copy.tsx renamed to src/pages/Order/Order/components/OrderDrawer copy.tsx
... ... @@ -36,7 +36,7 @@ import {
36 36 PAYMENT_CHANNEL_OPTIONS,
37 37 PAYMENT_METHOD_OPTIONS,
38 38 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
39   -} from '../constant';
  39 +} from '../../constant';
40 40 import KingdeeCustomerModal from './KingdeeCustomerModal';
41 41  
42 42 export default ({ onClose, data, subOrders, orderOptType }) => {
... ... @@ -554,7 +554,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
554 554 onChange={(_, option) => {
555 555 autoFillSalesInfo(option);
556 556 }}
557   - // disabled={mainInfoDisbled}
  557 + // disabled={mainInfoDisbled}
558 558 />
559 559  
560 560 <ProFormText
... ... @@ -642,7 +642,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
642 642 },
643 643 }}
644 644 debounceTime={1000}
645   - request={async (value, {}) => {
  645 + request={async (value, { }) => {
646 646 const keywords = value.keyWords;
647 647 const res = await postKingdeeRepCustomer({
648 648 data: { search: keywords },
... ... @@ -740,7 +740,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
740 740 </Button>
741 741 ),
742 742 }}
743   - // disabled={mainInfoDisbled}
  743 + // disabled={mainInfoDisbled}
744 744 />
745 745 </div>
746 746  
... ... @@ -752,7 +752,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
752 752 label="支付渠道"
753 753 options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)}
754 754 rules={[{ required: true, message: '支付渠道必填' }]}
755   - // disabled={mainInfoDisbled}
  755 + // disabled={mainInfoDisbled}
756 756 />
757 757 <ProFormSelect
758 758 placeholder="请输入支付方式"
... ... @@ -762,7 +762,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
762 762 label="支付方式"
763 763 options={enumToSelect(PAYMENT_METHOD_OPTIONS)}
764 764 rules={[{ required: true, message: '支付方式必填' }]}
765   - // disabled={mainInfoDisbled}
  765 + // disabled={mainInfoDisbled}
766 766 />
767 767 <ProFormSelect
768 768 placeholder="选择是否需要开票"
... ... @@ -1094,7 +1094,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1094 1094 options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)}
1095 1095 initialValue={'EXPERIMENTAL_CONSUMABLES'}
1096 1096 rules={[{ required: true, message: '所属事业部必填' }]}
1097   - // disabled={mainInfoDisbled}
  1097 + // disabled={mainInfoDisbled}
1098 1098 />,
1099 1099 <ProFormTextArea
1100 1100 key={'notes' + listMeta.index}
... ...
src/pages/Order/components/OrderDrawer.tsx renamed to src/pages/Order/Order/components/OrderDrawer.tsx
... ... @@ -52,7 +52,7 @@ import {
52 52 PAYMENT_METHOD_OPTIONS,
53 53 PRODUCT_BELONG_DEPARTMENT_OPTIONS,
54 54 SHIPPING_WAREHOUSE_OPTIONS,
55   -} from '../constant';
  55 +} from '../../constant';
56 56 import KingdeeCustomerModal from './KingdeeCustomerModal';
57 57  
58 58 export default ({ onClose, data, subOrders, orderOptType }) => {
... ... @@ -557,9 +557,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
557 557 form.setFieldValue(
558 558 'customerShippingAddress',
559 559 getDefaultString(option.province) +
560   - getDefaultString(option.city) +
561   - getDefaultString(option.district) +
562   - getDefaultString(option.detail),
  560 + getDefaultString(option.city) +
  561 + getDefaultString(option.district) +
  562 + getDefaultString(option.detail),
563 563 );
564 564 form.setFieldValue('customerNameString', option.realName);
565 565  
... ... @@ -642,11 +642,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
642 642  
643 643 message.error(
644 644 '用户余额不足,当前预减的金额为:' +
645   - data.subPrice +
646   - ',当前账号余额为:' +
647   - data.nowMoney +
648   - ',当前账号可赊账额度为:' +
649   - data.creditLimit,
  645 + data.subPrice +
  646 + ',当前账号余额为:' +
  647 + data.nowMoney +
  648 + ',当前账号可赊账额度为:' +
  649 + data.creditLimit,
650 650 );
651 651 return false;
652 652 }
... ... @@ -1111,7 +1111,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1111 1111 },
1112 1112 }}
1113 1113 debounceTime={1000}
1114   - request={async (value, {}) => {
  1114 + request={async (value, { }) => {
1115 1115 const keywords = value.keyWords;
1116 1116 if (keywords === '') {
1117 1117 return [];
... ... @@ -1867,7 +1867,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1867 1867 placeholder="请输入商品参数"
1868 1868 disabled={
1869 1869 productParametersDisabledFlagList[listMeta.index] !==
1870   - false || optType('after-sales-check')
  1870 + false || optType('after-sales-check')
1871 1871 }
1872 1872 />,
1873 1873 <ProFormDigit
... ... @@ -1920,7 +1920,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1920 1920 placeholder="请输入商品单位"
1921 1921 disabled={
1922 1922 productParametersDisabledFlagList[listMeta.index] !==
1923   - false || optType('after-sales-check')
  1923 + false || optType('after-sales-check')
1924 1924 }
1925 1925 rules={[{ required: true, message: '商品单位必填' }]}
1926 1926 />,
... ...
src/pages/Order/components/OrderNotesEditModal.tsx renamed to src/pages/Order/Order/components/OrderNotesEditModal.tsx
src/pages/Order/components/OtherInfoModal.tsx renamed to src/pages/Order/Order/components/OtherInfoModal.tsx
src/pages/Order/components/ProcureCheckModal.tsx renamed to src/pages/Order/Order/components/ProcureCheckModal.tsx
src/pages/Order/components/ProcureConvertModal.tsx renamed to src/pages/Order/Order/components/ProcureConvertModal.tsx
src/pages/Order/components/ProcureNotesEditModal.tsx renamed to src/pages/Order/Order/components/ProcureNotesEditModal.tsx
src/pages/Order/components/ProductionTimeModal.tsx renamed to src/pages/Order/Order/components/ProductionTimeModal.tsx
src/pages/Order/components/ReissueModal.tsx renamed to src/pages/Order/Order/components/ReissueModal.tsx
src/pages/Order/components/ReissueModal_old.tsx renamed to src/pages/Order/Order/components/ReissueModal_old.tsx
src/pages/Order/components/ShippingWarehouseChangeModal.tsx renamed to src/pages/Order/Order/components/ShippingWarehouseChangeModal.tsx
... ... @@ -3,7 +3,7 @@ import { postServiceOrderShippingWarehouseChange } from &#39;@/services&#39;;
3 3 import { enumToSelect } from '@/utils';
4 4 import { ModalForm, ProFormSelect } from '@ant-design/pro-components';
5 5 import { Form, message } from 'antd';
6   -import { SHIPPING_WAREHOUSE_OPTIONS } from '../constant';
  6 +import { SHIPPING_WAREHOUSE_OPTIONS } from '../../constant';
7 7  
8 8 export default ({
9 9 setVisible,
... ...
src/pages/Order/components/UploadPayBillModal.tsx renamed to src/pages/Order/Order/components/UploadPayBillModal.tsx
... ... @@ -3,7 +3,7 @@ import { Form, Modal, Upload, UploadFile, UploadProps, message } from &#39;antd&#39;;
3 3 import { RcFile } from 'antd/lib/upload';
4 4 import { cloneDeep } from 'lodash';
5 5 import { useEffect, useRef, useState } from 'react';
6   -import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../constant';
  6 +import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant';
7 7 import { PlusOutlined } from '@ant-design/icons';
8 8 import { transImageFile } from '@/utils';
9 9 import { postServiceOrderFileProcess, postServiceOrderUploadPaymentReceipt } from '@/services';
... ...
src/pages/Order/hooks.ts renamed to src/pages/Order/Order/hooks.ts
src/pages/Order/Order/index.css 0 → 100644
  1 +.order-page-container .ant-table .ant-table-middle {
  2 + margin-inline: 0 !important;
  3 +}
  4 +.order-page-container td {
  5 + font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', 'WenQuanYi Micro Hei', sans-serif;
  6 + font-size: 13px;
  7 +}
  8 +#total-payment .ant-input-number-group-addon {
  9 + padding: 0 !important;
  10 +}
  11 +.order-page-container table:hover,
  12 +.order-page-container tr:hover,
  13 +.order-page-container thead:hover {
  14 + background: none !important;
  15 +}
  16 +#main-table .ant-table-tbody > tr.ant-table-row:hover > td {
  17 + background: none !important;
  18 +}
  19 +.order-page-container .ant-pro-card {
  20 + background-color: transparent;
  21 +}
  22 +#main-table .ant-table-tbody .ant-table-cell {
  23 + padding: 10px 0 0;
  24 +}
  25 +.order-page-container .ant-pagination {
  26 + background-color: #fff !important;
  27 + padding: 10px;
  28 + border-radius: 8px;
  29 +}
  30 +.order-page-container .ant-pro-table .ant-form {
  31 + background-color: #fff;
  32 + border-radius: 8px;
  33 +}
  34 +#main-table .ant-table-tbody {
  35 + background-color: #f5f5f5;
  36 +}
  37 +.order-page-container .ant-pro-card-body {
  38 + padding: 0 !important;
  39 +}
  40 +.order-page-container .ant-table-thead .ant-table-cell {
  41 + background-color: #fff !important;
  42 + border-radius: 8px !important;
  43 +}
  44 +#sub-table tbody td {
  45 + padding: 10px 0 !important;
  46 +}
  47 +#sub-table tbody tr:first-child td:first-child {
  48 + border-top-left-radius: 8px;
  49 +}
  50 +#sub-table tbody tr:first-child td:nth-child(2) {
  51 + border-top-right-radius: 8px;
  52 +}
  53 +#sub-table tbody tr:last-child td:first-child {
  54 + border-bottom-left-radius: 8px;
  55 +}
  56 +#sub-table tbody tr:last-child td:nth-child(2) {
  57 + border-bottom-right-radius: 8px;
  58 +}
  59 +#sub-table tbody tr td:first-child {
  60 + border-top: 1px solid #d7d6d6;
  61 + /* 设置行与行之间分割线的颜色 */
  62 + border-bottom: 1px solid #d7d6d6;
  63 + /* 设置行与行之间分割线的颜色 */
  64 + border-left: 1px solid #d7d6d6;
  65 + /* 设置行与行之间分割线的颜色 */
  66 +}
  67 +#sub-table tbody tr td:nth-child(2) {
  68 + border-top: 1px solid #d7d6d6;
  69 + /* 设置行与行之间分割线的颜色 */
  70 + border-bottom: 1px solid #d7d6d6;
  71 + /* 设置行与行之间分割线的颜色 */
  72 + border-right: 1px solid #d7d6d6;
  73 + /* 设置行与行之间分割线的颜色 */
  74 +}
... ...
src/pages/Order/index.less renamed to src/pages/Order/Order/index.less
... ... @@ -9,7 +9,6 @@
9 9 'WenQuanYi Micro Hei', sans-serif;
10 10 font-size: 13px;
11 11 }
12   -
13 12 //订单编辑抽屉中,订单总额addonAfter的padding去除
14 13 #total-payment .ant-input-number-group-addon {
15 14 padding: 0 !important;
... ...
src/pages/Order/index.tsx renamed to src/pages/Order/Order/index.tsx
1 1 import ButtonConfirm from '@/components/ButtomConfirm';
2 2 import { RESPONSE_CODE } from '@/constants/enum';
3   -import ImportExpressBillModal from '@/pages/Order/components/ImportExpressBillModal';
4   -import InvoicingDrawerForm from '@/pages/Order/components/InvoicingDrawerForm';
5   -import ReissueModal from '@/pages/Order/components/ReissueModal';
6   -import ReissueModal_old from '@/pages/Order/components/ReissueModal_old';
  3 +import ImportExpressBillModal from '@/pages/Order/Order/components/ImportExpressBillModal';
  4 +import InvoicingDrawerForm from '@/pages/Order/Order/components/InvoicingDrawerForm';
  5 +import ReissueModal from '@/pages/Order/Order/components/ReissueModal';
  6 +import ReissueModal_old from '@/pages/Order/Order/components/ReissueModal_old';
7 7 import {
8 8 postKingdeeRepSalBillOutbound,
9 9 postKingdeeRepSalOrderSave,
... ... @@ -79,7 +79,7 @@ import {
79 79 import Base64 from 'base-64';
80 80 import { cloneDeep } from 'lodash';
81 81 import React, { Key, useEffect, useMemo, useRef, useState } from 'react';
82   -import OrderPrintModal from '../OrderPrint/OrderPrintModal';
  82 +import OrderPrintModal from '../../OrderPrint/OrderPrintModal';
83 83 import AfterSalesDrawer from './components/AfterSalesDrawer';
84 84 import ApplyForInvoicingModal from './components/ApplyForInvoicingModal';
85 85 import AttachmentModal from './components/AttachmentModal';
... ... @@ -120,7 +120,7 @@ import {
120 120 TAGS_COLOR,
121 121 getInvoicingType,
122 122 getNeedInvoicing,
123   -} from './constant';
  123 +} from '../constant';
124 124 import './index.less';
125 125 import { OrderListItemType, OrderType } from './type.d';
126 126  
... ... @@ -831,7 +831,7 @@ const OrderPage = () =&gt; {
831 831 onConfirm={() => {
832 832 window.open(
833 833 '/previewApi/onlinePreview?url=' +
834   - encodeURIComponent(Base64.encode(item.url)),
  834 + encodeURIComponent(Base64.encode(item.url)),
835 835 );
836 836 }}
837 837 onCancel={() => {
... ... @@ -903,7 +903,7 @@ const OrderPage = () =&gt; {
903 903 </span>
904 904 {(roleCode === 'salesRepresentative' ||
905 905 roleCode === 'salesManager') &&
906   - !optRecord.isCurrentUserOrder ? (
  906 + !optRecord.isCurrentUserOrder ? (
907 907 <span className="text-[#f44e4e]">(非本账号订单)</span>
908 908 ) : (
909 909 ''
... ... @@ -1087,13 +1087,13 @@ const OrderPage = () =&gt; {
1087 1087 <Tooltip
1088 1088 title={
1089 1089 optRecord.invoicingUrgentCause !== null &&
1090   - optRecord.afterInvoicingStatus ===
  1090 + optRecord.afterInvoicingStatus ===
1091 1091 'URGENT_INVOICE_AUDITING'
1092 1092 ? optRecord.invoicingUrgentCause
1093 1093 : enumValueToLabel(
1094   - optRecord.afterInvoicingStatus,
1095   - AFTER_INVOICING_STATUS,
1096   - )
  1094 + optRecord.afterInvoicingStatus,
  1095 + AFTER_INVOICING_STATUS,
  1096 + )
1097 1097 }
1098 1098 >
1099 1099 <Tag
... ... @@ -1124,7 +1124,7 @@ const OrderPage = () =&gt; {
1124 1124 )}
1125 1125  
1126 1126 {(roleCode === 'warehouseKeeper' || roleCode === 'admin') &&
1127   - optRecord.shippingWarehouse !== null ? (
  1127 + optRecord.shippingWarehouse !== null ? (
1128 1128 <div
1129 1129 className="overflow-hidden whitespace-no-wrap overflow-ellipsis"
1130 1130 title={enumValueToLabel(
... ... @@ -1146,7 +1146,7 @@ const OrderPage = () =&gt; {
1146 1146 {/* 生产时间 */}
1147 1147 <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis">
1148 1148 {optRecord.productionStartTime !== null ||
1149   - optRecord.productionEndTime !== null ? (
  1149 + optRecord.productionEndTime !== null ? (
1150 1150 <MyToolTip
1151 1151 title={
1152 1152 formatdate(optRecord.productionStartTime) +
... ... @@ -1176,7 +1176,7 @@ const OrderPage = () =&gt; {
1176 1176 <Tag
1177 1177 color={
1178 1178 optRecord.invoicingTime === null ||
1179   - optRecord.invoicingTime === undefined
  1179 + optRecord.invoicingTime === undefined
1180 1180 ? TAGS_COLOR.get(optRecord.invoicingStatus)
1181 1181 : 'success'
1182 1182 }
... ... @@ -1204,7 +1204,7 @@ const OrderPage = () =&gt; {
1204 1204  
1205 1205 {/**采购是否已下单状态 */}
1206 1206 {optRecord.procureOrderStatus !== null &&
1207   - optRecord.procureOrderStatus !== undefined ? (
  1207 + optRecord.procureOrderStatus !== undefined ? (
1208 1208 <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis">
1209 1209 <Tag color="success">
1210 1210 {enumValueToLabel(
... ... @@ -1220,21 +1220,21 @@ const OrderPage = () =&gt; {
1220 1220 {/* 物流信息 */}
1221 1221 <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis">
1222 1222 {optRecord.orderStatus === 'CONFIRM_RECEIPT' ||
1223   - optRecord.orderStatus === 'AFTER_SALES_COMPLETION' ||
1224   - optRecord.orderStatus === 'IN_AFTER_SALES' ||
1225   - optRecord.orderStatus === 'SHIPPED' ? (
  1223 + optRecord.orderStatus === 'AFTER_SALES_COMPLETION' ||
  1224 + optRecord.orderStatus === 'IN_AFTER_SALES' ||
  1225 + optRecord.orderStatus === 'SHIPPED' ? (
1226 1226 <MyToolTip
1227 1227 title={
1228 1228 optRecord.serialNumber === undefined
1229 1229 ? '暂无物流信息'
1230 1230 : enumValueToLabel(
1231   - optRecord.logisticsMethod,
1232   - LOGISTICS_STATUS_OPTIONS,
1233   - ) +
1234   - ' ' +
1235   - optRecord.serialNumber +
1236   - ' ' +
1237   - optRecord.logisticsNotes
  1231 + optRecord.logisticsMethod,
  1232 + LOGISTICS_STATUS_OPTIONS,
  1233 + ) +
  1234 + ' ' +
  1235 + optRecord.serialNumber +
  1236 + ' ' +
  1237 + optRecord.logisticsNotes
1238 1238 }
1239 1239 content={
1240 1240 <Button type="link" size="small" style={{ padding: 0 }}>
... ... @@ -1248,7 +1248,7 @@ const OrderPage = () =&gt; {
1248 1248  
1249 1249 {/* 修改审核状态 */}
1250 1250 {optRecord.modifiedAuditStatus !== null &&
1251   - optRecord.modifiedAuditStatus !== 'AUDIT_FAILURE' ? (
  1251 + optRecord.modifiedAuditStatus !== 'AUDIT_FAILURE' ? (
1252 1252 <div className="overflow-hidden whitespace-no-wrap overflow-ellipsis">
1253 1253 <Tooltip
1254 1254 title={recordOptNode ? recordOptNode : <Spin />}
... ... @@ -1688,7 +1688,7 @@ const OrderPage = () =&gt; {
1688 1688 )}
1689 1689  
1690 1690 {optRecord.paths?.includes('queryAnnex') &&
1691   - optRecord.listAnnex?.length > 0 ? (
  1691 + optRecord.listAnnex?.length > 0 ? (
1692 1692 <Button
1693 1693 className="p-0"
1694 1694 type="link"
... ... @@ -2141,7 +2141,7 @@ const OrderPage = () =&gt; {
2141 2141 </Flex>
2142 2142  
2143 2143 {(isProcure() || isWarehousekeeper() || isSales() || isAdmin()) &&
2144   - !isSupplier() ? (
  2144 + !isSupplier() ? (
2145 2145 <div className="pt-2">
2146 2146 <Flex title={optRecord.supplierName}>
2147 2147 <div>
... ... @@ -2216,7 +2216,7 @@ const OrderPage = () =&gt; {
2216 2216 <span className="text-[#8C8C8C]">
2217 2217 申请开票备注:
2218 2218 {optRecord.applyInvoicingNotes === undefined ||
2219   - optRecord.applyInvoicingNotes === null
  2219 + optRecord.applyInvoicingNotes === null
2220 2220 ? '暂无备注'
2221 2221 : optRecord.applyInvoicingNotes}
2222 2222 </span>
... ... @@ -2244,7 +2244,7 @@ const OrderPage = () =&gt; {
2244 2244 <span className="text-[#8C8C8C] mr-3">
2245 2245 财务审核备注:
2246 2246 {optRecord.checkNotes === undefined ||
2247   - optRecord.checkNotes === null
  2247 + optRecord.checkNotes === null
2248 2248 ? '暂无备注'
2249 2249 : optRecord.checkNotes}
2250 2250 </span>
... ... @@ -2268,7 +2268,7 @@ const OrderPage = () =&gt; {
2268 2268 <span className="text-[#8C8C8C]">
2269 2269 重新开票备注:
2270 2270 {optRecord.reissueNotes === undefined ||
2271   - optRecord.reissueNotes === null
  2271 + optRecord.reissueNotes === null
2272 2272 ? '暂无备注'
2273 2273 : optRecord.reissueNotes}
2274 2274 </span>
... ... @@ -2572,9 +2572,9 @@ const OrderPage = () =&gt; {
2572 2572 <span className="text-slate-700">
2573 2573 {record.receivingCompany !== null
2574 2574 ? enumValueToLabel(
2575   - record.receivingCompany,
2576   - getReceivingCompanyOptions(PAYEE_OPTIONS),
2577   - )
  2575 + record.receivingCompany,
  2576 + getReceivingCompanyOptions(PAYEE_OPTIONS),
  2577 + )
2578 2578 : '暂无'}
2579 2579 </span>
2580 2580 </div>
... ... @@ -3366,9 +3366,9 @@ const OrderPage = () =&gt; {
3366 3366 for (let i = 0; i < selectedSubOrders.length; i++) {
3367 3367 if (
3368 3368 selectedSubOrders[i].invoicingStatus ===
3369   - 'UN_INVOICE' ||
  3369 + 'UN_INVOICE' ||
3370 3370 selectedSubOrders[i].afterInvoicingStatus ===
3371   - 'APPLY_FOR_INVOICING'
  3371 + 'APPLY_FOR_INVOICING'
3372 3372 ) {
3373 3373 message.error(
3374 3374 '请选择需要开票且未申请开票的子订单进行申请',
... ... @@ -3403,9 +3403,9 @@ const OrderPage = () =&gt; {
3403 3403 for (let i = 0; i < selectedSubOrders.length; i++) {
3404 3404 if (
3405 3405 selectedSubOrders[i].invoicingStatus ===
3406   - 'UN_INVOICE' ||
  3406 + 'UN_INVOICE' ||
3407 3407 selectedSubOrders[i].afterInvoicingStatus ===
3408   - 'APPLY_FOR_INVOICING'
  3408 + 'APPLY_FOR_INVOICING'
3409 3409 ) {
3410 3410 message.error(
3411 3411 '请选择需要开票且未申请开票的子订单进行申请',
... ... @@ -3596,13 +3596,13 @@ const OrderPage = () =&gt; {
3596 3596 if (
3597 3597 selectedSubOrders[i].orderStatus !== 'AUDITED' &&
3598 3598 selectedSubOrders[i].orderStatus !==
3599   - 'PROCURE_PROCESS' &&
  3599 + 'PROCURE_PROCESS' &&
3600 3600 selectedSubOrders[i].orderStatus !==
3601   - 'PROCURE_PROCESS_FOR_MINE' &&
  3601 + 'PROCURE_PROCESS_FOR_MINE' &&
3602 3602 selectedSubOrders[i].orderStatus !==
3603   - 'PROCURE_WAIT_SHIP' &&
  3603 + 'PROCURE_WAIT_SHIP' &&
3604 3604 selectedSubOrders[i].orderStatus !==
3605   - 'SUPPLIER_WAIT_SHIP' &&
  3605 + 'SUPPLIER_WAIT_SHIP' &&
3606 3606 selectedSubOrders[i].orderStatus !== 'WAIT_SHIP'
3607 3607 ) {
3608 3608 message.error(
... ... @@ -3688,9 +3688,9 @@ const OrderPage = () =&gt; {
3688 3688 if (
3689 3689 selectedSubOrders[i].orderStatus !== 'UNAUDITED' &&
3690 3690 selectedSubOrders[i].orderStatus !==
3691   - 'FINANCE_PROCESS' &&
  3691 + 'FINANCE_PROCESS' &&
3692 3692 selectedSubOrders[i].orderStatus !==
3693   - 'LEADER_AUDITED'
  3693 + 'LEADER_AUDITED'
3694 3694 ) {
3695 3695 message.error(
3696 3696 '请选择[未审核]、[财务待审核]、[领导已审核]的子订单进行审核',
... ... @@ -3758,9 +3758,9 @@ const OrderPage = () =&gt; {
3758 3758 for (let i = 0; i < selectedSubOrders.length; i++) {
3759 3759 if (
3760 3760 selectedSubOrders[i].orderStatus !==
3761   - 'CONFIRM_RECEIPT' &&
  3761 + 'CONFIRM_RECEIPT' &&
3762 3762 selectedSubOrders[i].orderStatus !==
3763   - 'AFTER_SALES_FAILURE'
  3763 + 'AFTER_SALES_FAILURE'
3764 3764 ) {
3765 3765 message.error('请选择确认收货状态的子订单进行售后');
3766 3766 return;
... ... @@ -4246,7 +4246,7 @@ const OrderPage = () =&gt; {
4246 4246  
4247 4247 const exportMenuProps = {
4248 4248 items: exportItems,
4249   - onClick: () => {},
  4249 + onClick: () => { },
4250 4250 };
4251 4251  
4252 4252 //一键审核按钮配置
... ... @@ -4292,7 +4292,7 @@ const OrderPage = () =&gt; {
4292 4292  
4293 4293 const auditProps = {
4294 4294 items: auditItems,
4295   - onClick: () => {},
  4295 + onClick: () => { },
4296 4296 };
4297 4297  
4298 4298 if (rolePath?.includes('leaderMergeAudit')) {
... ... @@ -4413,8 +4413,8 @@ const OrderPage = () =&gt; {
4413 4413 if (errorIds.size > 0) {
4414 4414 message.error(
4415 4415 '订单号为:' +
4416   - [...errorIds.values()].join(',') +
4417   - '的订单存在不是[申请开票]或者[部分开票]状态的子订单,请检查!',
  4416 + [...errorIds.values()].join(',') +
  4417 + '的订单存在不是[申请开票]或者[部分开票]状态的子订单,请检查!',
4418 4418 );
4419 4419 return;
4420 4420 }
... ...
src/pages/Order/table.less renamed to src/pages/Order/Order/table.less
src/pages/Order/type.d.ts renamed to src/pages/Order/Order/type.d.ts
src/pages/Order/OrderWarning/components/AfterSalesDrawer.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { postServiceOrderApplyAfterSales } from '@/services';
  3 +import { enumToSelect } from '@/utils';
  4 +import {
  5 + DrawerForm,
  6 + ProFormDigit,
  7 + ProFormSelect,
  8 + ProFormTextArea,
  9 + ProFormUploadDragger,
  10 +} from '@ant-design/pro-components';
  11 +import { Form, message } from 'antd';
  12 +import { AFTE_SALES_PLAN_OPTIONS } from '../../constant';
  13 +export default ({ setVisible, mainOrder, subOrders, onClose }) => {
  14 + let subOrderIds = subOrders?.map((item: { id: any }) => {
  15 + return item.id;
  16 + });
  17 +
  18 + let mainOrderId = mainOrder.id;
  19 + const [form] = Form.useForm<{
  20 + afterSalesNotes: string;
  21 + afterSalesPlan: string;
  22 + ids: [];
  23 + totalPayment: number;
  24 + filePaths: any[];
  25 + }>();
  26 +
  27 + return (
  28 + <DrawerForm<{
  29 + afterSalesNotes: string;
  30 + afterSalesPlan: string;
  31 + subOrderIds: [];
  32 + totalPayment: number;
  33 + mainId: number;
  34 + filePaths: any[];
  35 + }>
  36 + title="申请售后"
  37 + open
  38 + resize={{
  39 + onResize() {
  40 + console.log('resize!');
  41 + },
  42 + maxWidth: window.innerWidth * 0.8,
  43 + minWidth: 500,
  44 + }}
  45 + form={form}
  46 + autoFocusFirstInput
  47 + drawerProps={{
  48 + destroyOnClose: true,
  49 + onClose: () => {
  50 + setVisible(false);
  51 + },
  52 + }}
  53 + onFinish={async (values) => {
  54 + values.subOrderIds = subOrderIds;
  55 + values.mainId = mainOrderId;
  56 + values.filePaths = values.filePaths?.map((file) => {
  57 + return { url: file.response.data[0] };
  58 + });
  59 + let res = await postServiceOrderApplyAfterSales({ data: values });
  60 + if (res?.result === RESPONSE_CODE.SUCCESS) {
  61 + message.success(res.message);
  62 + onClose();
  63 + }
  64 + }}
  65 + >
  66 + <ProFormSelect
  67 + key="key"
  68 + label="售后方案"
  69 + width="lg"
  70 + showSearch
  71 + name="afterSalesPlan"
  72 + options={enumToSelect(AFTE_SALES_PLAN_OPTIONS)}
  73 + placeholder="请搜索"
  74 + rules={[{ required: true, message: '售后方案必填' }]}
  75 + ></ProFormSelect>
  76 + <ProFormDigit
  77 + width="lg"
  78 + name="totalPayment"
  79 + label="总金额调整"
  80 + min={0}
  81 + initialValue={mainOrder.totalPayment}
  82 + rules={[{ required: true, message: '总金额必填' }]}
  83 + />
  84 + <ProFormTextArea
  85 + width="lg"
  86 + label="售后原因"
  87 + name="afterSalesNotes"
  88 + rules={[{ required: true, message: '售后原因必填' }]}
  89 + />
  90 + <ProFormUploadDragger
  91 + key="filePaths"
  92 + label="附件"
  93 + name="filePaths"
  94 + action="/api/service/order/fileProcess"
  95 + fieldProps={{
  96 + headers: { Authorization: localStorage.getItem('token') },
  97 + }}
  98 + />
  99 + </DrawerForm>
  100 + );
  101 +};
... ...
src/pages/Order/OrderWarning/components/ApplyForInvoicingModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { postServiceOrderApplyInvoicing } from '@/services';
  3 +import { enumToSelect, getAliYunOSSFileNameFromUrl } from '@/utils';
  4 +import {
  5 + ModalForm,
  6 + ProFormSelect,
  7 + ProFormText,
  8 + ProFormTextArea,
  9 + ProFormUploadDragger,
  10 +} from '@ant-design/pro-components';
  11 +import { Form, message } from 'antd';
  12 +import { useEffect, useState } from 'react';
  13 +import { PAYEE_OPTIONS } from '../../constant';
  14 +export default ({
  15 + setCheckVisible,
  16 + isEdit,
  17 + subOrders,
  18 + isMainOrder,
  19 + totalPayment,
  20 + onClose,
  21 +}) => {
  22 + const [isUrgent, setIsUrgent] = useState('');
  23 + let sumPrice = totalPayment;
  24 +
  25 + let ids = subOrders?.map((item) => {
  26 + return item.id;
  27 + });
  28 +
  29 + let mainIdSet = new Set();
  30 + subOrders?.forEach((item: { mainOrderId: unknown }) => {
  31 + mainIdSet.add(item.mainOrderId);
  32 + });
  33 +
  34 + let mainIds = Array.from(mainIdSet).join(',');
  35 +
  36 + let newListAnnex = [];
  37 +
  38 + //回显,子订单可以编辑备注跟附件
  39 + if (isEdit) {
  40 + newListAnnex = subOrders.afterAnnexList?.map((path) => {
  41 + let i = 0;
  42 + return {
  43 + uid: i++,
  44 + name: getAliYunOSSFileNameFromUrl(path),
  45 + status: 'uploaded',
  46 + url: path,
  47 + response: { data: [path] },
  48 + };
  49 + });
  50 + subOrders.filePaths = newListAnnex;
  51 + }
  52 +
  53 + const [form] = Form.useForm<{
  54 + applyInvoicingNotes: string;
  55 + filePaths: any;
  56 + subIds: any[];
  57 + afterInvoicingUpdate: boolean;
  58 + receivingCompany: string;
  59 + isUrgent: boolean;
  60 + deadline: string;
  61 + }>();
  62 +
  63 + useEffect(() => {
  64 + //显示拼接的主订单id
  65 + form.setFieldValue('applyInvoicingNotes', mainIds);
  66 + }, []);
  67 +
  68 + return (
  69 + <ModalForm<{
  70 + applyInvoicingNotes: string;
  71 + filePaths: any;
  72 + subIds: any[];
  73 + afterInvoicingUpdate: boolean;
  74 + }>
  75 + width={500}
  76 + open
  77 + title={isEdit ? '修改信息' : '申请开票'}
  78 + initialValues={subOrders}
  79 + form={form}
  80 + autoFocusFirstInput
  81 + modalProps={{
  82 + okText: '确认',
  83 + cancelText: '取消',
  84 + destroyOnClose: true,
  85 + onCancel: () => {
  86 + setCheckVisible(false);
  87 + },
  88 + }}
  89 + submitter={{
  90 + render: (props, defaultDoms) => {
  91 + return defaultDoms;
  92 + },
  93 + }}
  94 + submitTimeout={2000}
  95 + onFinish={async (values) => {
  96 + values.subIds = ids;
  97 + //附件处理
  98 + values.filePaths = values.filePaths?.map((item) => {
  99 + return { url: item.response.data[0] };
  100 + });
  101 +
  102 + if (isEdit) {
  103 + values.afterInvoicingUpdate = true;
  104 + } else {
  105 + values.afterInvoicingUpdate = false;
  106 + }
  107 +
  108 + const res = await postServiceOrderApplyInvoicing({ data: values });
  109 +
  110 + if (res.result === RESPONSE_CODE.SUCCESS) {
  111 + message.success(res.message);
  112 + onClose();
  113 + }
  114 + }}
  115 + onOpenChange={setCheckVisible}
  116 + >
  117 + {isMainOrder ? (
  118 + <div className="mb-[24px]">
  119 + <span>选中子订单金额之和:</span>
  120 + <span className="text-red-500">{sumPrice}¥</span>
  121 + </div>
  122 + ) : (
  123 + ''
  124 + )}
  125 +
  126 + <div className="mb-1">
  127 + 如果需要合并订单,请将需要合并的订单id写在备注中,id之间用英文逗号隔开。
  128 + </div>
  129 + <ProFormTextArea
  130 + width="lg"
  131 + name="applyInvoicingNotes"
  132 + key="applyInvoicingNotes"
  133 + placeholder="请输入备注"
  134 + onMetaChange={(val) => {
  135 + console.log(val);
  136 + }}
  137 + proFieldProps={{
  138 + onchange: () => {
  139 + message.info('change');
  140 + },
  141 + }}
  142 + />
  143 + <ProFormText
  144 + width="lg"
  145 + name="purchaser"
  146 + label="抬头名称"
  147 + key="purchaser"
  148 + placeholder="请输入抬头名称"
  149 + rules={[{ required: true, message: '抬头名称必填' }]}
  150 + />
  151 + <ProFormSelect
  152 + placeholder="选择收款单位"
  153 + name="receivingCompany"
  154 + width="lg"
  155 + key="receivingCompany"
  156 + label={
  157 + <div>
  158 + <span>开票收款单位</span>
  159 + <span className="pl-2 text-xs text-gray-400">
  160 + 财务开票将依据这个字段,选择对应的公司开票(若对[收款单位]没有要求,请任意选择一个)
  161 + </span>
  162 + </div>
  163 + }
  164 + options={enumToSelect(PAYEE_OPTIONS)}
  165 + rules={[{ required: true, message: '开票收款单位必填' }]}
  166 + />
  167 + <ProFormSelect
  168 + placeholder="选择是否加急"
  169 + name="isUrgent"
  170 + width="lg"
  171 + key="isUrgent"
  172 + label="是否加急"
  173 + options={[
  174 + { label: '是', value: 'true' },
  175 + { label: '否', value: 'false' },
  176 + ]}
  177 + rules={[{ required: true, message: '是否加急必填' }]}
  178 + onChange={(val: any) => {
  179 + setIsUrgent(val);
  180 + }}
  181 + />
  182 +
  183 + {/* <ProFormDatePicker
  184 + key="deadline"
  185 + label="期望开票时间"
  186 + name="deadline"
  187 + rules={[{ required: isUrgent === 'true', message: '期望开票时间必填' }]}
  188 + hidden={isUrgent !== 'true'}
  189 + /> */}
  190 +
  191 + <ProFormTextArea
  192 + key="invoicingUrgentCause"
  193 + label="加急开票原因"
  194 + name="invoicingUrgentCause"
  195 + rules={[{ required: isUrgent === 'true', message: '加急开票原因' }]}
  196 + hidden={isUrgent !== 'true'}
  197 + />
  198 +
  199 + <ProFormUploadDragger
  200 + key="2"
  201 + label={
  202 + <div>
  203 + <span>开票明细确认表</span>
  204 + <span className="pl-2 text-xs text-gray-400">
  205 + 如果开票信息有变更,如开票内容跟下单内容不一致、下单抬头和付款抬头不一致,请上传开票明细确认表。
  206 + </span>
  207 + </div>
  208 + }
  209 + name="filePaths"
  210 + action="/api/service/order/fileProcess"
  211 + fieldProps={{
  212 + headers: { Authorization: localStorage.getItem('token') },
  213 + }}
  214 + />
  215 + </ModalForm>
  216 + );
  217 +};
... ...
src/pages/Order/OrderWarning/components/AttachmentModal.tsx 0 → 100644
  1 +import { getAliYunOSSFileNameFromUrl, isImageName } from '@/utils';
  2 +import { ModalForm } from '@ant-design/pro-components';
  3 +import { Button, Card, Divider, Empty, Form, Image, List, message } from 'antd';
  4 +import Base64 from 'base-64';
  5 +import { cloneDeep } from 'lodash';
  6 +import React, { useEffect, useState } from 'react';
  7 +
  8 +export default ({ data, onClose }) => {
  9 + let newData = cloneDeep(data);
  10 + const [fileList, setFileList] = useState<[]>([]);
  11 + console.log(fileList);
  12 + const [form] = Form.useForm<{
  13 + subOrderId: '';
  14 + listAnnex: [];
  15 + }>();
  16 +
  17 + let newListAnnex = newData.listAnnex?.map((path) => {
  18 + let i = 0;
  19 + return {
  20 + uid: i++,
  21 + name: getAliYunOSSFileNameFromUrl(path),
  22 + status: 'uploaded',
  23 + url: path,
  24 + response: { data: [path] },
  25 + };
  26 + });
  27 + newData.listAnnex = newListAnnex;
  28 +
  29 + //将图片和其他文件区分开
  30 + let images: any[] = [];
  31 + let otherAnnex: any[] = [];
  32 + newListAnnex.forEach((item: any) => {
  33 + if (isImageName(item.name)) {
  34 + images.push(item);
  35 + } else {
  36 + otherAnnex.push(item);
  37 + }
  38 + });
  39 +
  40 + useEffect(() => {
  41 + setFileList(newData.listAnnex);
  42 + }, []);
  43 +
  44 + return (
  45 + <ModalForm
  46 + width={800}
  47 + open
  48 + title="查看附件"
  49 + initialValues={newData}
  50 + form={form}
  51 + modalProps={{
  52 + onCancel: onClose,
  53 + }}
  54 + submitter={{
  55 + render: () => {
  56 + return [
  57 + <Button
  58 + key="back"
  59 + onClick={() => {
  60 + onClose();
  61 + }}
  62 + >
  63 + 返回
  64 + </Button>,
  65 + ];
  66 + },
  67 + }}
  68 + >
  69 + {newListAnnex?.length <= 0 ? (
  70 + <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  71 + ) : (
  72 + // <ProFormUploadDragger
  73 + // name="listAnnex"
  74 + // action="/api/service/order/fileProcess"
  75 + // disabled
  76 + // fieldProps={{
  77 + // headers: { Authorization: localStorage.getItem('token') },
  78 + // // onRemove: (file) => {
  79 + // // const index = fileList[listMeta.index].indexOf(file);
  80 + // // console.log(index);
  81 + // // const newFileList = fileList.slice();
  82 + // // newFileList.splice(index, 1);
  83 + // // setFileList(newFileList);
  84 + // // },
  85 + // // beforeUpload: (file) => {
  86 + // // fileList[listMeta.index] = [...fileList[listMeta.index], file as RcFile];
  87 + // // setFileList(fileList);
  88 + // // return true;
  89 + // // },
  90 + // fileList,
  91 + // // defaultFileList: itemFileList
  92 + // }}
  93 + // />
  94 + <>
  95 + <Card>
  96 + <Image.PreviewGroup
  97 + className="mr-10"
  98 + preview={{
  99 + onChange: (current, prev) =>
  100 + console.log(`current index: ${current}, prev index: ${prev}`),
  101 + }}
  102 + >
  103 + {images.map((item, index) => (
  104 + <React.Fragment key={index}>
  105 + <Image
  106 + className="max-h-[200px] max-w-[200px]"
  107 + src={item.url}
  108 + title={item.name}
  109 + />{' '}
  110 + <Divider type="vertical" />
  111 + </React.Fragment>
  112 + ))}
  113 + </Image.PreviewGroup>
  114 + </Card>
  115 + <Divider />
  116 +
  117 + <div>
  118 + <List
  119 + size="small"
  120 + header={<div>其他类型文件</div>}
  121 + bordered
  122 + dataSource={otherAnnex}
  123 + renderItem={(item) => (
  124 + <List.Item
  125 + actions={[
  126 + <Button
  127 + type="link"
  128 + key="key"
  129 + href={item.url}
  130 + target="blank"
  131 + className="py-1"
  132 + >
  133 + 下载
  134 + </Button>,
  135 + <Button
  136 + type="link"
  137 + key="key"
  138 + className="py-1"
  139 + onClick={() => {
  140 + message.info(item.url);
  141 + window.open(
  142 + '/previewApi/onlinePreview?url=' +
  143 + encodeURIComponent(Base64.encode(item.url)),
  144 + );
  145 + }}
  146 + >
  147 + 预览
  148 + </Button>,
  149 + ]}
  150 + >
  151 + <div>
  152 + <span>{item.name}</span>
  153 + </div>
  154 + </List.Item>
  155 + )}
  156 + />
  157 + </div>
  158 + </>
  159 + )}
  160 + </ModalForm>
  161 + );
  162 +};
... ...
src/pages/Order/OrderWarning/components/BaseModal.tsx 0 → 100644
  1 +import { ModalForm } from '@ant-design/pro-components';
  2 +import { Form } from 'antd';
  3 +
  4 +// import { cloneDeep } from 'lodash';
  5 +export default ({ setVisible, onClose }) => {
  6 + const [form] = Form.useForm<{ name: string; company: string }>();
  7 +
  8 + return (
  9 + <>
  10 + <ModalForm<{
  11 + name: string;
  12 + company: string;
  13 + }>
  14 + width={500}
  15 + open
  16 + title="标题"
  17 + form={form}
  18 + autoFocusFirstInput
  19 + modalProps={{
  20 + okText: '通过',
  21 + cancelText: '取消',
  22 + destroyOnClose: true,
  23 + onCancel: () => {
  24 + setVisible(false);
  25 + },
  26 + }}
  27 + onFinish={async (values) => {
  28 + console.log(values);
  29 + onClose();
  30 + }}
  31 + onOpenChange={setVisible}
  32 + ></ModalForm>
  33 + </>
  34 + );
  35 +};
... ...
src/pages/Order/OrderWarning/components/CheckModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postPrepaidAudit,
  4 + postServiceOrderAfterSalesCheck,
  5 + postServiceOrderAudit,
  6 + postServiceOrderFileProcess,
  7 + postServiceOrderFinanceCheckOrder,
  8 + postServiceOrderLeaderAudit,
  9 + postServiceOrderToProcureAudit,
  10 +} from '@/services';
  11 +import {
  12 + ModalForm,
  13 + ProFormTextArea,
  14 + ProList,
  15 +} from '@ant-design/pro-components';
  16 +import {
  17 + Button,
  18 + Col,
  19 + Divider,
  20 + Form,
  21 + Image,
  22 + Modal,
  23 + Row,
  24 + Space,
  25 + Tag,
  26 + UploadFile,
  27 + message,
  28 +} from 'antd';
  29 +import Upload, { RcFile, UploadProps } from 'antd/es/upload';
  30 +import { useEffect, useRef, useState } from 'react';
  31 +import {
  32 + AFTE_SALES_PLAN_OPTIONS,
  33 + CHECK_TYPE,
  34 + COMFIR_RECEIPT_IMAGES_NUMBER,
  35 +} from '../../constant';
  36 +// import { cloneDeep } from 'lodash';
  37 +import InvoiceSubOrderInfoTable from '@/pages/Order/Order/components/InvoiceSubOrderInfoTable';
  38 +import { enumValueToLabel, transImageFile } from '@/utils';
  39 +import { PlusOutlined } from '@ant-design/icons';
  40 +import { cloneDeep } from 'lodash';
  41 +
  42 +export default ({
  43 + setCheckVisible,
  44 + data,
  45 + subOrders,
  46 + orderCheckType,
  47 + openOrderDrawer,
  48 + onClose,
  49 +}) => {
  50 + const [previewOpen, setPreviewOpen] = useState(false);
  51 + const [aPopoverTitle, setAPopoverTitle] = useState('审核');
  52 + const [previewImage, setPreviewImage] = useState('');
  53 + const [previewTitle, setPreviewTitle] = useState('');
  54 + const [paymentReceiptsImages, setPymentReceiptsImages] = useState<any[]>([]);
  55 + const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致
  56 + const getBase64 = (file: RcFile): Promise<string> =>
  57 + new Promise((resolve, reject) => {
  58 + const reader = new FileReader();
  59 + reader.readAsDataURL(file);
  60 + reader.onload = () => resolve(reader.result as string);
  61 + reader.onerror = (error) => reject(error);
  62 + });
  63 + const [fileList, setFileList] = useState<UploadFile[]>([]);
  64 + const handleCancel = () => setPreviewOpen(false);
  65 + const [messageApi, contextHolder] = message.useMessage();
  66 + const [form] = Form.useForm<{ name: string; company: string }>();
  67 + let subOrderIds: any[] = subOrders?.map((subOrder) => subOrder.id);
  68 + const [mainOrderId] = useState(data.id);
  69 +
  70 + const [afterSalesInfo, setAfterSalesInfo] = useState<any>();
  71 + const [prepaidProofImages, setPrepaidProofImages] = useState<any[]>([]);
  72 + /**
  73 + * 审核类型
  74 + */
  75 + function checkType(check: string) {
  76 + if (orderCheckType === check) {
  77 + return true;
  78 + }
  79 + return false;
  80 + }
  81 +
  82 + const getOrderAfterSalesInfo = async () => {
  83 + // let res = await postServiceOrderQueryAfterSalesInfoSnapshot({
  84 + // data: { subOrderIds: subOrderIds },
  85 + // });
  86 +
  87 + //附件
  88 + let annex = subOrders[0].afterSalesAnnexList;
  89 + let index = 1;
  90 + let annexLinks = annex?.map((f) => {
  91 + return (
  92 + <Button className="p-0 pr-1" type="link" key="key" href={f}>
  93 + {'附件' + index++}
  94 + </Button>
  95 + );
  96 + });
  97 +
  98 + console.log(annexLinks);
  99 +
  100 + setAfterSalesInfo(
  101 + <div className="my-5">
  102 + <Row gutter={[16, 24]}>
  103 + <Col span={6}>
  104 + <span className="text-[#333333]">售后方案</span>
  105 + </Col>
  106 + <Col span={18}>
  107 + {enumValueToLabel(
  108 + subOrders[0]?.afterSalesPlan,
  109 + AFTE_SALES_PLAN_OPTIONS,
  110 + )}
  111 + </Col>
  112 + <Col span={6}>
  113 + <span className="className='text-[#333333]'">售后原因</span>
  114 + </Col>
  115 + <Col span={18}>{subOrders[0]?.afterSalesNotes}</Col>
  116 + <Col span={6}>
  117 + <span className="className='text-[#333333]'">附件</span>
  118 + </Col>
  119 + <Col span={18}>{annexLinks}</Col>
  120 + </Row>
  121 + </div>,
  122 + );
  123 + };
  124 +
  125 + useEffect(() => {
  126 + if (checkType(CHECK_TYPE.CONFIRM_DELIVER)) {
  127 + setAPopoverTitle('确认发货');
  128 + }
  129 + getOrderAfterSalesInfo();
  130 +
  131 + let paymentReceiptsImagesList: any[] = [];
  132 + subOrders?.forEach((item: any) => {
  133 + if (item.paymentReceiptAnnexList) {
  134 + paymentReceiptsImagesList.push(...item.paymentReceiptAnnexList);
  135 + }
  136 + });
  137 + //去重
  138 + paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)];
  139 + setPymentReceiptsImages(paymentReceiptsImagesList);
  140 +
  141 + //预存审核的凭证
  142 + let proofImages: any[] = [];
  143 + subOrders?.forEach((item) => {
  144 + let images = item.proofImages;
  145 + if (images !== null && images !== undefined) {
  146 + proofImages.push(...images);
  147 + }
  148 + });
  149 + setPrepaidProofImages(proofImages);
  150 + }, []);
  151 +
  152 + const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
  153 + //fileListObj得在change里变化,change的参数是已经处理过的file数组
  154 + //beforeUpload中的参数file是未处理过,还需要Base64拿到文件数据处理
  155 + fileListObj.current = newFileList;
  156 + setFileList(newFileList);
  157 + };
  158 +
  159 + /** 粘贴快捷键的回调 */
  160 + const onPaste = async (e: any) => {
  161 + /** 获取剪切板的数据clipboardData */
  162 + let clipboardData = e.clipboardData,
  163 + i = 0,
  164 + items,
  165 + item,
  166 + types;
  167 +
  168 + /** 为空判断 */
  169 + if (clipboardData) {
  170 + items = clipboardData.items;
  171 + if (!items) {
  172 + message.info('您的剪贴板中没有照片');
  173 + return;
  174 + }
  175 +
  176 + item = items[0];
  177 + types = clipboardData.types || [];
  178 + /** 遍历剪切板的数据 */
  179 + for (; i < types.length; i++) {
  180 + if (types[i] === 'Files') {
  181 + item = items[i];
  182 + break;
  183 + }
  184 + }
  185 +
  186 + /** 判断文件是否为图片 */
  187 + if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
  188 + const imgItem = item.getAsFile();
  189 + const newFileList = cloneDeep(fileListObj.current);
  190 + let filteredArray = newFileList.filter(
  191 + (obj) => obj.status !== 'removed',
  192 + ); //过滤掉状态为已删除的照片
  193 + const listItem = {
  194 + ...imgItem,
  195 + status: 'done',
  196 + url: await getBase64(imgItem),
  197 + originFileObj: imgItem,
  198 + };
  199 +
  200 + if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) {
  201 + message.info('发货照片数量不能超过3');
  202 + return;
  203 + }
  204 + fileListObj.current = filteredArray;
  205 + filteredArray.push(listItem);
  206 + setFileList(filteredArray);
  207 + return;
  208 + }
  209 + }
  210 +
  211 + message.info('您的剪贴板中没有照片');
  212 + };
  213 + useEffect(() => {
  214 + //回显售后信息
  215 + // if (checkType(CHECK_TYPE.AFTER_SALES)) {
  216 + // getOrderAfterSalesInfo();
  217 + // }
  218 +
  219 + document.addEventListener('paste', onPaste);
  220 + return () => {
  221 + document.removeEventListener('paste', onPaste);
  222 + };
  223 + }, []);
  224 + const uploadButton = (
  225 + <div>
  226 + <PlusOutlined />
  227 + <div style={{ marginTop: 8 }}>上传凭证</div>
  228 + </div>
  229 + );
  230 + const handlePreview = async (file: UploadFile) => {
  231 + if (!file.url && !file.preview) {
  232 + file.preview = await getBase64(file.originFileObj as RcFile);
  233 + }
  234 + setPreviewImage(file.url || (file.preview as string));
  235 + setPreviewOpen(true);
  236 + setPreviewTitle(
  237 + file.name ||
  238 + file.originFileObj?.name ||
  239 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
  240 + );
  241 + };
  242 +
  243 + const handleBeforeUpload = (file: any) => {
  244 + setFileList([...fileList, file]);
  245 + return false;
  246 + };
  247 +
  248 + const props: UploadProps = {
  249 + onRemove: (file) => {
  250 + const index = fileList.indexOf(file);
  251 + const newFileList = fileList.slice();
  252 + newFileList.splice(index, 1);
  253 + setFileList(newFileList);
  254 + },
  255 + beforeUpload: handleBeforeUpload,
  256 + listType: 'picture-card',
  257 + onPreview: handlePreview,
  258 + fileList,
  259 + onChange: handleChange,
  260 + accept: 'image/png, image/jpeg, image/png',
  261 + // action: '/api/service/order/fileProcess',
  262 + name: 'files',
  263 + headers: { Authorization: localStorage.getItem('token') },
  264 + };
  265 +
  266 + //仓库审核
  267 + async function doCheck(body: object) {
  268 + const data = await postServiceOrderAudit({
  269 + data: body,
  270 + });
  271 + if (data.result === RESPONSE_CODE.SUCCESS) {
  272 + message.success(data.message);
  273 + onClose();
  274 + }
  275 + }
  276 +
  277 + /**
  278 + *
  279 + * @param body 财务审核
  280 + */
  281 + async function doFinancailCheck(values: any, isAgree: boolean) {
  282 + if (fileList.length <= 0) {
  283 + message.error('凭证不能为空');
  284 + return;
  285 + }
  286 + messageApi.open({
  287 + type: 'loading',
  288 + content: '正在上传图片...',
  289 + duration: 0,
  290 + });
  291 + //附件处理
  292 + let formData = new FormData();
  293 + //附件处理
  294 + for (let file of fileList) {
  295 + if (file.originFileObj) {
  296 + formData.append('files', file.originFileObj as RcFile);
  297 + } else {
  298 + //有url的话取url(源文件),没url取thumbUrl。有url的时候thumbUrl是略缩图
  299 + if (file?.url === undefined || file?.url === null) {
  300 + formData.append(
  301 + 'files',
  302 + transImageFile(file?.thumbUrl),
  303 + file?.originFileObj?.name,
  304 + );
  305 + } else {
  306 + formData.append(
  307 + 'files',
  308 + transImageFile(file?.url),
  309 + file?.originFileObj?.name,
  310 + );
  311 + }
  312 + }
  313 + }
  314 + let res = await postServiceOrderFileProcess({
  315 + data: formData,
  316 + });
  317 + messageApi.destroy();
  318 + if (res.result === RESPONSE_CODE.SUCCESS) {
  319 + message.success('上传成功!');
  320 +
  321 + let fileUrls = res?.data?.map((item) => {
  322 + return { url: item };
  323 + });
  324 + //财务审核
  325 + const data = await postServiceOrderFinanceCheckOrder({
  326 + data: {
  327 + checkNotes: values.name,
  328 + ids: subOrderIds,
  329 + checkPassOrReject: isAgree,
  330 + invoicingCheckAnnex: fileUrls,
  331 + },
  332 + });
  333 + if (data.result === RESPONSE_CODE.SUCCESS) {
  334 + message.success(data.message);
  335 + onClose();
  336 + }
  337 + } else {
  338 + message.success('上传失败');
  339 + }
  340 + }
  341 +
  342 + /**
  343 + *
  344 + * @param body 售后审核
  345 + */
  346 + async function doAfterSalesCheck(body: object) {
  347 + const data = await postServiceOrderAfterSalesCheck({
  348 + data: body,
  349 + });
  350 + if (data.result === RESPONSE_CODE.SUCCESS) {
  351 + message.success(data.message);
  352 + onClose();
  353 + }
  354 + }
  355 +
  356 + /**
  357 + *
  358 + * @param body 领导审核
  359 + */
  360 + async function doLeaderCheck(body: object) {
  361 + const data = await postServiceOrderLeaderAudit({
  362 + data: body,
  363 + });
  364 + if (data.result === RESPONSE_CODE.SUCCESS) {
  365 + message.success(data.message);
  366 + onClose();
  367 + }
  368 + }
  369 +
  370 + /**
  371 + * 预存审核
  372 + * @param body
  373 + */
  374 + async function doPrepaidAudit(body: any) {
  375 + const data = await postPrepaidAudit({
  376 + data: body,
  377 + });
  378 + if (data.result === RESPONSE_CODE.SUCCESS) {
  379 + message.success(data.message);
  380 + onClose();
  381 + }
  382 + }
  383 +
  384 + function computeType() {
  385 + let type: string = '';
  386 + if (checkType(CHECK_TYPE.CONFIRM_DELIVER)) {
  387 + type = 'confirm_deliver';
  388 + }
  389 + if (checkType(CHECK_TYPE.WEARHOUSE_KEEPER)) {
  390 + type = 'warehouse_audit';
  391 + }
  392 + if (checkType(CHECK_TYPE.WAITING_FOR_POST_AUDIT)) {
  393 + type = 'post_audit';
  394 + }
  395 + if (checkType(CHECK_TYPE.NODE_OPERATING_AUDIT)) {
  396 + type = 'node_operating_audit';
  397 + }
  398 + if (checkType(CHECK_TYPE.MODIFY_LEADER_AUDIT)) {
  399 + type = 'modify_leader_audit';
  400 + }
  401 + if (checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING)) {
  402 + type = 'urgent_invoice_audit';
  403 + }
  404 + if (checkType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT)) {
  405 + type = 'payment_receipt_audit';
  406 + }
  407 + if (checkType(CHECK_TYPE.CONFIRM_REISSUE)) {
  408 + type = 'confirm_reissue';
  409 + }
  410 + if (checkType(CHECK_TYPE.CREDIT_AUDIT)) {
  411 + type = 'credit_audit';
  412 + }
  413 + if (checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING_OLD)) {
  414 + type = 'urgent_invoice_audit_old';
  415 + }
  416 + if (checkType(CHECK_TYPE.CONFIRM_REISSUE_OLD)) {
  417 + type = 'confirm_reissue_old';
  418 + }
  419 + return type;
  420 + }
  421 +
  422 + return (
  423 + <>
  424 + <ModalForm<{
  425 + name: string;
  426 + company: string;
  427 + }>
  428 + width={500}
  429 + open
  430 + title={aPopoverTitle}
  431 + form={form}
  432 + autoFocusFirstInput
  433 + modalProps={{
  434 + okText: '通过',
  435 + cancelText: '驳回',
  436 + destroyOnClose: true,
  437 + onCancel: () => {
  438 + setCheckVisible(false);
  439 + },
  440 + }}
  441 + submitter={{
  442 + render: (props, defaultDoms) => {
  443 + let myDoms = [];
  444 + if (!checkType(CHECK_TYPE.CONFIRM_DELIVER)) {
  445 + myDoms.push(
  446 + <Button
  447 + key="驳回"
  448 + onClick={async () => {
  449 + if (checkType(CHECK_TYPE.AFTER_SALES)) {
  450 + doAfterSalesCheck({
  451 + applyType: 'after-sales',
  452 + isAfterSalesSuccess: false,
  453 + subOrderIds: subOrderIds,
  454 + mainId: mainOrderId,
  455 + afterSalesRejectionNotes: form.getFieldValue('name'),
  456 + });
  457 + return;
  458 + }
  459 +
  460 + if (checkType(CHECK_TYPE.FINALCIAL)) {
  461 + let values = { name: form.getFieldValue('name') };
  462 + doFinancailCheck(values, false);
  463 + return;
  464 + }
  465 +
  466 + if (checkType(CHECK_TYPE.LEADER_AUDIT)) {
  467 + doLeaderCheck({
  468 + pass: false,
  469 + subOrderIds: subOrderIds,
  470 + reason: form.getFieldValue('name'),
  471 + });
  472 + return;
  473 + }
  474 +
  475 + if (checkType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT)) {
  476 + doAfterSalesCheck({
  477 + applyType: 'order-change-normal',
  478 + isAfterSalesSuccess: false,
  479 + subOrderIds: subOrderIds,
  480 + mainId: mainOrderId,
  481 + afterSalesRejectionNotes: form.getFieldValue('name'),
  482 + });
  483 + return;
  484 + }
  485 +
  486 + //预存审核,先暂时共用同一个审核弹窗
  487 + if (checkType(CHECK_TYPE.PREPAID_AUDIT)) {
  488 + return doPrepaidAudit({
  489 + pass: false,
  490 + ids: subOrderIds,
  491 + auditNotes: form.getFieldValue('name'),
  492 + });
  493 + }
  494 +
  495 + let type = '';
  496 + type = computeType();
  497 + console.log('type:' + type);
  498 + doCheck({
  499 + pass: false,
  500 + subOrderIds: subOrderIds,
  501 + type: type,
  502 + notes: form.getFieldValue('name'),
  503 + });
  504 + }}
  505 + >
  506 + 驳回
  507 + </Button>,
  508 + );
  509 + }
  510 +
  511 + //如果是仓库审核,那么显示这个外部采购
  512 + if (checkType(CHECK_TYPE.WEARHOUSE_KEEPER)) {
  513 + myDoms.push(
  514 + <Button
  515 + key="外部采购"
  516 + onClick={async () => {
  517 + let res = await postServiceOrderToProcureAudit({
  518 + data: {
  519 + subOrderIds: subOrderIds,
  520 + },
  521 + });
  522 +
  523 + if (res && res.result === RESPONSE_CODE.SUCCESS) {
  524 + message.success(res.message);
  525 + onClose();
  526 + }
  527 + }}
  528 + >
  529 + 外部采购
  530 + </Button>,
  531 + );
  532 + }
  533 +
  534 + //确认
  535 + myDoms.push(defaultDoms[1]);
  536 + return myDoms;
  537 + },
  538 + }}
  539 + submitTimeout={2000}
  540 + onFinish={async (values) => {
  541 + if (checkType(CHECK_TYPE.AFTER_SALES)) {
  542 + //审核通过
  543 + return doAfterSalesCheck({
  544 + applyType: 'after-sales',
  545 + isAfterSalesSuccess: true,
  546 + subOrderIds: subOrderIds,
  547 + mainId: mainOrderId,
  548 + afterSalesRejectionNotes: values.name,
  549 + });
  550 + }
  551 + console.log('h');
  552 + if (checkType(CHECK_TYPE.FINALCIAL)) {
  553 + doFinancailCheck(values, true);
  554 + return;
  555 + }
  556 +
  557 + if (checkType(CHECK_TYPE.LEADER_AUDIT)) {
  558 + doLeaderCheck({
  559 + pass: true,
  560 + subOrderIds: subOrderIds,
  561 + reason: values.name,
  562 + });
  563 + return;
  564 + }
  565 +
  566 + if (checkType(CHECK_TYPE.MODIFY_APPLY_WAIT_FOR_AUDIT)) {
  567 + //审核通过
  568 + return doAfterSalesCheck({
  569 + applyType: 'order-change-normal',
  570 + isAfterSalesSuccess: true,
  571 + subOrderIds: subOrderIds,
  572 + mainId: mainOrderId,
  573 + afterSalesRejectionNotes: values.name,
  574 + });
  575 + }
  576 +
  577 + //预存审核,先暂时共用同一个审核弹窗
  578 + if (checkType(CHECK_TYPE.PREPAID_AUDIT)) {
  579 + return doPrepaidAudit({
  580 + pass: true,
  581 + ids: subOrderIds,
  582 + auditNotes: form.getFieldValue('name'),
  583 + });
  584 + }
  585 +
  586 + let type = '';
  587 + type = computeType();
  588 + doCheck({
  589 + pass: true,
  590 + subOrderIds: subOrderIds,
  591 + type: type,
  592 + notes: form.getFieldValue('name'),
  593 + });
  594 + }}
  595 + onOpenChange={setCheckVisible}
  596 + >
  597 + {checkType(CHECK_TYPE.AFTER_SALES) ? (
  598 + <>
  599 + {afterSalesInfo}
  600 + <Button
  601 + className="px-0"
  602 + type="link"
  603 + onClick={() => {
  604 + console.log(data);
  605 + openOrderDrawer('after-sales-check', mainOrderId);
  606 + }}
  607 + >
  608 + 查看旧订单
  609 + </Button>
  610 + </>
  611 + ) : (
  612 + ''
  613 + )}
  614 +
  615 + {checkType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT) ? (
  616 + <>
  617 + <Divider orientation="center">
  618 + <span className="text-sm">回款凭证</span>
  619 + </Divider>
  620 + <Image.PreviewGroup
  621 + className="mr-10"
  622 + preview={{
  623 + onChange: (current, prev) =>
  624 + console.log(`current index: ${current}, prev index: ${prev}`),
  625 + }}
  626 + >
  627 + {paymentReceiptsImages.map((url) => (
  628 + <>
  629 + <Image width={120} src={url} /> <Divider type="vertical" />
  630 + </>
  631 + ))}
  632 + </Image.PreviewGroup>
  633 + <Divider></Divider>
  634 + </>
  635 + ) : (
  636 + ''
  637 + )}
  638 +
  639 + {checkType(CHECK_TYPE.PREPAID_AUDIT) && (
  640 + <>
  641 + <Divider orientation="center">
  642 + <span className="text-sm">凭证</span>
  643 + </Divider>
  644 + <Image.PreviewGroup
  645 + className="mr-10"
  646 + preview={{
  647 + onChange: (current, prev) =>
  648 + console.log(`current index: ${current}, prev index: ${prev}`),
  649 + }}
  650 + >
  651 + {prepaidProofImages.map((url) => (
  652 + <>
  653 + <Image width={120} src={url} /> <Divider type="vertical" />
  654 + </>
  655 + ))}
  656 + </Image.PreviewGroup>
  657 + <Divider></Divider>
  658 + </>
  659 + )}
  660 +
  661 + {checkType('prepaidAudit') ? (
  662 + <div>请特别注意手机号码和充值金额。</div>
  663 + ) : (
  664 + <div>请特别注意订单总金额与订单金额。</div>
  665 + )}
  666 + {!checkType(CHECK_TYPE.CONFIRM_DELIVER) ? (
  667 + <ProFormTextArea
  668 + width="lg"
  669 + name="name"
  670 + placeholder="若驳回,请填写驳回理由"
  671 + />
  672 + ) : (
  673 + <></>
  674 + )}
  675 + {checkType(CHECK_TYPE.FINALCIAL) ? (
  676 + <>
  677 + <div className="pb-4 text-xs decoration-gray-50">
  678 + 可复制照片粘贴
  679 + </div>
  680 + <Upload {...props}>
  681 + {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER
  682 + ? uploadButton
  683 + : ''}
  684 + </Upload>
  685 + </>
  686 + ) : (
  687 + ''
  688 + )}
  689 + {checkType(CHECK_TYPE.CONFIRM_REISSUE) && (
  690 + <>
  691 + <InvoiceSubOrderInfoTable
  692 + subOrderIds={subOrderIds}
  693 + ></InvoiceSubOrderInfoTable>
  694 + </>
  695 + )}
  696 + {checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING) ? (
  697 + <>
  698 + <ProList
  699 + rowKey="id"
  700 + headerTitle="发票信息"
  701 + metas={{
  702 + title: {
  703 + dataIndex: 'name',
  704 + },
  705 + avatar: {
  706 + dataIndex: 'image',
  707 + editable: false,
  708 + },
  709 + description: {
  710 + dataIndex: 'desc',
  711 + },
  712 + subTitle: {
  713 + render: () => {
  714 + return (
  715 + <Space size={0}>
  716 + <Tag color="blue">Ant Design</Tag>
  717 + <Tag color="#5BD8A6">TechUI</Tag>
  718 + </Space>
  719 + );
  720 + },
  721 + },
  722 + actions: {
  723 + render: (text, row, index, action) => [
  724 + <a
  725 + onClick={() => {
  726 + action?.startEditable(row.id);
  727 + }}
  728 + key="link"
  729 + >
  730 + 编辑
  731 + </a>,
  732 + ],
  733 + },
  734 + }}
  735 + ></ProList>
  736 + </>
  737 + ) : (
  738 + ''
  739 + )}
  740 + </ModalForm>
  741 +
  742 + <Modal
  743 + open={previewOpen}
  744 + title={previewTitle}
  745 + footer={null}
  746 + onCancel={handleCancel}
  747 + >
  748 + <img alt="图片预览" style={{ width: '100%' }} src={previewImage} />
  749 + </Modal>
  750 + {contextHolder}
  751 + </>
  752 + );
  753 +};
... ...
src/pages/Order/OrderWarning/components/ConfirmReceiptModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { postServiceOrderConfirmReceipt } from '@/services';
  3 +import { PlusOutlined } from '@ant-design/icons';
  4 +import { Button, Modal, Upload, message } from 'antd';
  5 +import { RcFile, UploadFile, UploadProps } from 'antd/es/upload';
  6 +import { cloneDeep } from 'lodash';
  7 +import { useEffect, useRef, useState } from 'react';
  8 +import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant';
  9 +export default ({ data, onClose }) => {
  10 + const subIds = data?.map((item) => {
  11 + return item.id;
  12 + });
  13 + // const [form] = Form.useForm<{ name: string; company: string }>();
  14 + const [previewOpen, setPreviewOpen] = useState(false);
  15 + const [previewImage, setPreviewImage] = useState('');
  16 + const [previewTitle, setPreviewTitle] = useState('');
  17 + const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致
  18 + const getBase64 = (file: RcFile): Promise<string> =>
  19 + new Promise((resolve, reject) => {
  20 + const reader = new FileReader();
  21 + reader.readAsDataURL(file);
  22 + reader.onload = () => resolve(reader.result as string);
  23 + reader.onerror = (error) => reject(error);
  24 + });
  25 + const [fileList, setFileList] = useState<UploadFile[]>([]);
  26 + const [uploading, setUploading] = useState(false);
  27 + const handleCancel = () => setPreviewOpen(false);
  28 +
  29 + const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
  30 + //fileListObj得在change里变化,change的参数是已经处理过的file数组
  31 + //beforeUpload中的参数file是未处理过,还需要Base64拿到文件数据处理
  32 + fileListObj.current = newFileList;
  33 + setFileList(newFileList);
  34 + };
  35 +
  36 + /** 粘贴快捷键的回调 */
  37 + const onPaste = async (e: any) => {
  38 + /** 获取剪切板的数据clipboardData */
  39 + let clipboardData = e.clipboardData,
  40 + i = 0,
  41 + items,
  42 + item,
  43 + types;
  44 +
  45 + /** 为空判断 */
  46 + if (clipboardData) {
  47 + items = clipboardData.items;
  48 + if (!items) {
  49 + message.info('您的剪贴板中没有照片');
  50 + return;
  51 + }
  52 +
  53 + item = items[0];
  54 + types = clipboardData.types || [];
  55 + /** 遍历剪切板的数据 */
  56 + for (; i < types.length; i++) {
  57 + if (types[i] === 'Files') {
  58 + item = items[i];
  59 + break;
  60 + }
  61 + }
  62 +
  63 + /** 判断文件是否为图片 */
  64 + if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
  65 + const imgItem = item.getAsFile();
  66 + const newFileList = cloneDeep(fileListObj.current);
  67 + let filteredArray = newFileList.filter(
  68 + (obj) => obj.status !== 'removed',
  69 + ); //过滤掉状态为已删除的照片
  70 + const listItem = {
  71 + ...imgItem,
  72 + status: 'done',
  73 + url: await getBase64(imgItem),
  74 + originFileObj: imgItem,
  75 + };
  76 +
  77 + if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) {
  78 + message.info('发货凭证照片数量不能超过3');
  79 + return;
  80 + }
  81 + fileListObj.current = filteredArray;
  82 + filteredArray.push(listItem);
  83 + setFileList(filteredArray);
  84 + return;
  85 + }
  86 + }
  87 +
  88 + message.info('您的剪贴板中没有照片');
  89 + };
  90 + useEffect(() => {
  91 + document.addEventListener('paste', onPaste);
  92 + return () => {
  93 + document.removeEventListener('paste', onPaste);
  94 + };
  95 + }, []);
  96 + const uploadButton = (
  97 + <div>
  98 + <PlusOutlined />
  99 + <div style={{ marginTop: 8 }}>上传凭证</div>
  100 + </div>
  101 + );
  102 + const handlePreview = async (file: UploadFile) => {
  103 + if (!file.url && !file.preview) {
  104 + file.preview = await getBase64(file.originFileObj as RcFile);
  105 + }
  106 + setPreviewImage(file.url || (file.preview as string));
  107 + setPreviewOpen(true);
  108 + setPreviewTitle(
  109 + file.name ||
  110 + file.originFileObj?.name ||
  111 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
  112 + );
  113 + };
  114 +
  115 + const handleUpload = async () => {
  116 + const formData = new FormData();
  117 + fileList.forEach((file) => {
  118 + //originFileObj二进制文件
  119 + formData.append('files', file.originFileObj as RcFile);
  120 + });
  121 + // console.log(fileList[0] as RcFile)
  122 + // formData.append('file', fileList[0] as RcFile);
  123 + formData.append('subIds', subIds);
  124 + setUploading(true);
  125 + // You can use any AJAX library you like
  126 + const res = await postServiceOrderConfirmReceipt({
  127 + data: formData,
  128 + headers: {
  129 + 'Content-Type':
  130 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  131 + },
  132 + });
  133 +
  134 + if (res.result === RESPONSE_CODE.SUCCESS) {
  135 + message.success(res.message);
  136 + onClose();
  137 + }
  138 +
  139 + setUploading(false);
  140 + };
  141 +
  142 + const props: UploadProps = {
  143 + onRemove: (file) => {
  144 + const index = fileList.indexOf(file);
  145 + const newFileList = fileList.slice();
  146 + newFileList.splice(index, 1);
  147 + setFileList(newFileList);
  148 + },
  149 + beforeUpload: (file) => {
  150 + setFileList([...fileList, file]);
  151 + return false;
  152 + },
  153 + listType: 'picture-card',
  154 + onPreview: handlePreview,
  155 + fileList,
  156 + onChange: handleChange,
  157 + accept: 'image/png, image/jpeg, image/png',
  158 + };
  159 +
  160 + return (
  161 + <>
  162 + <Modal
  163 + width={500}
  164 + open
  165 + title="确认收货"
  166 + footer={[
  167 + <Button key="cancel" onClick={onClose}>
  168 + 取消
  169 + </Button>,
  170 + <Button
  171 + type="primary"
  172 + key="ok"
  173 + onClick={handleUpload}
  174 + disabled={fileList.length === 0}
  175 + loading={uploading}
  176 + >
  177 + {uploading ? '上传中' : '提交'}
  178 + </Button>,
  179 + ]}
  180 + onCancel={async () => {
  181 + onClose();
  182 + }}
  183 + >
  184 + <div className="pt-4 font-semibold">请将买家确认收货的凭证照片上传</div>
  185 + <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div>
  186 + <Upload {...props}>
  187 + {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER ? uploadButton : ''}
  188 + </Upload>
  189 + </Modal>
  190 + <Modal
  191 + open={previewOpen}
  192 + title={previewTitle}
  193 + footer={null}
  194 + onCancel={handleCancel}
  195 + >
  196 + <img alt="图片预览" style={{ width: '100%' }} src={previewImage} />
  197 + </Modal>
  198 + </>
  199 + );
  200 +};
... ...
src/pages/Order/OrderWarning/components/DeliverInfoDrawer.tsx 0 → 100644
  1 +import { postDistrictSelOrderProvince } from '@/services';
  2 +import { enumValueToLabel } from '@/utils';
  3 +import { getReceivingCompanyOptions } from '@/utils/order';
  4 +import { Col, Drawer, Row } from 'antd';
  5 +import { useEffect, useState } from 'react';
  6 +import { PAYEE_OPTIONS } from '../../constant';
  7 +
  8 +export default ({ data, onClose }) => {
  9 + const [province, setProvince] = useState('');
  10 + const [city, setCity] = useState('');
  11 + const [district, setDistrict] = useState('');
  12 +
  13 + useEffect(() => {
  14 + const fetchData = async () => {
  15 + if (data.id !== undefined) {
  16 + const resp = await postDistrictSelOrderProvince({
  17 + data: data.id,
  18 + });
  19 + if (resp && resp.data) {
  20 + if (resp.data.province) {
  21 + setProvince(resp.data.province);
  22 + }
  23 + if (resp.data.city) {
  24 + setCity(resp.data.city);
  25 + }
  26 + if (resp.data.district) {
  27 + setDistrict(resp.data.district);
  28 + }
  29 + }
  30 + }
  31 + };
  32 +
  33 + fetchData();
  34 + }, [data.id]);
  35 + return (
  36 + <>
  37 + <Drawer
  38 + width={500}
  39 + title="基本信息"
  40 + placement="right"
  41 + onClose={onClose}
  42 + open
  43 + >
  44 + <Row gutter={[16, 24]}>
  45 + <Col span={6}>
  46 + <span className="text-[#333333]">收货人</span>
  47 + </Col>
  48 + <Col span={18}>{data.customerName}</Col>
  49 + <Col span={6}>
  50 + <span className="className='text-[#333333]'">联系方式</span>
  51 + </Col>
  52 + <Col span={18}>{data.customerContactNumber}</Col>
  53 + <Col span={6}>
  54 + <span className="className='text-[#333333]'">省市区</span>
  55 + </Col>
  56 + <Col span={18}>
  57 + {province}&nbsp;{city}&nbsp;{district}
  58 + </Col>
  59 + <Col span={6}>
  60 + <span className="className='text-[#333333]'">收货地址</span>
  61 + </Col>
  62 + <Col span={18}>{data.customerShippingAddress}</Col>
  63 + <Col span={6}>
  64 + <span className="className='text-[#333333]'">课题组老师</span>
  65 + </Col>
  66 + <Col span={18}>{data.institutionContactName}</Col>
  67 + <Col span={6}>
  68 + <span className="className='text-[#333333]'">单位名称</span>
  69 + </Col>
  70 + <Col span={18}>{data.institution}</Col>
  71 + <Col span={6}>
  72 + <span className="className='text-[#333333]'">开户银行</span>
  73 + </Col>
  74 + <Col span={18}>{data.bank}</Col>
  75 +
  76 + <Col span={6}>
  77 + <span className="className='text-[#333333]'">开票收款单位</span>
  78 + </Col>
  79 + <Col span={18}>
  80 + {enumValueToLabel(
  81 + data.receivingCompany,
  82 + getReceivingCompanyOptions(PAYEE_OPTIONS),
  83 + )}
  84 + </Col>
  85 +
  86 + <Col span={6}>
  87 + <span className="className='text-[#333333]'">银行账号</span>
  88 + </Col>
  89 + <Col span={18}>{data.bankAccountNumber}</Col>
  90 + <Col span={6}>
  91 + <span className="className='text-[#333333]'">开票识别号</span>
  92 + </Col>
  93 + <Col span={18}>{data.invoiceIdentificationNumber}</Col>
  94 + </Row>
  95 + </Drawer>
  96 + </>
  97 + );
  98 +};
... ...
src/pages/Order/OrderWarning/components/DeliverModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postServiceOrderProcureSend,
  4 + postServiceOrderSendProduct,
  5 + postServiceOrderSupplierSendOrder,
  6 +} from '@/services';
  7 +import { enumToSelect } from '@/utils';
  8 +import {
  9 + ProColumns,
  10 + ProForm,
  11 + ProFormSelect,
  12 + ProFormText,
  13 + ProTable,
  14 +} from '@ant-design/pro-components';
  15 +import {
  16 + Button,
  17 + Col,
  18 + Flex,
  19 + Input,
  20 + InputNumber,
  21 + Modal,
  22 + Row,
  23 + Select,
  24 + message,
  25 +} from 'antd';
  26 +import { cloneDeep } from 'lodash';
  27 +import { useEffect, useRef, useState } from 'react';
  28 +import { CHECK_TYPE, LOGISTICS_STATUS_OPTIONS } from '../../constant';
  29 +
  30 +const DeliverModal = ({
  31 + data: propsData,
  32 + isSendProduct,
  33 + setVisible,
  34 + sendType,
  35 + onClose,
  36 +}) => {
  37 + const [data, setData] = useState(propsData || {});
  38 + const form = useRef();
  39 +
  40 + /**
  41 + * 是供应商发货还是普通发货
  42 + * @param typeString
  43 + * @returns
  44 + */
  45 + function optType(typeString: string) {
  46 + if (sendType === typeString) {
  47 + return true;
  48 + }
  49 +
  50 + return false;
  51 + }
  52 +
  53 + useEffect(() => {
  54 + setData(propsData);
  55 + }, [propsData]);
  56 +
  57 + const handleChange = (key: string, index: number, obj: any) => {
  58 + const newData = cloneDeep(data);
  59 + if (typeof obj !== 'object') {
  60 + newData[index][key] = obj;
  61 + } else {
  62 + newData[index][key] = obj.target?.value;
  63 + }
  64 + setData(newData);
  65 + };
  66 + const columns: ProColumns<any>[] = [
  67 + {
  68 + title: 'ID',
  69 + dataIndex: 'id',
  70 + width: 120,
  71 + render: (_, record) => <Input value={record.id} disabled />,
  72 + },
  73 + {
  74 + title: '商品编号',
  75 + dataIndex: 'productCode',
  76 + width: 120,
  77 + render: (_, record) => <Input value={record.productCode} disabled />,
  78 + },
  79 + {
  80 + title: '商品名称',
  81 + dataIndex: 'productName',
  82 + width: 120,
  83 + render: (_, record) => <Input value={record.productName} disabled />,
  84 + },
  85 + {
  86 + title: '商品参数',
  87 + dataIndex: 'parameters',
  88 + width: 80,
  89 + render: (_, record) => <Input value={record.parameters} disabled />,
  90 + },
  91 + {
  92 + title: '商品数量',
  93 + dataIndex: 'status',
  94 + render: (_, record) => <InputNumber value={record.quantity} disabled />,
  95 + },
  96 + {
  97 + title: '包裹数量',
  98 + dataIndex: 'packageNumber',
  99 + render: (_, record, index) => (
  100 + <InputNumber
  101 + min={1}
  102 + value={record.packageNumber}
  103 + defaultValue={1}
  104 + onChange={(value) => handleChange('packageNumber', index, value)}
  105 + />
  106 + ),
  107 + },
  108 + {
  109 + title: '物流方式',
  110 + key: 'logisticsMethod',
  111 + render: (_, record, index) => (
  112 + <Select
  113 + style={{ minWidth: 150 }}
  114 + placeholder="请输入物流方式"
  115 + value={record.logisticsMethod}
  116 + options={enumToSelect(LOGISTICS_STATUS_OPTIONS)}
  117 + onChange={(value) => {
  118 + handleChange('logisticsMethod', index, value); //修改时更改record数据
  119 + if (value === 'OTHER_LOGISTICS') {
  120 + message.info(
  121 + '您选择的是[其他物流方式],请将该物流方式写在备注中',
  122 + );
  123 + }
  124 + }}
  125 + />
  126 + ),
  127 + },
  128 + {
  129 + title: '物流单号',
  130 + key: 'serialNumber',
  131 + render: (_, record, index) => (
  132 + <Input
  133 + placeholder="请输入物流单号"
  134 + value={record.serialNumber}
  135 + onChange={(value) => {
  136 + handleChange('serialNumber', index, value);
  137 + }}
  138 + />
  139 + ),
  140 + },
  141 + {
  142 + title: '物流备注',
  143 + dataIndex: 'packageNumber',
  144 + render: (_, record, index) => (
  145 + <Input.TextArea
  146 + value={record.logisticsNotes}
  147 + onChange={(value) => handleChange('logisticsNotes', index, value)}
  148 + />
  149 + ),
  150 + },
  151 + ];
  152 +
  153 + return (
  154 + <Modal
  155 + open
  156 + width={1000}
  157 + title={isSendProduct ? '发货' : '修改发货信息'}
  158 + onOk={async () => {
  159 + //请求体封装
  160 + let list = data.map((item) => {
  161 + return {
  162 + id: item.id,
  163 + logisticsMethod: item.logisticsMethod,
  164 + serialNumber: item.serialNumber,
  165 + packageNumber:
  166 + item.packageNumber === null || item.packageNumber === undefined
  167 + ? 1
  168 + : item.packageNumber,
  169 + logisticsNotes: item.logisticsNotes,
  170 + };
  171 + });
  172 +
  173 + for (let item of list) {
  174 + let method = item.logisticsMethod;
  175 + let notes = item.logisticsNotes;
  176 + if (
  177 + method === 'OTHER_LOGISTICS' &&
  178 + (notes === '' || notes === undefined)
  179 + ) {
  180 + message.error(
  181 + '请检查:物流方式为[其他物流方式]的记录中,物流备注不能为空!请将实际的物流方式填写在备注中!',
  182 + );
  183 + return;
  184 + }
  185 + }
  186 + let body = { id: data[0].mainOrderId, list: list, flag: false };
  187 + if (isSendProduct) {
  188 + body.flag = true;
  189 + }
  190 + //发货请求
  191 + let res;
  192 + if (optType(CHECK_TYPE.SUPPLIER)) {
  193 + res = await postServiceOrderSupplierSendOrder({ data: body });
  194 + } else if (optType(CHECK_TYPE.PROCURE)) {
  195 + res = await postServiceOrderProcureSend({ data: body });
  196 + } else {
  197 + res = await postServiceOrderSendProduct({ data: body });
  198 + }
  199 +
  200 + if (res.result === RESPONSE_CODE.SUCCESS) {
  201 + message.success(res.message);
  202 + onClose();
  203 + }
  204 + }}
  205 + onCancel={() => {
  206 + setVisible(false);
  207 + }}
  208 + footer={[
  209 + <Button
  210 + key="back"
  211 + onClick={() => {
  212 + setVisible(false);
  213 + }}
  214 + >
  215 + 取消
  216 + </Button>,
  217 + <Button
  218 + key="selfDeliver"
  219 + type="primary"
  220 + onClick={async () => {
  221 + //请求体封装
  222 + let list = data.map((item) => {
  223 + return {
  224 + id: item.id,
  225 + deliverType: 'SELF_DELIVER',
  226 + };
  227 + });
  228 +
  229 + let body = { id: data[0].mainOrderId, list: list, flag: false };
  230 + if (isSendProduct) {
  231 + body.flag = true;
  232 + }
  233 + //发货请求
  234 + let res;
  235 + if (optType(CHECK_TYPE.SUPPLIER)) {
  236 + res = await postServiceOrderSupplierSendOrder({ data: body });
  237 + } else if (optType(CHECK_TYPE.PROCURE)) {
  238 + res = await postServiceOrderProcureSend({ data: body });
  239 + } else {
  240 + res = await postServiceOrderSendProduct({ data: body });
  241 + }
  242 +
  243 + if (res.result === RESPONSE_CODE.SUCCESS) {
  244 + message.success(res.message);
  245 + onClose();
  246 + }
  247 + }}
  248 + >
  249 + 自行派送
  250 + </Button>,
  251 + <Button
  252 + key="submit"
  253 + type="primary"
  254 + onClick={async () => {
  255 + //请求体封装
  256 + let list = data.map((item) => {
  257 + return {
  258 + id: item.id,
  259 + logisticsMethod: item.logisticsMethod,
  260 + serialNumber: item.serialNumber,
  261 + packageNumber:
  262 + item.packageNumber === null ||
  263 + item.packageNumber === undefined
  264 + ? 1
  265 + : item.packageNumber,
  266 + logisticsNotes: item.logisticsNotes,
  267 + };
  268 + });
  269 +
  270 + for (let item of list) {
  271 + let method = item.logisticsMethod;
  272 + let notes = item.logisticsNotes;
  273 + if (
  274 + method === 'OTHER_LOGISTICS' &&
  275 + (notes === '' || notes === undefined)
  276 + ) {
  277 + message.error(
  278 + '请检查:物流方式为[其他物流方式]的记录中,物流备注不能为空!请将实际的物流方式填写在备注中!',
  279 + );
  280 + return;
  281 + }
  282 + }
  283 + let body = { id: data[0].mainOrderId, list: list, flag: false };
  284 + if (isSendProduct) {
  285 + body.flag = true;
  286 + }
  287 + //发货请求
  288 + let res;
  289 + if (optType(CHECK_TYPE.SUPPLIER)) {
  290 + res = await postServiceOrderSupplierSendOrder({ data: body });
  291 + } else if (optType(CHECK_TYPE.PROCURE)) {
  292 + res = await postServiceOrderProcureSend({ data: body });
  293 + } else {
  294 + res = await postServiceOrderSendProduct({ data: body });
  295 + }
  296 +
  297 + if (res.result === RESPONSE_CODE.SUCCESS) {
  298 + message.success(res.message);
  299 + onClose();
  300 + }
  301 + }}
  302 + >
  303 + 确认
  304 + </Button>,
  305 + ]}
  306 + >
  307 + <Flex vertical>
  308 + <strong>将物流方式和物流单号更新到下方所有订单</strong>
  309 + <span className="text-[red] py-1">
  310 + 选择【其他物流方式】时,需要将对应的物流方式填写在备注中。例如:如果发圆通快递,系统上没有这个选项,就需要选【其他物流方式】,然后把“圆通快递”填在备注上。
  311 + </span>
  312 + </Flex>
  313 +
  314 + <ProForm
  315 + layout="inline"
  316 + submitter={false}
  317 + className="mb-8"
  318 + formRef={form}
  319 + >
  320 + <Row gutter={[0, 6]}>
  321 + <Col>
  322 + <ProFormSelect
  323 + placeholder="请输入物流方式"
  324 + name="logisticsMethod"
  325 + width="sm"
  326 + label="物流方式"
  327 + options={enumToSelect(LOGISTICS_STATUS_OPTIONS)}
  328 + />
  329 + <ProFormText name="logisticsNotes" label="物流备注"></ProFormText>
  330 + </Col>
  331 + <Col>
  332 + <ProFormText name="serialNumber" label="物流单号"></ProFormText>
  333 + </Col>
  334 + </Row>
  335 +
  336 + <Button
  337 + type="primary"
  338 + onClick={() => {
  339 + const values = form.current.getFieldsValue();
  340 + if (values.logisticsMethod === 'OTHER_LOGISTICS') {
  341 + message.info(
  342 + '自动填充成功!您选择的是其他物流方式,请将物流方式写在物流备注中!',
  343 + );
  344 + }
  345 + let newData = cloneDeep(data);
  346 + newData = newData.map((item) => ({
  347 + ...item,
  348 + logisticsMethod: values.logisticsMethod,
  349 + serialNumber: values.serialNumber,
  350 + logisticsNotes: values.logisticsNotes,
  351 + }));
  352 + setData(newData);
  353 + }}
  354 + >
  355 + 批量更新
  356 + </Button>
  357 + </ProForm>
  358 + <ProTable<any>
  359 + className="px-0"
  360 + dataSource={data}
  361 + rowKey="id"
  362 + pagination={false}
  363 + columns={columns}
  364 + search={false}
  365 + dateFormatter="string"
  366 + options={false}
  367 + scroll={{ x: 1400 }}
  368 + />
  369 + </Modal>
  370 + );
  371 +};
  372 +
  373 +export default DeliverModal;
... ...
src/pages/Order/OrderWarning/components/FinancialDrawer.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postServiceOrderEditOrder,
  4 + postServiceOrderInvoicing,
  5 +} from '@/services';
  6 +import { FloatAdd, enumToSelect, enumValueToLabel } from '@/utils';
  7 +import { getReceivingCompanyOptions } from '@/utils/order';
  8 +import {
  9 + DrawerForm,
  10 + ProFormDatePicker,
  11 + ProFormDigit,
  12 + ProFormSelect,
  13 + ProFormText,
  14 + ProFormTextArea,
  15 +} from '@ant-design/pro-components';
  16 +import { Button, Form, message } from 'antd';
  17 +import { useEffect, useState } from 'react';
  18 +import { INVOCING_STATUS_OPTIONS_OLD, PAYEE_OPTIONS } from '../../constant';
  19 +
  20 +export default ({
  21 + mainOrder,
  22 + subOrders,
  23 + isEdit,
  24 + isMainOrder,
  25 + cancel,
  26 + onClose,
  27 +}) => {
  28 + const [invoicingStatus, setInvoicingStatus] = useState('');
  29 + const subIds = subOrders.map((item) => item.id);
  30 + useEffect(() => {
  31 + // 在组件挂载或数据变化时,更新组件状态
  32 + if (mainOrder) {
  33 + setInvoicingStatus(subOrders[0]?.invoicingStatus);
  34 + }
  35 + }, [mainOrder]);
  36 + useEffect(() => {
  37 + console.log(JSON.stringify(subOrders));
  38 + }, []);
  39 +
  40 + const [form] = Form.useForm<{ name: string; company: string }>();
  41 +
  42 + /**
  43 + * 自动选择收款公司
  44 + * @param receivingCompany
  45 + */
  46 + function chooseReceivingCompany(receivingCompany: any) {
  47 + form.setFieldValue('payee', receivingCompany);
  48 + }
  49 +
  50 + /**
  51 + * 计算选中子订单的主订单金额之和
  52 + */
  53 + function computeTotalPayment() {
  54 + let distinctMap = new Map();
  55 +
  56 + subOrders?.forEach((item: any) => {
  57 + distinctMap.set(item.mainOrderId, item.totalPayment);
  58 + });
  59 +
  60 + let sum = 0;
  61 + for (let p of distinctMap.values()) {
  62 + sum = FloatAdd(p, sum);
  63 + }
  64 +
  65 + form.setFieldValue('money', sum);
  66 + }
  67 +
  68 + return (
  69 + <DrawerForm<{
  70 + name: string;
  71 + company: string;
  72 + }>
  73 + open
  74 + title="财务信息"
  75 + resize={{
  76 + onResize() {
  77 + console.log('resize!');
  78 + },
  79 + maxWidth: window.innerWidth * 0.8,
  80 + minWidth: 400,
  81 + }}
  82 + initialValues={mainOrder}
  83 + form={form}
  84 + autoFocusFirstInput
  85 + drawerProps={{
  86 + destroyOnClose: true,
  87 + }}
  88 + submitTimeout={2000}
  89 + onFinish={async (values) => {
  90 + let res;
  91 + let body = values;
  92 + body.subIds = subIds;
  93 + if (isEdit) {
  94 + res = await postServiceOrderEditOrder({ data: body });
  95 + } else {
  96 + res = await postServiceOrderInvoicing({ data: body });
  97 + }
  98 + if (res.result === RESPONSE_CODE.SUCCESS) {
  99 + message.success(res.message);
  100 + onClose();
  101 + }
  102 + }}
  103 + onOpenChange={(val) => {
  104 + return !val && cancel();
  105 + }}
  106 + >
  107 + {isMainOrder ? (
  108 + <ProFormSelect
  109 + placeholder="选择是否需要开票"
  110 + name="invoicingStatus"
  111 + width="lg"
  112 + label="是否需要开票"
  113 + options={enumToSelect(INVOCING_STATUS_OPTIONS_OLD)}
  114 + onChange={setInvoicingStatus}
  115 + initialValue={subOrders[0]?.invoicingStatus}
  116 + // disabled={mainInfoDisbled}
  117 + rules={[{ required: true, message: '是否需要开票必填' }]}
  118 + />
  119 + ) : (
  120 + ''
  121 + )}
  122 +
  123 + <ProFormTextArea
  124 + width="lg"
  125 + name="invoiceIdentificationNumber"
  126 + label="开票信息"
  127 + placeholder="请输入开票信息"
  128 + disabled
  129 + />
  130 + <ProFormText
  131 + width="lg"
  132 + name="bank"
  133 + label="开户银行"
  134 + placeholder="请输入开户银行"
  135 + disabled
  136 + />
  137 + <ProFormText
  138 + width="lg"
  139 + name="bankAccountNumber"
  140 + label="开户银行账号"
  141 + placeholder="请输入开户银行账号"
  142 + disabled
  143 + />
  144 +
  145 + {invoicingStatus !== 'UN_INVOICE'
  146 + ? [
  147 + <ProFormDatePicker
  148 + key="invoicingTime"
  149 + width="lg"
  150 + name="invoicingTime"
  151 + label="开票时间"
  152 + disabled={isEdit}
  153 + rules={[
  154 + { required: !isEdit ? true : false, message: '这是必填项' },
  155 + ]}
  156 + initialValue={subOrders[0]?.invoicingTime}
  157 + />,
  158 + <ProFormText
  159 + key="purchaser"
  160 + width="lg"
  161 + name="purchaser"
  162 + label="抬头名称"
  163 + disabled={isEdit}
  164 + rules={[
  165 + { required: !isEdit ? true : false, message: '这是必填项' },
  166 + ]}
  167 + initialValue={subOrders[0]?.purchaser}
  168 + />,
  169 + <ProFormDatePicker
  170 + key="financialReceiptIssuanceTime"
  171 + width="lg"
  172 + name="financialReceiptIssuanceTime"
  173 + label="开收据时间"
  174 + initialValue={subOrders[0]?.financialReceiptIssuanceTime}
  175 + />,
  176 + <ProFormDatePicker
  177 + key="collectMoneyTime"
  178 + width="lg"
  179 + name="collectMoneyTime"
  180 + label="收款时间"
  181 + initialValue={subOrders[0]?.collectMoneyTime}
  182 + />,
  183 + <ProFormText
  184 + width="lg"
  185 + key="invoiceNumber"
  186 + name="invoiceNumber"
  187 + label="发票号码"
  188 + initialValue={subOrders[0]?.invoiceNumber}
  189 + rules={[{ required: true, message: '发票号码必填' }]}
  190 + />,
  191 + <div
  192 + key="salesChooseReceivingCompany"
  193 + hidden={subOrders[0].receivingCompany === null}
  194 + >
  195 + <span className={'pl-2 text-xs text-gray-400'}>
  196 + 销售申请开票时选择了:
  197 + {enumValueToLabel(
  198 + subOrders[0].receivingCompany,
  199 + getReceivingCompanyOptions(PAYEE_OPTIONS),
  200 + )}
  201 + </span>
  202 + <span
  203 + hidden={subOrders[0].receivingCompany === 'ANY'}
  204 + className={
  205 + 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'
  206 + }
  207 + onClick={() => {
  208 + chooseReceivingCompany(subOrders[0].receivingCompany);
  209 + }}
  210 + >
  211 + 选择
  212 + </span>
  213 + </div>,
  214 + <ProFormSelect
  215 + key="payee"
  216 + placeholder="选择收款单位"
  217 + name="payee"
  218 + width="lg"
  219 + showSearch
  220 + label="收款单位"
  221 + options={enumToSelect(PAYEE_OPTIONS)}
  222 + initialValue={subOrders[0]?.payee}
  223 + rules={[{ required: true, message: '收款单位必填' }]}
  224 + />,
  225 +
  226 + <div id="total-payment" key="money">
  227 + <ProFormDigit
  228 + key="money"
  229 + name="money"
  230 + width="lg"
  231 + label="金额"
  232 + rules={[{ required: true, message: '金额必填' }]}
  233 + tooltip="点击计算,合计所有子订单对应主订单总额"
  234 + fieldProps={{
  235 + addonAfter: (
  236 + <Button
  237 + className="rounded-l-none"
  238 + type="primary"
  239 + onClick={computeTotalPayment}
  240 + >
  241 + 计算
  242 + </Button>
  243 + ),
  244 + }}
  245 + />
  246 + </div>,
  247 + ]
  248 + : ''}
  249 +
  250 + <ProFormSelect
  251 + placeholder="是否完全开票"
  252 + name="afterInvoicingStatus"
  253 + width="lg"
  254 + label="是否完全开票"
  255 + options={[
  256 + { label: '完全开票', value: 'COMPLETE_INVOICING' },
  257 + { label: '部分开票', value: 'PARTIAL_INVOICING' },
  258 + ]}
  259 + // disabled={mainInfoDisbled}
  260 + initialValue={
  261 + subOrders[0]?.afterInvoicingStatus === 'APPLY_FOR_INVOICING'
  262 + ? 'COMPLETE_INVOICING'
  263 + : subOrders[0]?.afterInvoicingStatus
  264 + }
  265 + rules={[{ required: true, message: '是否完全开票必填' }]}
  266 + />
  267 + <ProFormTextArea
  268 + width="lg"
  269 + name="invoicingNotes"
  270 + label="备注"
  271 + initialValue={subOrders[0]?.invoicingNotes}
  272 + />
  273 + </DrawerForm>
  274 + );
  275 +};
... ...
src/pages/Order/OrderWarning/components/FinancialEditDrawer.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { postServiceOrderNoNeedInvoicingEdit } from '@/services';
  3 +import { enumToSelect } from '@/utils';
  4 +import {
  5 + DrawerForm,
  6 + ProFormDatePicker,
  7 + ProFormSelect,
  8 + ProFormText,
  9 +} from '@ant-design/pro-components';
  10 +import { Form, message } from 'antd';
  11 +import { useEffect, useState } from 'react';
  12 +import { INVOCING_STATUS_OPTIONS_OLD } from '../../constant';
  13 +
  14 +export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) => {
  15 + const [invoicingStatus, setInvoicingStatus] = useState('');
  16 + useEffect(() => {
  17 + setInvoicingStatus(subOrders[0]?.invoicingStatus);
  18 + }, []);
  19 + const subOrderIds = subOrders?.map((subOrder) => {
  20 + return subOrder?.id;
  21 + });
  22 + const mainOrderId = mainOrder.id;
  23 + const [form] = Form.useForm<{
  24 + collectMoneyTime: string;
  25 + subIds: [];
  26 + financialReceiptIssuanceTime: string;
  27 + }>();
  28 +
  29 + //回显开收据时间和收款时间
  30 + if (!isMainOrder) {
  31 + form.setFieldValue('collectMoneyTime', subOrders[0].collectMoneyTime);
  32 + form.setFieldValue(
  33 + 'financialReceiptIssuanceTime',
  34 + subOrders[0].financialReceiptIssuanceTime,
  35 + );
  36 + }
  37 +
  38 + return (
  39 + <DrawerForm<{
  40 + collectMoneyTime: string;
  41 + financialReceiptIssuanceTime: string;
  42 + subIds: [];
  43 + }>
  44 + open
  45 + title={isMainOrder ? '编辑开票信息' : '编辑收款时间'}
  46 + resize={{
  47 + onResize() {
  48 + console.log('resize!');
  49 + },
  50 + maxWidth: window.innerWidth * 0.8,
  51 + minWidth: 400,
  52 + }}
  53 + initialValues={mainOrder}
  54 + form={form}
  55 + autoFocusFirstInput
  56 + drawerProps={{
  57 + destroyOnClose: true,
  58 + }}
  59 + submitTimeout={2000}
  60 + onFinish={async (values) => {
  61 + let body = {
  62 + ...values,
  63 + mainOrderId: mainOrderId,
  64 + subIds: subOrderIds,
  65 + };
  66 +
  67 + if (!isMainOrder) {
  68 + body.invoicingStatus = 'UN_INVOICE';
  69 + }
  70 +
  71 + let res = await postServiceOrderNoNeedInvoicingEdit({
  72 + data: body,
  73 + });
  74 + if (res.result === RESPONSE_CODE.SUCCESS) {
  75 + message.success(res.message);
  76 + onClose();
  77 + }
  78 + }}
  79 + onOpenChange={(val) => {
  80 + return !val && setVisible(val);
  81 + }}
  82 + >
  83 + {isMainOrder ? (
  84 + <ProFormSelect
  85 + placeholder="选择是否需要开票"
  86 + name="invoicingStatus"
  87 + width="lg"
  88 + label="是否需要开票"
  89 + options={enumToSelect(INVOCING_STATUS_OPTIONS_OLD)}
  90 + onChange={setInvoicingStatus}
  91 + initialValue={subOrders[0]?.invoicingStatus}
  92 + // disabled={mainInfoDisbled}
  93 + rules={[{ required: true, message: '是否需要开票必填' }]}
  94 + />
  95 + ) : (
  96 + ''
  97 + )}
  98 +
  99 + {invoicingStatus !== 'UN_INVOICE' ? (
  100 + <>
  101 + <ProFormText
  102 + key="invoiceIdentificationNumber"
  103 + width="lg"
  104 + name="invoiceIdentificationNumber"
  105 + label="开票信息"
  106 + placeholder="请输入开票信息"
  107 + rules={[{ required: true, message: '开票信息必填' }]}
  108 + />
  109 + <ProFormText
  110 + key="bank"
  111 + width="lg"
  112 + name="bank"
  113 + label="开户银行"
  114 + placeholder="请输入开户银行"
  115 + />
  116 + <ProFormText
  117 + key="bankAccountNumber"
  118 + width="lg"
  119 + name="bankAccountNumber"
  120 + label="开户银行账号"
  121 + placeholder="请输入开户银行账号"
  122 + />
  123 + </>
  124 + ) : (
  125 + ''
  126 + )}
  127 +
  128 + <ProFormDatePicker
  129 + key="financialReceiptIssuanceTime"
  130 + width="lg"
  131 + name="financialReceiptIssuanceTime"
  132 + label="开收据时间"
  133 + // rules={[
  134 + // {
  135 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  136 + // message: '开收据时间必填',
  137 + // },
  138 + // ]}
  139 + />
  140 + <ProFormDatePicker
  141 + key="collectMoneyTime"
  142 + width="lg"
  143 + name="collectMoneyTime"
  144 + label="收款时间"
  145 + // rules={[
  146 + // {
  147 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  148 + // message: '收款时间必填',
  149 + // },
  150 + // ]}
  151 + />
  152 + </DrawerForm>
  153 + );
  154 +};
... ...
src/pages/Order/OrderWarning/components/FinancialMergeDrawer.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { enumToSelect } from '@/utils';
  3 +import {
  4 + DrawerForm,
  5 + ProFormDatePicker,
  6 + ProFormDigit,
  7 + ProFormSelect,
  8 + ProFormText,
  9 + ProFormTextArea,
  10 +} from '@ant-design/pro-components';
  11 +import { Form, message } from 'antd';
  12 +import { PAYEE_OPTIONS } from '../../constant';
  13 +
  14 +export default ({ dataList, setVisible, onClose }) => {
  15 + // let subOrderIds = dataList?.map((item) => {
  16 + // return item.id;
  17 + // });
  18 + let firstMainOrder = dataList[0];
  19 + let bank = firstMainOrder?.bank;
  20 + let bankAccountNumber = firstMainOrder?.bankAccountNumber;
  21 + let invoiceIdentificationNumber = firstMainOrder?.invoiceIdentificationNumber;
  22 +
  23 + const [form] = Form.useForm<{
  24 + invoicingTime: string;
  25 + financialReceiptIssuanceTime: string;
  26 + invoicingNotes: string;
  27 + afterInvoicingStatus: string;
  28 + collectMoneyTime: string;
  29 + }>();
  30 + return (
  31 + <DrawerForm
  32 + open
  33 + title="合并开票"
  34 + resize={{
  35 + onResize() {
  36 + console.log('resize!');
  37 + },
  38 + maxWidth: window.innerWidth * 0.8,
  39 + minWidth: 400,
  40 + }}
  41 + form={form}
  42 + autoFocusFirstInput
  43 + drawerProps={{
  44 + destroyOnClose: true,
  45 + }}
  46 + submitTimeout={2000}
  47 + onFinish={async (values) => {
  48 + console.log(values);
  49 + let res;
  50 + let body = values;
  51 + body.subIds = subIds;
  52 + body.mainOrderId = mainOrder.id;
  53 + body.mainorderOrSubOrderInvoicing = isMainOrder;
  54 + if (isEdit) {
  55 + res = await postServiceOrderEditOrder({ data: body });
  56 + } else {
  57 + res = await postServiceOrderInvoicing({ data: body });
  58 + }
  59 + if (res.result === RESPONSE_CODE.SUCCESS) {
  60 + message.success(res.message);
  61 + onClose();
  62 + }
  63 + }}
  64 + onOpenChange={(val) => {
  65 + return !val && setVisible();
  66 + }}
  67 + >
  68 + <ProFormText
  69 + width="lg"
  70 + name="invoiceIdentificationNumber"
  71 + label="开票信息"
  72 + placeholder="请输入开票信息"
  73 + initialValue={invoiceIdentificationNumber}
  74 + disabled
  75 + />
  76 + <ProFormText
  77 + width="lg"
  78 + name="bank"
  79 + label="开户银行"
  80 + placeholder="请输入开户银行"
  81 + initialValue={bank}
  82 + disabled
  83 + />
  84 + <ProFormText
  85 + width="lg"
  86 + name="bankAccountNumber"
  87 + label="开户银行账号"
  88 + placeholder="请输入开户银行账号"
  89 + initialValue={bankAccountNumber}
  90 + disabled
  91 + />
  92 +
  93 + <ProFormDatePicker
  94 + key="invoicingTime"
  95 + width="lg"
  96 + name="invoicingTime"
  97 + label="开票时间"
  98 + rules={[{ required: true, message: '这是必填项' }]}
  99 + />
  100 + <ProFormDatePicker
  101 + key="financialReceiptIssuanceTime"
  102 + width="lg"
  103 + name="financialReceiptIssuanceTime"
  104 + label="开收据时间"
  105 + />
  106 + <ProFormDatePicker
  107 + key="collectMoneyTime"
  108 + width="lg"
  109 + name="collectMoneyTime"
  110 + label="收款时间"
  111 + />
  112 + <ProFormText
  113 + width="lg"
  114 + key="invoiceNumber"
  115 + name="invoiceNumber"
  116 + label="发票号码"
  117 + rules={[{ required: true, message: '发票号码必填' }]}
  118 + />
  119 + <ProFormSelect
  120 + key="payee"
  121 + placeholder="选择收款单位"
  122 + name="payee"
  123 + width="lg"
  124 + label="收款单位"
  125 + options={enumToSelect(PAYEE_OPTIONS)}
  126 + rules={[{ required: true, message: '收款单位必填' }]}
  127 + />
  128 +
  129 + <ProFormDigit
  130 + key="money"
  131 + name="money"
  132 + width="lg"
  133 + label="金额"
  134 + rules={[{ required: true, message: '金额必填' }]}
  135 + />
  136 + <ProFormSelect
  137 + placeholder="是否完全开票"
  138 + name="afterInvoicingStatus"
  139 + width="lg"
  140 + label="是否完全开票"
  141 + options={[
  142 + { label: '完全开票', value: 'COMPLETE_INVOICING' },
  143 + { label: '部分开票', value: 'PARTIAL_INVOICING' },
  144 + ]}
  145 + initialValue={'COMPLETE_INVOICING'}
  146 + />
  147 + <ProFormTextArea width="lg" name="invoicingNotes" label="备注" />
  148 + </DrawerForm>
  149 + );
  150 +};
... ...
src/pages/Order/OrderWarning/components/FinancialReceiptsModal.tsx 0 → 100644
  1 +import { postServiceOrderUpdateHirePurchase } from '@/services';
  2 +import {
  3 + EditableProTable,
  4 + ModalForm,
  5 + ProColumns,
  6 + ProForm,
  7 +} from '@ant-design/pro-components';
  8 +import { Form } from 'antd';
  9 +import { useState } from 'react';
  10 +
  11 +// import { cloneDeep } from 'lodash';
  12 +export default ({ setVisible, datas, onClose }) => {
  13 + const [form] = Form.useForm<{ name: string; company: string }>();
  14 + type DataSourceType = {
  15 + id: React.Key;
  16 + hirePurchaseMethod?: string;
  17 + hirePurchaseMethodName?: string;
  18 + money?: number;
  19 + updateTime?: string;
  20 + notes?: string;
  21 + };
  22 + const defaultData: DataSourceType[] = [
  23 + {
  24 + id: 1,
  25 + hirePurchaseMethod: 'ADVANCE_CHARGE',
  26 + hirePurchaseMethodName: '预付款',
  27 + money: undefined,
  28 + updateTime: undefined,
  29 + notes: undefined,
  30 + },
  31 + {
  32 + id: 2,
  33 + hirePurchaseMethod: 'PAYMENT_FOR_SHIPMENT',
  34 + hirePurchaseMethodName: '发货款',
  35 + money: undefined,
  36 + updateTime: undefined,
  37 + notes: undefined,
  38 + },
  39 + {
  40 + id: 3,
  41 + hirePurchaseMethod: 'ACCEPTANCE_PAYMENT',
  42 + hirePurchaseMethodName: '验收款',
  43 + money: undefined,
  44 + updateTime: undefined,
  45 + notes: undefined,
  46 + },
  47 + {
  48 + id: 4,
  49 + hirePurchaseMethod: 'BALANCE_PAYMENT',
  50 + hirePurchaseMethodName: '尾款',
  51 + money: undefined,
  52 + updateTime: undefined,
  53 + notes: undefined,
  54 + },
  55 + ];
  56 + const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
  57 + // defaultData.map((item) => item.id),
  58 + [1, 2, 3, 4],
  59 + );
  60 + const columns: ProColumns<DataSourceType>[] = [
  61 + {
  62 + title: '款项',
  63 + dataIndex: 'hirePurchaseMethodName',
  64 + editable: false,
  65 + width: '10%',
  66 + },
  67 + {
  68 + title: '已收金额',
  69 + dataIndex: 'money',
  70 + valueType: 'digit',
  71 + width: '15%',
  72 + },
  73 + {
  74 + title: '收款时间',
  75 + dataIndex: 'updateTime',
  76 + valueType: 'dateTime',
  77 + width: '25%',
  78 + },
  79 + {
  80 + title: '备注',
  81 + dataIndex: 'receiptsNotes',
  82 + },
  83 + ];
  84 + return (
  85 + <>
  86 + <ModalForm<{
  87 + name: string;
  88 + company: string;
  89 + }>
  90 + width={1100}
  91 + open
  92 + title="收款记录"
  93 + form={form}
  94 + autoFocusFirstInput
  95 + modalProps={{
  96 + okText: '保存',
  97 + cancelText: '取消',
  98 + destroyOnClose: true,
  99 + onCancel: () => {
  100 + setVisible(false);
  101 + },
  102 + }}
  103 + onFinish={async (values) => {
  104 + let res = await postServiceOrderUpdateHirePurchase({
  105 + data: {
  106 + mainOrderId: datas[0].id,
  107 + list: values.dataSource,
  108 + },
  109 + });
  110 + console.log(res);
  111 + onClose();
  112 + }}
  113 + onOpenChange={setVisible}
  114 + >
  115 + <ProForm.Item
  116 + label=""
  117 + name="dataSource"
  118 + initialValue={defaultData}
  119 + trigger="onValuesChange"
  120 + >
  121 + <EditableProTable<DataSourceType>
  122 + rowKey="id"
  123 + toolBarRender={false}
  124 + columns={columns}
  125 + recordCreatorProps={{
  126 + newRecordType: 'dataSource',
  127 + position: 'top',
  128 + record: () => ({
  129 + id: Date.now(),
  130 + addonBefore: 'ccccccc',
  131 + decs: 'testdesc',
  132 + }),
  133 + style: {
  134 + display: 'none',
  135 + },
  136 + }}
  137 + editable={{
  138 + type: 'multiple',
  139 + editableKeys,
  140 + onChange: setEditableRowKeys,
  141 + actionRender: (row, _, dom) => {
  142 + return [dom.delete];
  143 + },
  144 + }}
  145 + />
  146 + </ProForm.Item>
  147 +
  148 + {/* <ProForm.Group>
  149 + <ProFormText
  150 + width="sm"
  151 + name="name1"
  152 + label="款项"
  153 + tooltip="最长为 24 位"
  154 + initialValue={"预付款"}
  155 + disabled
  156 + placeholder="请输入名称"
  157 + />
  158 +
  159 + <ProFormText
  160 + width="sm"
  161 + name="company"
  162 + label="收款时间"
  163 + placeholder="请输入名称"
  164 + />
  165 +
  166 + <ProFormText
  167 + width="sm"
  168 + name="price"
  169 + label="收款金额"
  170 + placeholder="请输入名称"
  171 + />
  172 +
  173 + <ProFormText
  174 + width="sm"
  175 + name="notes"
  176 + label="备注"
  177 + placeholder="请输入名称"
  178 + />
  179 + </ProForm.Group>
  180 +
  181 + <ProForm.Group>
  182 + <ProFormText
  183 + width="sm"
  184 + name="name2"
  185 + initialValue={"发货款"}
  186 + disabled
  187 + tooltip="最长为 24 位"
  188 + placeholder="请输入名称"
  189 + />
  190 +
  191 + <ProFormText
  192 + width="sm"
  193 + name="company"
  194 + placeholder="请输入名称"
  195 + />
  196 +
  197 + <ProFormText
  198 + width="sm"
  199 + name="price"
  200 + placeholder="请输入名称"
  201 + />
  202 +
  203 + <ProFormText
  204 + width="sm"
  205 + name="notes"
  206 + placeholder="请输入名称"
  207 + />
  208 + </ProForm.Group>
  209 +
  210 + <ProForm.Group>
  211 + <ProFormText
  212 + width="sm"
  213 + name="name3"
  214 + initialValue={"验收款"}
  215 + disabled
  216 + tooltip="最长为 24 位"
  217 + placeholder="请输入名称"
  218 + />
  219 +
  220 + <ProFormText
  221 + width="sm"
  222 + name="company"
  223 + placeholder="请输入名称"
  224 + />
  225 +
  226 + <ProFormText
  227 + width="sm"
  228 + name="price"
  229 + placeholder="请输入名称"
  230 + />
  231 +
  232 + <ProFormText
  233 + width="sm"
  234 + name="notes"
  235 + placeholder="请输入名称"
  236 + />
  237 + </ProForm.Group>
  238 +
  239 + <ProForm.Group>
  240 + <ProFormText
  241 + width="sm"
  242 + name="name4"
  243 + disabled
  244 + initialValue={"尾款"}
  245 + tooltip="最长为 24 位"
  246 + placeholder="请输入名称"
  247 + />
  248 +
  249 + <ProFormText
  250 + width="sm"
  251 + name="company"
  252 + placeholder="请输入名称"
  253 + />
  254 +
  255 + <ProFormText
  256 + width="sm"
  257 + name="price"
  258 + placeholder="请输入名称"
  259 + />
  260 +
  261 + <ProFormText
  262 + width="sm"
  263 + name="notes"
  264 + placeholder="请输入名称"
  265 + />
  266 + </ProForm.Group> */}
  267 + </ModalForm>
  268 + </>
  269 + );
  270 +};
... ...
src/pages/Order/OrderWarning/components/HistoryModal.tsx 0 → 100644
  1 +import { postServiceOrderQueryHistoryOrderRecord } from '@/services';
  2 +import { formatDateTime } from '@/utils';
  3 +import { Button, Col, Empty, Flex, Modal, Row, Spin } from 'antd';
  4 +import { useEffect, useState } from 'react';
  5 +
  6 +export default ({ subOrders, isCancelledOrder, onClose }) => {
  7 + let subOrderIds = subOrders?.map((subOrder: any) => {
  8 + return subOrder.id;
  9 + });
  10 +
  11 + const [data, setData] = useState([]);
  12 + const [loading, setLoading] = useState(true);
  13 + let i = 0;
  14 +
  15 + const handleOk = () => {
  16 + onClose();
  17 + };
  18 +
  19 + /**
  20 + * 获取历史记录
  21 + */
  22 + const getHistory = async () => {
  23 + let res = await postServiceOrderQueryHistoryOrderRecord({
  24 + data: { ids: subOrderIds, isDeleteQueryOrder: isCancelledOrder },
  25 + });
  26 + setData(res.data);
  27 + setLoading(false);
  28 + };
  29 +
  30 + const getRecord = (history: any) => {
  31 + let record = [];
  32 + record.push(
  33 + <span className="pr-2 text-[#5E5E5E]">
  34 + {formatDateTime(history.createTime)}
  35 + </span>,
  36 + );
  37 +
  38 + record.push(<span className="text-[#3b83e5]">{history.createByName}</span>);
  39 +
  40 + record.push(<span>进行了</span>);
  41 +
  42 + // let label = enumValueToLabel(history.status, ORDER_STATUS_OPTIONS);
  43 +
  44 + // if (
  45 + // history.record !== 'INVOICING' && history.record !== 'order-change-normal' && history.record !== 'order-change-normal-CHECK' &&
  46 + // history.record?.indexOf(':') === -1 &&
  47 + // label !== undefined &&
  48 + // label !== ''
  49 + // ) {
  50 + // record.push(
  51 + // <>
  52 + // <span>,订单状态为:</span>
  53 + // <span className="text-[#3b83e5]">{label}</span>
  54 + // </>,
  55 + // );
  56 + // }
  57 +
  58 + if (history.record?.indexOf(':') !== -1) {
  59 + let values = history.record?.split(':');
  60 + let type = values[0];
  61 + let target = values[1];
  62 + if (target === 'null') {
  63 + target = '未指定';
  64 + }
  65 + //采购转发
  66 + if (type === 'PROCURE_CONVERT_PROCURE') {
  67 + record.push(
  68 + <>
  69 + <span>采购转发,{history.createByName}将订单转发给了</span>
  70 + <span className="text-[#3b83e5]">{target}</span>
  71 + </>,
  72 + );
  73 + }
  74 + } else {
  75 + record.push(
  76 + <span className="text-[#3b83e5]">
  77 + {history.recordText +
  78 + (history.record === 'INVOICING'
  79 + ? '(开票号码:' + history.invoiceNumber + ')'
  80 + : '')}
  81 + </span>,
  82 + );
  83 + }
  84 +
  85 + if (history.notes !== null) {
  86 + record.push(<span className="pl-1">{'备注:' + history.notes}</span>);
  87 + }
  88 +
  89 + if (history.description !== null) {
  90 + record.push(
  91 + <span className="pl-1">{'描述:' + history.description}</span>,
  92 + );
  93 + }
  94 +
  95 + return record;
  96 + };
  97 +
  98 + useEffect(() => {
  99 + getHistory();
  100 + }, []);
  101 +
  102 + const handleCancel = () => {
  103 + onClose();
  104 + };
  105 +
  106 + return (
  107 + <>
  108 + <Modal
  109 + title="订单历史记录"
  110 + open
  111 + width={650}
  112 + onOk={handleOk}
  113 + onCancel={handleCancel}
  114 + footer={() => (
  115 + <>
  116 + <Button onClick={handleCancel}>返回</Button>
  117 + </>
  118 + )}
  119 + >
  120 + <Spin tip="加载中" spinning={loading}>
  121 + <Row className="max-h-[500px] overflow-auto" gutter={[0, 14]}>
  122 + {data.map((item) => {
  123 + return (
  124 + <Col span={24} key={i}>
  125 + <Flex vertical>
  126 + <div>
  127 + <span className="py-2 text-[#5E5E5E]">
  128 + {'商品' + ++i}
  129 + </span>
  130 + <span className="text-[#8C8C8C]">
  131 + -【{item.productName}】
  132 + </span>
  133 + </div>
  134 +
  135 + <Flex vertical>
  136 + {item.historySubOrderRecordDto?.map((history) => {
  137 + return (
  138 + <div className="py-1" key={history.id}>
  139 + {getRecord(history)}
  140 + </div>
  141 + );
  142 + })}
  143 + </Flex>
  144 + </Flex>
  145 + </Col>
  146 + );
  147 + })}
  148 + </Row>
  149 + {data?.length <= 0 ? (
  150 + <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  151 + ) : (
  152 + ''
  153 + )}
  154 + </Spin>
  155 + </Modal>
  156 + </>
  157 + );
  158 +};
... ...
src/pages/Order/OrderWarning/components/ImagesViewerModal.tsx 0 → 100644
  1 +import { postServiceOrderViewImages } from '@/services';
  2 +import { Button, Divider, Image, Modal } from 'antd';
  3 +import { useEffect, useState } from 'react';
  4 +export default ({ setVisible, optType, onClose, orderRow }) => {
  5 + const [images, setImages] = useState<any[]>([]);
  6 + const [title, setTitle] = useState("收货凭证");
  7 + const handleOk = () => {
  8 + onClose();
  9 + setVisible(false);
  10 + };
  11 +
  12 + const handleCancel = () => {
  13 + onClose();
  14 + setVisible(false);
  15 + };
  16 +
  17 + async function getImages() {
  18 + const res = await postServiceOrderViewImages({
  19 + data: { subId: orderRow.id },
  20 + });
  21 + const images = res.data;
  22 + setImages(images);
  23 + }
  24 + useEffect(() => {
  25 + if (optType === 'shippingReceipt') {
  26 + setTitle("收货凭证");
  27 + getImages();
  28 + } else if (optType === 'paymentReceipt') {
  29 + let paymentReceiptsImagesList: any[] = [];
  30 + if (orderRow.paymentReceiptAnnexList) {
  31 + paymentReceiptsImagesList.push(...orderRow.paymentReceiptAnnexList);
  32 + }
  33 + //去重
  34 + paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)];
  35 + setImages(paymentReceiptsImagesList);
  36 + }
  37 +
  38 + }, []);
  39 +
  40 + return (
  41 + <>
  42 + <Modal
  43 + title={title}
  44 + open
  45 + onOk={handleOk}
  46 + onCancel={handleCancel}
  47 + footer={[
  48 + <Button key="back" onClick={handleCancel}>
  49 + 返回
  50 + </Button>,
  51 + ]}
  52 + >
  53 + <Image.PreviewGroup
  54 + className="mr-10"
  55 + preview={{
  56 + onChange: (current, prev) =>
  57 + console.log(`current index: ${current}, prev index: ${prev}`),
  58 + }}
  59 + >
  60 + {images.map((url) => (
  61 + <>
  62 + <Image width={120} src={url} /> <Divider type="vertical" />
  63 + </>
  64 + ))}
  65 + </Image.PreviewGroup>
  66 + </Modal>
  67 + </>
  68 + );
  69 +};
... ...
src/pages/Order/OrderWarning/components/ImportExpressBillModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { postOrderImportImportWeightAndVolume } from '@/services';
  3 +import { ModalForm, ProFormUploadDragger } from '@ant-design/pro-components';
  4 +import { Button, Form, message } from 'antd';
  5 +
  6 +export default () => {
  7 + const [form] = Form.useForm();
  8 + const [messageApi, contextHolder] = message.useMessage();
  9 + return (
  10 + <>
  11 + <ModalForm
  12 + title="导入重量、体积"
  13 + trigger={<Button type="primary">导入重量、体积</Button>}
  14 + form={form}
  15 + autoFocusFirstInput
  16 + modalProps={{
  17 + destroyOnClose: true,
  18 + }}
  19 + submitTimeout={2000}
  20 + onFinish={async (values) => {
  21 + console.log(values);
  22 + const formData = new FormData();
  23 + formData.append('file', values.express[0].originFileObj);
  24 + messageApi.open({
  25 + type: 'loading',
  26 + content: '正在导入...',
  27 + duration: 0,
  28 + });
  29 + const res = await postOrderImportImportWeightAndVolume({
  30 + data: formData,
  31 + headers: {
  32 + 'Content-Type':
  33 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  34 + },
  35 + });
  36 + if (res.result === RESPONSE_CODE.SUCCESS) {
  37 + message.error('导入成功');
  38 + } else {
  39 + message.error('导入失败');
  40 + }
  41 + messageApi.destroy();
  42 + return true;
  43 + }}
  44 + >
  45 + <ProFormUploadDragger max={1} label="上传快递单" name="express" />
  46 + </ModalForm>
  47 + {contextHolder}
  48 + </>
  49 + );
  50 +};
... ...
src/pages/Order/OrderWarning/components/ImportModal.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import { postServiceOrderImportExcel } from '@/services';
  3 +import { orderExport } from '@/services/order';
  4 +import { UploadOutlined } from '@ant-design/icons';
  5 +import { Button, Modal, Upload, message } from 'antd';
  6 +import { RcFile, UploadFile, UploadProps } from 'antd/es/upload';
  7 +import { useState } from 'react';
  8 +export default ({ onClose }) => {
  9 + // const [form] = Form.useForm<{ name: string; company: string }>();
  10 + const [messageApi, contextHolder] = message.useMessage();
  11 + const [fileList, setFileList] = useState<UploadFile[]>([]);
  12 + const [uploading, setUploading] = useState(false);
  13 + const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>
  14 + setFileList(newFileList);
  15 +
  16 + const exportLoading = (content: string) => {
  17 + messageApi.open({
  18 + type: 'loading',
  19 + content: content,
  20 + duration: 0,
  21 + });
  22 + };
  23 +
  24 + const exportLoadingDestory = () => {
  25 + messageApi.destroy();
  26 + };
  27 + const downloadTemplate = async () => {
  28 + exportLoading('正在下载模板...');
  29 + orderExport(
  30 + '/api/service/order/exportTemplate',
  31 + '订单.xlsx',
  32 + 'post',
  33 + {},
  34 + exportLoadingDestory,
  35 + );
  36 + };
  37 +
  38 + const handleUpload = async () => {
  39 + const formData = new FormData();
  40 + fileList.forEach((file) => {
  41 + //originFileObj二进制文件
  42 + formData.append('file', file.originFileObj as RcFile);
  43 + });
  44 + // console.log(fileList[0] as RcFile)
  45 + // formData.append('file', fileList[0] as RcFile);
  46 + setUploading(true);
  47 + // You can use any AJAX library you like
  48 + const res = await postServiceOrderImportExcel({
  49 + data: formData,
  50 + headers: {
  51 + 'Content-Type':
  52 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  53 + },
  54 + });
  55 +
  56 + if (res.result === RESPONSE_CODE.SUCCESS) {
  57 + message.success(res.message);
  58 + onClose();
  59 + } else {
  60 + if (res.message === '表格中没有数据') {
  61 + setUploading(false);
  62 + return;
  63 + }
  64 + //存在错误信息,下载错误信息模板
  65 + exportLoading('正在下载错误信息...');
  66 + orderExport(
  67 + '/api/service/order/errorExcelInformation',
  68 + '订单.xlsx',
  69 + 'post',
  70 + formData,
  71 + exportLoadingDestory,
  72 + );
  73 + }
  74 +
  75 + setUploading(false);
  76 + };
  77 +
  78 + const props: UploadProps = {
  79 + onRemove: (file) => {
  80 + const index = fileList.indexOf(file);
  81 + const newFileList = fileList.slice();
  82 + newFileList.splice(index, 1);
  83 + setFileList(newFileList);
  84 + },
  85 + beforeUpload: (file) => {
  86 + setFileList([...fileList, file]);
  87 +
  88 + return false;
  89 + },
  90 + fileList,
  91 + onChange: handleChange,
  92 + accept: '.xlsx',
  93 + };
  94 +
  95 + return (
  96 + <>
  97 + <Modal
  98 + width={500}
  99 + open
  100 + title="批量发货"
  101 + footer={[
  102 + <Button key="cancel" onClick={onClose}>
  103 + 取消
  104 + </Button>,
  105 + <Button
  106 + type="primary"
  107 + key="ok"
  108 + onClick={handleUpload}
  109 + disabled={fileList.length === 0}
  110 + loading={uploading}
  111 + >
  112 + {uploading ? '上传中' : '提交'}
  113 + </Button>,
  114 + ]}
  115 + onCancel={async () => {
  116 + onClose();
  117 + }}
  118 + >
  119 + <div className="py-4 font-semibold">
  120 + 导入发货信息
  121 + <Button type="link" onClick={downloadTemplate}>
  122 + 下载模板
  123 + </Button>
  124 + </div>
  125 + <Upload {...props}>
  126 + <Button icon={<UploadOutlined />} disabled={fileList.length > 0}>
  127 + 点击选择文件
  128 + </Button>
  129 + </Upload>
  130 + </Modal>
  131 + {contextHolder}
  132 + </>
  133 + );
  134 +};
... ...
src/pages/Order/OrderWarning/components/InvoiceSubOrderInfoTable.tsx 0 → 100644
  1 +import { postServiceOrderGetReissueInfo } from '@/services';
  2 +import type { ProColumns } from '@ant-design/pro-components';
  3 +import { ProTable } from '@ant-design/pro-components';
  4 +import { Button, Divider } from 'antd';
  5 +import { useEffect, useState } from 'react';
  6 +
  7 +const columns: ProColumns[] = [
  8 + {
  9 + title: '发票号码',
  10 + width: 80,
  11 + dataIndex: 'invoiceNumber',
  12 + render: (_) => _,
  13 + },
  14 + {
  15 + title: '关联订单',
  16 + dataIndex: 'subOrderIds',
  17 + render: (_, { subOrderIds }) => {
  18 + console.log(JSON.stringify(_));
  19 + console.log(JSON.stringify(subOrderIds));
  20 + return (
  21 + <>
  22 + {subOrderIds.map((subOrderId, index) => {
  23 + return (
  24 + <>
  25 + <Button
  26 + key={index}
  27 + className="pl-1 pr-0"
  28 + type="link"
  29 + target="_blank"
  30 + href={'/order?id=' + subOrderId}
  31 + >
  32 + {subOrderId}
  33 + </Button>
  34 + <Divider type="vertical" />
  35 + </>
  36 + );
  37 + })}
  38 + </>
  39 + );
  40 + },
  41 + },
  42 +];
  43 +
  44 +export default ({ subOrderIds }) => {
  45 + const [reissueInfos, setReissueInfos] = useState([]);
  46 + useEffect(() => {
  47 + console.log('info');
  48 + const getReissueInfo = async () => {
  49 + let res = await postServiceOrderGetReissueInfo({
  50 + data: subOrderIds,
  51 + });
  52 + setReissueInfos(res.data);
  53 + };
  54 + getReissueInfo();
  55 + }, []);
  56 + return (
  57 + <ProTable
  58 + dataSource={reissueInfos}
  59 + rowKey="key"
  60 + pagination={false}
  61 + size={'small'}
  62 + //设置左右下边距为0
  63 + options={false}
  64 + columns={columns}
  65 + search={false}
  66 + dateFormatter="string"
  67 + headerTitle="发票信息"
  68 + />
  69 + );
  70 +};
... ...