Commit fa87b7a24a4dab45a1a7b577f64f3e9bb249dd3b
Merge branch 'feature-installment2' into 'master'
Feature installment2 See merge request !61
Showing
12 changed files
with
1337 additions
and
91 deletions
src/pages/Order/OrderList/CheckModal.tsx
@@ -70,6 +70,8 @@ export default ({ | @@ -70,6 +70,8 @@ export default ({ | ||
70 | 70 | ||
71 | const [afterSalesInfo, setAfterSalesInfo] = useState<any>(); | 71 | const [afterSalesInfo, setAfterSalesInfo] = useState<any>(); |
72 | const [prepaidProofImages, setPrepaidProofImages] = useState<any[]>([]); | 72 | const [prepaidProofImages, setPrepaidProofImages] = useState<any[]>([]); |
73 | + const [partialPaymentReceiptsImages, setPartialPaymentReceiptsImages] = | ||
74 | + useState<any[]>([]); | ||
73 | /** | 75 | /** |
74 | * 审核类型 | 76 | * 审核类型 |
75 | */ | 77 | */ |
@@ -129,6 +131,7 @@ export default ({ | @@ -129,6 +131,7 @@ export default ({ | ||
129 | } | 131 | } |
130 | getOrderAfterSalesInfo(); | 132 | getOrderAfterSalesInfo(); |
131 | 133 | ||
134 | + // 常规回款凭证 | ||
132 | let paymentReceiptsImagesList: any[] = []; | 135 | let paymentReceiptsImagesList: any[] = []; |
133 | subOrders?.forEach((item: any) => { | 136 | subOrders?.forEach((item: any) => { |
134 | if (item.paymentReceiptAnnexList) { | 137 | if (item.paymentReceiptAnnexList) { |
@@ -139,6 +142,22 @@ export default ({ | @@ -139,6 +142,22 @@ export default ({ | ||
139 | paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)]; | 142 | paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)]; |
140 | setPymentReceiptsImages(paymentReceiptsImagesList); | 143 | setPymentReceiptsImages(paymentReceiptsImagesList); |
141 | 144 | ||
145 | + // 分期付款凭证从 subOrderInformationLists 获取 | ||
146 | + let partialPaymentImages: any[] = []; | ||
147 | + if ( | ||
148 | + checkType(CHECK_TYPE.PARTIAL_PAYMENT_RECEIPTS_AUDIT) && | ||
149 | + data?.subOrderInformationLists | ||
150 | + ) { | ||
151 | + data.subOrderInformationLists.forEach((subOrder: any) => { | ||
152 | + if (subOrder.paymentReceiptAnnexPartialList) { | ||
153 | + partialPaymentImages.push(...subOrder.paymentReceiptAnnexPartialList); | ||
154 | + } | ||
155 | + }); | ||
156 | + } | ||
157 | + // 去重 | ||
158 | + partialPaymentImages = [...new Set(partialPaymentImages)]; | ||
159 | + setPartialPaymentReceiptsImages(partialPaymentImages); | ||
160 | + | ||
142 | //预存审核的凭证 | 161 | //预存审核的凭证 |
143 | let proofImages: any[] = []; | 162 | let proofImages: any[] = []; |
144 | subOrders?.forEach((item) => { | 163 | subOrders?.forEach((item) => { |
@@ -403,7 +422,10 @@ export default ({ | @@ -403,7 +422,10 @@ export default ({ | ||
403 | if (checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING)) { | 422 | if (checkType(CHECK_TYPE.URGENT_INVOICE_AUDITING)) { |
404 | type = 'urgent_invoice_audit'; | 423 | type = 'urgent_invoice_audit'; |
405 | } | 424 | } |
406 | - if (checkType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT)) { | 425 | + if ( |
426 | + checkType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT) || | ||
427 | + checkType(CHECK_TYPE.PARTIAL_PAYMENT_RECEIPTS_AUDIT) | ||
428 | + ) { | ||
407 | type = 'payment_receipt_audit'; | 429 | type = 'payment_receipt_audit'; |
408 | } | 430 | } |
409 | if (checkType(CHECK_TYPE.CONFIRM_REISSUE)) { | 431 | if (checkType(CHECK_TYPE.CONFIRM_REISSUE)) { |
@@ -585,6 +607,18 @@ export default ({ | @@ -585,6 +607,18 @@ export default ({ | ||
585 | }); | 607 | }); |
586 | } | 608 | } |
587 | 609 | ||
610 | + // 分期回款审核处理 | ||
611 | + if (checkType(CHECK_TYPE.PARTIAL_PAYMENT_RECEIPTS_AUDIT)) { | ||
612 | + let type = computeType(); | ||
613 | + return doCheck({ | ||
614 | + ...values, | ||
615 | + pass: true, | ||
616 | + subOrderIds: subOrderIds, | ||
617 | + type: type, | ||
618 | + notes: form.getFieldValue('name'), | ||
619 | + }); | ||
620 | + } | ||
621 | + | ||
588 | let type = ''; | 622 | let type = ''; |
589 | type = computeType(); | 623 | type = computeType(); |
590 | doCheck({ | 624 | doCheck({ |
@@ -621,7 +655,6 @@ export default ({ | @@ -621,7 +655,6 @@ export default ({ | ||
621 | <span className="text-sm">回款凭证</span> | 655 | <span className="text-sm">回款凭证</span> |
622 | </Divider> | 656 | </Divider> |
623 | <Image.PreviewGroup | 657 | <Image.PreviewGroup |
624 | - className="mr-10" | ||
625 | preview={{ | 658 | preview={{ |
626 | onChange: (current, prev) => | 659 | onChange: (current, prev) => |
627 | console.log(`current index: ${current}, prev index: ${prev}`), | 660 | console.log(`current index: ${current}, prev index: ${prev}`), |
@@ -639,13 +672,54 @@ export default ({ | @@ -639,13 +672,54 @@ export default ({ | ||
639 | '' | 672 | '' |
640 | )} | 673 | )} |
641 | 674 | ||
675 | + {checkType(CHECK_TYPE.PARTIAL_PAYMENT_RECEIPTS_AUDIT) ? ( | ||
676 | + <> | ||
677 | + <Row gutter={[16, 16]}> | ||
678 | + <Col span={24}> | ||
679 | + <div className="mb-2"> | ||
680 | + <span className="font-semibold">回款类型:</span> | ||
681 | + <span>分期付款</span> | ||
682 | + </div> | ||
683 | + </Col> | ||
684 | + <Col span={24}> | ||
685 | + <div className="mb-2"> | ||
686 | + <span className="font-semibold">回款金额:</span> | ||
687 | + <span>{data?.installmentMoney || 0} 元</span> | ||
688 | + </div> | ||
689 | + </Col> | ||
690 | + <Col span={24}> | ||
691 | + <div className="mb-2 font-semibold">附件凭证:</div> | ||
692 | + <div> | ||
693 | + <Image.PreviewGroup | ||
694 | + preview={{ | ||
695 | + onChange: (current, prev) => | ||
696 | + console.log( | ||
697 | + `current index: ${current}, prev index: ${prev}`, | ||
698 | + ), | ||
699 | + }} | ||
700 | + > | ||
701 | + {partialPaymentReceiptsImages.map((url, index) => ( | ||
702 | + <span key={`img-${index}`}> | ||
703 | + <Image width={120} src={url} />{' '} | ||
704 | + <Divider type="vertical" /> | ||
705 | + </span> | ||
706 | + ))} | ||
707 | + </Image.PreviewGroup> | ||
708 | + </div> | ||
709 | + </Col> | ||
710 | + </Row> | ||
711 | + <Divider></Divider> | ||
712 | + </> | ||
713 | + ) : ( | ||
714 | + '' | ||
715 | + )} | ||
716 | + | ||
642 | {checkType(CHECK_TYPE.PREPAID_AUDIT) && ( | 717 | {checkType(CHECK_TYPE.PREPAID_AUDIT) && ( |
643 | <> | 718 | <> |
644 | <Divider orientation="center"> | 719 | <Divider orientation="center"> |
645 | <span className="text-sm">凭证</span> | 720 | <span className="text-sm">凭证</span> |
646 | </Divider> | 721 | </Divider> |
647 | <Image.PreviewGroup | 722 | <Image.PreviewGroup |
648 | - className="mr-10" | ||
649 | preview={{ | 723 | preview={{ |
650 | onChange: (current, prev) => | 724 | onChange: (current, prev) => |
651 | console.log(`current index: ${current}, prev index: ${prev}`), | 725 | console.log(`current index: ${current}, prev index: ${prev}`), |
src/pages/Order/OrderList/HirePurchaseUploadPayBillModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { | ||
3 | + postServiceOrderFileProcess, | ||
4 | + postServiceOrderHirePurchase, | ||
5 | +} from '@/services'; | ||
6 | +import { transImageFile } from '@/utils'; | ||
7 | +import { PlusOutlined } from '@ant-design/icons'; | ||
8 | +import { Button, Form, Input, Modal, Upload, message } from 'antd'; | ||
9 | +import { RcFile } from 'antd/lib/upload'; | ||
10 | +import { UploadFile, UploadProps } from 'antd/lib/upload/interface'; | ||
11 | +import { cloneDeep } from 'lodash'; | ||
12 | +import { useEffect, useRef, useState } from 'react'; | ||
13 | +import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../constant'; | ||
14 | + | ||
15 | +interface HirePurchaseUploadPayBillModalProps { | ||
16 | + visible: boolean; | ||
17 | + onCancel: () => void; | ||
18 | + onOk: () => void; | ||
19 | + orderAmount?: number; | ||
20 | + paidAmount?: number; | ||
21 | + record?: any; | ||
22 | + subOrders?: any[]; | ||
23 | +} | ||
24 | + | ||
25 | +const HirePurchaseUploadPayBillModal: React.FC< | ||
26 | + HirePurchaseUploadPayBillModalProps | ||
27 | +> = ({ | ||
28 | + visible, | ||
29 | + onCancel, | ||
30 | + onOk, | ||
31 | + orderAmount = 100000.0, | ||
32 | + paidAmount = 0, | ||
33 | + record, | ||
34 | + subOrders = [], | ||
35 | +}) => { | ||
36 | + // 订单总金额 | ||
37 | + const totalPayment = record?.totalPayment || orderAmount; | ||
38 | + // 已回款金额 | ||
39 | + const installedMoney = record?.installmentMoneyAudit || paidAmount; | ||
40 | + // 待回款金额 | ||
41 | + const remainingMoney = totalPayment - installedMoney; | ||
42 | + const [form] = Form.useForm(); | ||
43 | + const [fileList, setFileList] = useState<UploadFile[]>([]); | ||
44 | + const [paymentType] = useState<string>('INSTALLMENT'); | ||
45 | + const [previewOpen, setPreviewOpen] = useState(false); | ||
46 | + const [previewImage, setPreviewImage] = useState(''); | ||
47 | + const [previewTitle, setPreviewTitle] = useState(''); | ||
48 | + | ||
49 | + const fileListObj = useRef<UploadFile[]>([]); | ||
50 | + | ||
51 | + const getBase64 = (file: RcFile): Promise<string> => | ||
52 | + new Promise((resolve, reject) => { | ||
53 | + const reader = new FileReader(); | ||
54 | + reader.readAsDataURL(file); | ||
55 | + reader.onload = () => resolve(reader.result as string); | ||
56 | + reader.onerror = (error) => reject(error); | ||
57 | + }); | ||
58 | + | ||
59 | + const handleCancel = () => setPreviewOpen(false); | ||
60 | + | ||
61 | + const uploadButton = ( | ||
62 | + <div> | ||
63 | + <PlusOutlined /> | ||
64 | + <div style={{ marginTop: 8 }}>上传凭证</div> | ||
65 | + </div> | ||
66 | + ); | ||
67 | + | ||
68 | + // const handleTypeChange = (e: any) => { | ||
69 | + // const newType = e.target.value; | ||
70 | + // setPaymentType(newType); | ||
71 | + | ||
72 | + // // 如果选择全部回款,自动填入待回款金额 | ||
73 | + // if (newType === 'FULL') { | ||
74 | + // form.setFieldsValue({ | ||
75 | + // amount: remainingMoney.toFixed(2), | ||
76 | + // }); | ||
77 | + // } | ||
78 | + // }; | ||
79 | + | ||
80 | + // 验证回款金额不能超过待回款金额 | ||
81 | + const validateAmount = (_: any, value: string) => { | ||
82 | + // Check if the value is a valid number | ||
83 | + if (isNaN(value)) return Promise.reject('请输入有效的数字'); | ||
84 | + | ||
85 | + // Check if the value has more than 2 decimal places | ||
86 | + const decimalCount = (value.match(/\.\d+/) || [''])[0].length - 1; | ||
87 | + if (decimalCount > 2) { | ||
88 | + return Promise.reject('最多只能输入两位小数'); | ||
89 | + } | ||
90 | + | ||
91 | + const amount = parseFloat(value); | ||
92 | + if (amount <= 0) return Promise.reject('回款金额必须大于0'); | ||
93 | + if (amount > remainingMoney) | ||
94 | + return Promise.reject( | ||
95 | + `回款金额不能超过待回款金额 ${remainingMoney.toFixed(2)}元`, | ||
96 | + ); | ||
97 | + | ||
98 | + return Promise.resolve(); | ||
99 | + }; | ||
100 | + | ||
101 | + const handleBeforeUpload = (file: any) => { | ||
102 | + setFileList([...fileList, file]); | ||
103 | + return false; | ||
104 | + }; | ||
105 | + | ||
106 | + /** 粘贴快捷键的回调 */ | ||
107 | + const onPaste = async (e: any) => { | ||
108 | + /** 获取剪切板的数据clipboardData */ | ||
109 | + let clipboardData = e.clipboardData, | ||
110 | + i = 0, | ||
111 | + items, | ||
112 | + item, | ||
113 | + types; | ||
114 | + | ||
115 | + /** 为空判断 */ | ||
116 | + if (clipboardData) { | ||
117 | + items = clipboardData.items; | ||
118 | + if (!items) { | ||
119 | + message.info('您的剪贴板中没有照片'); | ||
120 | + return; | ||
121 | + } | ||
122 | + | ||
123 | + item = items[0]; | ||
124 | + types = clipboardData.types || []; | ||
125 | + /** 遍历剪切板的数据 */ | ||
126 | + for (; i < types.length; i++) { | ||
127 | + if (types[i] === 'Files') { | ||
128 | + item = items[i]; | ||
129 | + break; | ||
130 | + } | ||
131 | + } | ||
132 | + | ||
133 | + /** 判断文件是否为图片 */ | ||
134 | + if (item && item.kind === 'file' && item.type.match(/^image\//i)) { | ||
135 | + const imgItem = item.getAsFile(); | ||
136 | + const newFileList = cloneDeep(fileListObj.current); | ||
137 | + let filteredArray = newFileList.filter( | ||
138 | + (obj) => obj.status !== 'removed', | ||
139 | + ); //过滤掉状态为已删除的照片 | ||
140 | + const listItem = { | ||
141 | + ...imgItem, | ||
142 | + status: 'done', | ||
143 | + url: await getBase64(imgItem), | ||
144 | + originFileObj: imgItem, | ||
145 | + }; | ||
146 | + | ||
147 | + if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) { | ||
148 | + message.info('上传凭证数量不能超过3'); | ||
149 | + return; | ||
150 | + } | ||
151 | + fileListObj.current = filteredArray; | ||
152 | + filteredArray.push(listItem); | ||
153 | + setFileList(filteredArray); | ||
154 | + return; | ||
155 | + } | ||
156 | + } | ||
157 | + | ||
158 | + message.info('您的剪贴板中没有照片'); | ||
159 | + }; | ||
160 | + | ||
161 | + const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { | ||
162 | + fileListObj.current = newFileList; | ||
163 | + setFileList(newFileList); | ||
164 | + }; | ||
165 | + | ||
166 | + const handlePreview = async (file: UploadFile) => { | ||
167 | + if (!file.url && !file.preview) { | ||
168 | + file.preview = await getBase64(file.originFileObj as RcFile); | ||
169 | + } | ||
170 | + setPreviewImage(file.url || (file.preview as string)); | ||
171 | + setPreviewOpen(true); | ||
172 | + setPreviewTitle( | ||
173 | + file.name || | ||
174 | + file.originFileObj?.name || | ||
175 | + file.url!.substring(file.url!.lastIndexOf('/') + 1), | ||
176 | + ); | ||
177 | + }; | ||
178 | + | ||
179 | + const props: UploadProps = { | ||
180 | + onRemove: (file) => { | ||
181 | + const index = fileList.indexOf(file); | ||
182 | + const newFileList = fileList.slice(); | ||
183 | + newFileList.splice(index, 1); | ||
184 | + setFileList(newFileList); | ||
185 | + }, | ||
186 | + beforeUpload: handleBeforeUpload, | ||
187 | + listType: 'picture-card', | ||
188 | + onPreview: handlePreview, | ||
189 | + fileList, | ||
190 | + onChange: handleChange, | ||
191 | + accept: 'image/png, image/jpeg, image/png', | ||
192 | + name: 'files', | ||
193 | + headers: { Authorization: localStorage.getItem('token') }, | ||
194 | + }; | ||
195 | + | ||
196 | + useEffect(() => { | ||
197 | + document.addEventListener('paste', onPaste); | ||
198 | + return () => { | ||
199 | + document.removeEventListener('paste', onPaste); | ||
200 | + }; | ||
201 | + }, []); | ||
202 | + | ||
203 | + const handleOk = async () => { | ||
204 | + try { | ||
205 | + const values = await form.validateFields(); | ||
206 | + | ||
207 | + if (fileList.length <= 0) { | ||
208 | + message.error('请上传至少一张凭证'); | ||
209 | + return; | ||
210 | + } | ||
211 | + | ||
212 | + message.open({ | ||
213 | + type: 'loading', | ||
214 | + content: '正在上传凭证...', | ||
215 | + duration: 0, | ||
216 | + }); | ||
217 | + | ||
218 | + // 附件处理 | ||
219 | + let formData = new FormData(); | ||
220 | + for (let file of fileList) { | ||
221 | + if (file.originFileObj) { | ||
222 | + formData.append('files', file.originFileObj as RcFile); | ||
223 | + } else { | ||
224 | + // 有url的话取url(源文件),没url取thumbUrl。有url的时候thumbUrl是略缩图 | ||
225 | + if (file?.url === undefined || file?.url === null) { | ||
226 | + formData.append( | ||
227 | + 'files', | ||
228 | + transImageFile(file?.thumbUrl), | ||
229 | + file?.originFileObj?.name, | ||
230 | + ); | ||
231 | + } else { | ||
232 | + formData.append( | ||
233 | + 'files', | ||
234 | + transImageFile(file?.url), | ||
235 | + file?.originFileObj?.name, | ||
236 | + ); | ||
237 | + } | ||
238 | + } | ||
239 | + } | ||
240 | + | ||
241 | + let res = await postServiceOrderFileProcess({ | ||
242 | + data: formData, | ||
243 | + }); | ||
244 | + | ||
245 | + message.destroy(); | ||
246 | + | ||
247 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
248 | + let fileUrls = res?.data?.map((item) => { | ||
249 | + return { url: item }; | ||
250 | + }); | ||
251 | + | ||
252 | + // 分期付款提交 | ||
253 | + const installmentMoney = values.amount; | ||
254 | + const installmentComment = values.remarks; | ||
255 | + | ||
256 | + // 获取子订单IDs | ||
257 | + const subOrderIds = | ||
258 | + subOrders?.map((item: any) => { | ||
259 | + return item.id; | ||
260 | + }) || []; | ||
261 | + | ||
262 | + const data = await postServiceOrderHirePurchase({ | ||
263 | + data: { | ||
264 | + subOrderIds: subOrderIds, | ||
265 | + filePaths: fileUrls, | ||
266 | + installmentMoney: installmentMoney, | ||
267 | + installmentComment: installmentComment, | ||
268 | + }, | ||
269 | + }); | ||
270 | + | ||
271 | + if (data.result === RESPONSE_CODE.SUCCESS) { | ||
272 | + message.success(data.message || '提交成功'); | ||
273 | + onOk(); | ||
274 | + } else { | ||
275 | + message.error(data.message || '提交失败'); | ||
276 | + } | ||
277 | + } else { | ||
278 | + message.error(res.message || '上传失败'); | ||
279 | + } | ||
280 | + } catch (error) { | ||
281 | + console.error('Validate Failed:', error); | ||
282 | + message.error('提交失败'); | ||
283 | + } | ||
284 | + }; | ||
285 | + | ||
286 | + return ( | ||
287 | + <> | ||
288 | + <Modal | ||
289 | + title="回款" | ||
290 | + open={visible} | ||
291 | + onCancel={onCancel} | ||
292 | + footer={[ | ||
293 | + <Button key="cancel" onClick={onCancel}> | ||
294 | + 取消 | ||
295 | + </Button>, | ||
296 | + <Button key="submit" type="primary" onClick={handleOk}> | ||
297 | + 确认 | ||
298 | + </Button>, | ||
299 | + ]} | ||
300 | + width={500} | ||
301 | + > | ||
302 | + <Form form={form} layout="vertical"> | ||
303 | + <div style={{ marginBottom: 16 }}> | ||
304 | + <div | ||
305 | + style={{ | ||
306 | + display: 'flex', | ||
307 | + justifyContent: 'space-between', | ||
308 | + marginBottom: 8, | ||
309 | + }} | ||
310 | + > | ||
311 | + <span>订单总金额:</span> | ||
312 | + <span>{totalPayment.toFixed(2)}元</span> | ||
313 | + </div> | ||
314 | + <div | ||
315 | + style={{ | ||
316 | + display: 'flex', | ||
317 | + justifyContent: 'space-between', | ||
318 | + marginBottom: 8, | ||
319 | + }} | ||
320 | + > | ||
321 | + <span>已回款金额:</span> | ||
322 | + <span>{installedMoney.toFixed(2)}元</span> | ||
323 | + </div> | ||
324 | + <div | ||
325 | + style={{ | ||
326 | + display: 'flex', | ||
327 | + justifyContent: 'space-between', | ||
328 | + marginBottom: 8, | ||
329 | + }} | ||
330 | + > | ||
331 | + <span>待回款金额:</span> | ||
332 | + <span>{remainingMoney.toFixed(2)}元</span> | ||
333 | + </div> | ||
334 | + </div> | ||
335 | + <Form.Item | ||
336 | + label="回款金额" | ||
337 | + name="amount" | ||
338 | + rules={[ | ||
339 | + { required: true, message: '请输入回款金额' }, | ||
340 | + { validator: validateAmount }, | ||
341 | + ]} | ||
342 | + > | ||
343 | + <Input | ||
344 | + placeholder="请输入回款金额" | ||
345 | + suffix="元" | ||
346 | + disabled={paymentType === 'FULL'} | ||
347 | + /> | ||
348 | + </Form.Item> | ||
349 | + | ||
350 | + <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div> | ||
351 | + <Form.Item | ||
352 | + label="附件凭证" | ||
353 | + name="attachments" | ||
354 | + rules={[{ required: true, message: '请上传回款凭证' }]} | ||
355 | + > | ||
356 | + <Upload {...props}> | ||
357 | + {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER | ||
358 | + ? uploadButton | ||
359 | + : ''} | ||
360 | + </Upload> | ||
361 | + </Form.Item> | ||
362 | + </Form> | ||
363 | + </Modal> | ||
364 | + | ||
365 | + <Modal | ||
366 | + open={previewOpen} | ||
367 | + title={previewTitle} | ||
368 | + footer={null} | ||
369 | + onCancel={handleCancel} | ||
370 | + > | ||
371 | + <img alt="图片预览" style={{ width: '100%' }} src={previewImage} /> | ||
372 | + </Modal> | ||
373 | + </> | ||
374 | + ); | ||
375 | +}; | ||
376 | + | ||
377 | +export default HirePurchaseUploadPayBillModal; |
src/pages/Order/OrderList/ImagesViewerModal.tsx
@@ -3,7 +3,7 @@ import { Button, Divider, Image, Modal } from 'antd'; | @@ -3,7 +3,7 @@ import { Button, Divider, Image, Modal } from 'antd'; | ||
3 | import { useEffect, useState } from 'react'; | 3 | import { useEffect, useState } from 'react'; |
4 | export default ({ setVisible, optType, onClose, orderRow }) => { | 4 | export default ({ setVisible, optType, onClose, orderRow }) => { |
5 | const [images, setImages] = useState<any[]>([]); | 5 | const [images, setImages] = useState<any[]>([]); |
6 | - const [title, setTitle] = useState('收货凭证'); | 6 | + const [title, setTitle] = useState('收款凭证'); |
7 | const handleOk = () => { | 7 | const handleOk = () => { |
8 | onClose(); | 8 | onClose(); |
9 | setVisible(false); | 9 | setVisible(false); |
src/pages/Order/OrderList/OrderDrawer.tsx
@@ -75,6 +75,8 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -75,6 +75,8 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
75 | const [kingdeeCstomerModalVisible, setKingdeeCstomerModalVisible] = | 75 | const [kingdeeCstomerModalVisible, setKingdeeCstomerModalVisible] = |
76 | useState(false); | 76 | useState(false); |
77 | const [paymentMethod, setPaymentMethod] = useState(''); | 77 | const [paymentMethod, setPaymentMethod] = useState(''); |
78 | + const [paymentMethodDisabled, setPaymentMethodDisabled] = useState(false); | ||
79 | + const [paymentChannelDisabled, setPaymentChannelDisabled] = useState(false); | ||
78 | const [customerRequestCount, setCustomerRequestCount] = useState(0); | 80 | const [customerRequestCount, setCustomerRequestCount] = useState(0); |
79 | const [ | 81 | const [ |
80 | productParametersDisabledFlagList, | 82 | productParametersDisabledFlagList, |
@@ -307,6 +309,23 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -307,6 +309,23 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
307 | 309 | ||
308 | copyData.customerNameString = copyData.customerName; | 310 | copyData.customerNameString = copyData.customerName; |
309 | 311 | ||
312 | + // // 清空支付方式和支付渠道 | ||
313 | + // if ( | ||
314 | + // copyData.paymentChannel === 'TAOBAO' || | ||
315 | + // [ | ||
316 | + // 'UNPAID', | ||
317 | + // 'TAOBAO_ORDER_HAS_BEEN_PAID', | ||
318 | + // 'OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID', | ||
319 | + // 'WITHHOLDING_ADVANCE_DEPOSIT', | ||
320 | + // 'PLATFORM_SETTLEMENT', | ||
321 | + // 'PAYMENT_RECEIPT', | ||
322 | + // 'PREPAID_NO_NEED_SEND', | ||
323 | + // ].includes(copyData.paymentMethod) | ||
324 | + // ) { | ||
325 | + // copyData.paymentMethod = ''; | ||
326 | + // copyData.paymentChannel = ''; | ||
327 | + // } | ||
328 | + | ||
310 | setPaymentMethod(copyData.paymentMethod); | 329 | setPaymentMethod(copyData.paymentMethod); |
311 | 330 | ||
312 | //子订单数据处理:子订单在表单中的命名为list | 331 | //子订单数据处理:子订单在表单中的命名为list |
@@ -418,6 +437,30 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -418,6 +437,30 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
418 | if (optType('add')) { | 437 | if (optType('add')) { |
419 | form.resetFields(['list']); | 438 | form.resetFields(['list']); |
420 | } | 439 | } |
440 | + | ||
441 | + // 如果是复制操作,检查销售代码是否为淘宝相关代码 | ||
442 | + if (optType('copy')) { | ||
443 | + const salesCode = data?.salesCode; | ||
444 | + const isTaobaoSalesCode = [ | ||
445 | + 'TB', | ||
446 | + 'TBC', | ||
447 | + 'HCTB', | ||
448 | + '淘宝', | ||
449 | + 'TAOBAO', | ||
450 | + ].includes(salesCode); | ||
451 | + | ||
452 | + if (isTaobaoSalesCode) { | ||
453 | + // 锁定支付渠道和支付方式,但保留原有值 | ||
454 | + setPaymentChannelDisabled(true); | ||
455 | + setPaymentMethodDisabled(true); | ||
456 | + | ||
457 | + // 确保控制台日志 | ||
458 | + console.log('复制淘宝订单,锁定支付渠道和支付方式:', { | ||
459 | + paymentChannel: data?.paymentChannel, | ||
460 | + paymentMethod: data?.paymentMethod, | ||
461 | + }); | ||
462 | + } | ||
463 | + } | ||
421 | }, [data]); | 464 | }, [data]); |
422 | 465 | ||
423 | /** | 466 | /** |
@@ -954,9 +997,11 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -954,9 +997,11 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
954 | if (typeof values.erpCustomerId !== 'string') { | 997 | if (typeof values.erpCustomerId !== 'string') { |
955 | values.erpCustomerId = values.erpCustomerId?.id; | 998 | values.erpCustomerId = values.erpCustomerId?.id; |
956 | } | 999 | } |
1000 | + | ||
957 | values.province = province; | 1001 | values.province = province; |
958 | values.city = city; | 1002 | values.city = city; |
959 | values.district = district; | 1003 | values.district = district; |
1004 | + | ||
960 | // Handle the prepaidUid and privatePocket values for API submission | 1005 | // Handle the prepaidUid and privatePocket values for API submission |
961 | if ( | 1006 | if ( |
962 | values.paymentMethod === 'WITHHOLDING_ADVANCE_DEPOSIT' && | 1007 | values.paymentMethod === 'WITHHOLDING_ADVANCE_DEPOSIT' && |
@@ -1127,8 +1172,67 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -1127,8 +1172,67 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
1127 | placeholder="请输入销售代表" | 1172 | placeholder="请输入销售代表" |
1128 | rules={[{ required: true, message: '销售代表必填' }]} | 1173 | rules={[{ required: true, message: '销售代表必填' }]} |
1129 | options={salesCodeOptions} | 1174 | options={salesCodeOptions} |
1130 | - onChange={(_, option) => { | 1175 | + onChange={(value, option) => { |
1131 | autoFillSalesInfo(option); | 1176 | autoFillSalesInfo(option); |
1177 | + | ||
1178 | + // 检查是否是特殊的淘宝销售代码 | ||
1179 | + const isTaobaoSalesCode = [ | ||
1180 | + 'TB', | ||
1181 | + 'TBC', | ||
1182 | + 'HCTB', | ||
1183 | + '淘宝', | ||
1184 | + 'TAOBAO', | ||
1185 | + ].includes(value); | ||
1186 | + | ||
1187 | + // 如果是复制操作且是淘宝销售代码,锁定支付方式和支付渠道,不清空值 | ||
1188 | + if (optType('copy') && isTaobaoSalesCode) { | ||
1189 | + // 保留当前的支付渠道和支付方式值,只锁定选择器 | ||
1190 | + setPaymentChannelDisabled(true); | ||
1191 | + setPaymentMethodDisabled(true); | ||
1192 | + | ||
1193 | + // 如果当前没有值,则设置默认值 | ||
1194 | + const currentPaymentChannel = | ||
1195 | + form.getFieldValue('paymentChannel'); | ||
1196 | + if (!currentPaymentChannel) { | ||
1197 | + form.setFieldsValue({ paymentChannel: 'TAOBAO' }); | ||
1198 | + } | ||
1199 | + | ||
1200 | + const currentPaymentMethod = form.getFieldValue('paymentMethod'); | ||
1201 | + if (!currentPaymentMethod) { | ||
1202 | + form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_ADVANCE' }); | ||
1203 | + setPaymentMethod('PAYMENT_IN_ADVANCE'); | ||
1204 | + } | ||
1205 | + } else if (!optType('copy')) { | ||
1206 | + // 非复制操作时,清空支付渠道和支付方式 | ||
1207 | + form.setFieldsValue({ | ||
1208 | + paymentChannel: undefined, | ||
1209 | + paymentMethod: undefined, | ||
1210 | + }); | ||
1211 | + | ||
1212 | + // 重置支付渠道和支付方式的禁用状态 | ||
1213 | + setPaymentChannelDisabled(false); | ||
1214 | + setPaymentMethodDisabled(false); | ||
1215 | + | ||
1216 | + if (isTaobaoSalesCode) { | ||
1217 | + // 设置支付渠道为淘宝并锁定 | ||
1218 | + form.setFieldsValue({ paymentChannel: 'TAOBAO' }); | ||
1219 | + setPaymentChannelDisabled(true); | ||
1220 | + | ||
1221 | + // 支付方式默认锁定为预付 | ||
1222 | + form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_ADVANCE' }); | ||
1223 | + setPaymentMethod('PAYMENT_IN_ADVANCE'); | ||
1224 | + setPaymentMethodDisabled(true); | ||
1225 | + } else { | ||
1226 | + // 如果不是淘宝销售代码,解除锁定 | ||
1227 | + setPaymentChannelDisabled(false); | ||
1228 | + // 只有当前支付渠道不是扣预存时才解除付款方式的锁定 | ||
1229 | + const currentPaymentChannel = | ||
1230 | + form.getFieldValue('paymentChannel'); | ||
1231 | + if (currentPaymentChannel !== 'BALANCE') { | ||
1232 | + setPaymentMethodDisabled(false); | ||
1233 | + } | ||
1234 | + } | ||
1235 | + } | ||
1132 | }} | 1236 | }} |
1133 | disabled={optType('after-sales-check')} | 1237 | disabled={optType('after-sales-check')} |
1134 | /> | 1238 | /> |
@@ -1798,9 +1902,37 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -1798,9 +1902,37 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
1798 | width="lg" | 1902 | width="lg" |
1799 | key="paymentChannel" | 1903 | key="paymentChannel" |
1800 | label="支付渠道" | 1904 | label="支付渠道" |
1801 | - options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)} | 1905 | + options={enumToSelect(PAYMENT_CHANNEL_OPTIONS).map((option) => { |
1906 | + // 将淘宝选项设置为禁用状态,使其无法手动选择 | ||
1907 | + if (option.value === 'TAOBAO') { | ||
1908 | + return { ...option, disabled: true }; | ||
1909 | + } | ||
1910 | + return option; | ||
1911 | + })} | ||
1802 | rules={[{ required: true, message: '支付渠道必填' }]} | 1912 | rules={[{ required: true, message: '支付渠道必填' }]} |
1803 | - disabled={optType('after-sales-check')} | 1913 | + disabled={optType('after-sales-check') || paymentChannelDisabled} |
1914 | + fieldProps={{ | ||
1915 | + style: paymentChannelDisabled ? { backgroundColor: '#f5f5f5' } : {}, | ||
1916 | + }} | ||
1917 | + onChange={(val: any) => { | ||
1918 | + // 根据支付渠道设置不同的支付方式 | ||
1919 | + if (val === 'BALANCE') { | ||
1920 | + // 支付渠道为扣预存时,支付方式设置为扣预存 | ||
1921 | + setPaymentMethodDisabled(true); | ||
1922 | + form.setFieldsValue({ | ||
1923 | + paymentMethod: 'WITHHOLDING_ADVANCE_DEPOSIT', | ||
1924 | + }); | ||
1925 | + setPaymentMethod('WITHHOLDING_ADVANCE_DEPOSIT'); | ||
1926 | + } else if (val === 'TAOBAO') { | ||
1927 | + // 支付渠道为淘宝时,支付方式设置为预付 | ||
1928 | + setPaymentMethodDisabled(true); | ||
1929 | + form.setFieldsValue({ paymentMethod: 'PAYMENT_IN_ADVANCE' }); | ||
1930 | + setPaymentMethod('PAYMENT_IN_ADVANCE'); | ||
1931 | + } else { | ||
1932 | + // 支付渠道修改为其他的去除锁定状态 | ||
1933 | + setPaymentMethodDisabled(false); | ||
1934 | + } | ||
1935 | + }} | ||
1804 | /> | 1936 | /> |
1805 | <ProFormSelect | 1937 | <ProFormSelect |
1806 | placeholder="请输入支付方式" | 1938 | placeholder="请输入支付方式" |
@@ -1811,9 +1943,44 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | @@ -1811,9 +1943,44 @@ export default ({ onClose, data, subOrders, orderOptType }) => { | ||
1811 | onChange={(val: any) => { | 1943 | onChange={(val: any) => { |
1812 | setPaymentMethod(val); | 1944 | setPaymentMethod(val); |
1813 | }} | 1945 | }} |
1814 | - options={enumToSelect(PAYMENT_METHOD_OPTIONS_4_ADD)} | 1946 | + options={[ |
1947 | + // 默认可选项 | ||
1948 | + ...enumToSelect(PAYMENT_METHOD_OPTIONS_4_ADD), | ||
1949 | + // 强制禁用项 | ||
1950 | + { label: '未付款', value: 'UNPAID', disabled: true }, | ||
1951 | + { | ||
1952 | + label: '淘宝订单已付款', | ||
1953 | + value: 'TAOBAO_ORDER_HAS_BEEN_PAID', | ||
1954 | + disabled: true, | ||
1955 | + }, | ||
1956 | + { | ||
1957 | + label: '官网已付', | ||
1958 | + value: 'OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID', | ||
1959 | + disabled: true, | ||
1960 | + }, | ||
1961 | + { | ||
1962 | + label: '淘宝', | ||
1963 | + value: 'PAYMENT_IN_ADVANCE', | ||
1964 | + disabled: true, | ||
1965 | + }, | ||
1966 | + { | ||
1967 | + label: '预付', | ||
1968 | + value: 'WITHHOLDING_ADVANCE_DEPOSIT', | ||
1969 | + disabled: true, | ||
1970 | + }, | ||
1971 | + { label: '平台结算', value: 'PLATFORM_SETTLEMENT', disabled: true }, | ||
1972 | + { label: '已回款', value: 'PAYMENT_RECEIPT', disabled: true }, | ||
1973 | + { | ||
1974 | + label: '预存款无需发货', | ||
1975 | + value: 'PREPAID_NO_NEED_SEND', | ||
1976 | + disabled: true, | ||
1977 | + }, | ||
1978 | + ]} | ||
1815 | rules={[{ required: true, message: '支付方式必填' }]} | 1979 | rules={[{ required: true, message: '支付方式必填' }]} |
1816 | - disabled={optType('after-sales-check')} | 1980 | + disabled={optType('after-sales-check') || paymentMethodDisabled} |
1981 | + fieldProps={{ | ||
1982 | + style: paymentMethodDisabled ? { backgroundColor: '#f5f5f5' } : {}, | ||
1983 | + }} | ||
1817 | /> | 1984 | /> |
1818 | {/* 隐藏字段用于存储真实UID和privatePocket标志 */} | 1985 | {/* 隐藏字段用于存储真实UID和privatePocket标志 */} |
1819 | <ProFormText name="realPrepaidUid" hidden /> | 1986 | <ProFormText name="realPrepaidUid" hidden /> |
src/pages/Order/OrderList/OrderList.tsx
@@ -2,6 +2,7 @@ import ButtonConfirm from '@/components/ButtomConfirm'; | @@ -2,6 +2,7 @@ import ButtonConfirm from '@/components/ButtomConfirm'; | ||
2 | import { RESPONSE_CODE } from '@/constants/enum'; | 2 | import { RESPONSE_CODE } from '@/constants/enum'; |
3 | import ImportExpressBillModal from '@/pages/Order/OrderList/ImportExpressBillModal'; | 3 | import ImportExpressBillModal from '@/pages/Order/OrderList/ImportExpressBillModal'; |
4 | import InvoicingDrawerForm from '@/pages/Order/OrderList/InvoicingDrawerForm'; | 4 | import InvoicingDrawerForm from '@/pages/Order/OrderList/InvoicingDrawerForm'; |
5 | +import PaymentRecordModal from '@/pages/Order/OrderList/PaymentRecordModal'; | ||
5 | import ReissueModal from '@/pages/Order/OrderList/ReissueModal'; | 6 | import ReissueModal from '@/pages/Order/OrderList/ReissueModal'; |
6 | import ReissueModal_old from '@/pages/Order/OrderList/ReissueModal_old'; | 7 | import ReissueModal_old from '@/pages/Order/OrderList/ReissueModal_old'; |
7 | import { | 8 | import { |
@@ -115,6 +116,7 @@ import FinancialDrawer from './FinancialDrawer'; | @@ -115,6 +116,7 @@ import FinancialDrawer from './FinancialDrawer'; | ||
115 | import FinancialEditDrawer from './FinancialEditDrawer'; | 116 | import FinancialEditDrawer from './FinancialEditDrawer'; |
116 | import FinancialMergeDrawer from './FinancialMergeDrawer'; | 117 | import FinancialMergeDrawer from './FinancialMergeDrawer'; |
117 | import FinancialReceiptsModal from './FinancialReceiptsModal'; | 118 | import FinancialReceiptsModal from './FinancialReceiptsModal'; |
119 | +import HirePurchaseUploadPayBillModal from './HirePurchaseUploadPayBillModal'; | ||
118 | import HistoryModal from './HistoryModal'; | 120 | import HistoryModal from './HistoryModal'; |
119 | import ImagesViewerModal from './ImagesViewerModal'; | 121 | import ImagesViewerModal from './ImagesViewerModal'; |
120 | import ImportModal from './ImportModal'; | 122 | import ImportModal from './ImportModal'; |
@@ -147,6 +149,12 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -147,6 +149,12 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
147 | const [uploadPayBillModalVisible, setUploadPayBillModalVisible] = | 149 | const [uploadPayBillModalVisible, setUploadPayBillModalVisible] = |
148 | useState<boolean>(false); | 150 | useState<boolean>(false); |
149 | const [ | 151 | const [ |
152 | + hirePurchaseUploadPayBillModalVisible, | ||
153 | + setHirePurchaseUploadPayBillModalVisible, | ||
154 | + ] = useState<boolean>(false); | ||
155 | + const [paymentRecordModalVisible, setPaymentRecordModalVisible] = | ||
156 | + useState<boolean>(false); | ||
157 | + const [ | ||
150 | feedbackRegistrationModalVisible, | 158 | feedbackRegistrationModalVisible, |
151 | setFeedbackRegistrationModalVisible, | 159 | setFeedbackRegistrationModalVisible, |
152 | ] = useState<boolean>(false); | 160 | ] = useState<boolean>(false); |
@@ -236,6 +244,22 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -236,6 +244,22 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
236 | }, [selectedSubOrderKeys]); | 244 | }, [selectedSubOrderKeys]); |
237 | const [procureNotes, setProcureNotes] = useState<string>(''); | 245 | const [procureNotes, setProcureNotes] = useState<string>(''); |
238 | console.log(JSON.stringify(userInfo)); | 246 | console.log(JSON.stringify(userInfo)); |
247 | + | ||
248 | + // 付款状态枚举映射 | ||
249 | + const getPaymentStatusText = (status: string | undefined): string => { | ||
250 | + if (!status) return '无'; | ||
251 | + switch (status) { | ||
252 | + case 'WAIT_PAYMENT': | ||
253 | + return '待付款'; | ||
254 | + case 'PARTIAL_PAYMENT': | ||
255 | + return '部分付款'; | ||
256 | + case 'COMPLETE_PAYMENT': | ||
257 | + return '已付款'; | ||
258 | + default: | ||
259 | + return status; | ||
260 | + } | ||
261 | + }; | ||
262 | + | ||
239 | const triggerRecordOptNode = async (id) => { | 263 | const triggerRecordOptNode = async (id) => { |
240 | const res = await postServiceOrderGetCurrentOptNode({ | 264 | const res = await postServiceOrderGetCurrentOptNode({ |
241 | query: { | 265 | query: { |
@@ -1059,6 +1083,15 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1059,6 +1083,15 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1059 | )} | 1083 | )} |
1060 | </span> | 1084 | </span> |
1061 | </div> | 1085 | </div> |
1086 | + {/* 回款状态 */} | ||
1087 | + <div className="overflow-hidden overflow-ellipsis whitespace-no-wrap"> | ||
1088 | + <span className="text-slate-700"> | ||
1089 | + {enumValueToLabel( | ||
1090 | + optRecord.paymentReceiptStatus, | ||
1091 | + PAYMENT_RECEIPTS_STATUS_OPTIONS, | ||
1092 | + )} | ||
1093 | + </span> | ||
1094 | + </div> | ||
1062 | {/* 回款审核状态 */} | 1095 | {/* 回款审核状态 */} |
1063 | {optRecord.paymentReceiptStatus !== null ? ( | 1096 | {optRecord.paymentReceiptStatus !== null ? ( |
1064 | <div className="overflow-hidden overflow-ellipsis whitespace-no-wrap"> | 1097 | <div className="overflow-hidden overflow-ellipsis whitespace-no-wrap"> |
@@ -1440,20 +1473,6 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1440,20 +1473,6 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1440 | }} | 1473 | }} |
1441 | /> | 1474 | /> |
1442 | )} | 1475 | )} |
1443 | - {optRecord.paths?.includes('uploadPaymentReceiptBill') ? ( | ||
1444 | - <Button | ||
1445 | - className="p-0" | ||
1446 | - type="link" | ||
1447 | - onClick={() => { | ||
1448 | - createOptObject(optRecord.id, record.id); | ||
1449 | - setUploadPayBillModalVisible(true); | ||
1450 | - }} | ||
1451 | - > | ||
1452 | - 回款 | ||
1453 | - </Button> | ||
1454 | - ) : ( | ||
1455 | - '' | ||
1456 | - )} | ||
1457 | 1476 | ||
1458 | {optRecord.paths?.includes('confirmReissue_old') ? ( | 1477 | {optRecord.paths?.includes('confirmReissue_old') ? ( |
1459 | <Button | 1478 | <Button |
@@ -1522,22 +1541,6 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1522,22 +1541,6 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1522 | '' | 1541 | '' |
1523 | )} | 1542 | )} |
1524 | 1543 | ||
1525 | - {optRecord.paths?.includes('auditPaymentReceipt') ? ( | ||
1526 | - <Button | ||
1527 | - className="p-0" | ||
1528 | - type="link" | ||
1529 | - onClick={() => { | ||
1530 | - createOptObject(optRecord.id, record.id); | ||
1531 | - setCheckVisible(true); | ||
1532 | - setOrderCheckType(CHECK_TYPE.PAYMENT_RECEIPTS_AUDIT); | ||
1533 | - }} | ||
1534 | - > | ||
1535 | - 回款审核 | ||
1536 | - </Button> | ||
1537 | - ) : ( | ||
1538 | - '' | ||
1539 | - )} | ||
1540 | - | ||
1541 | {optRecord.paths?.includes('modifiedAuditRequest') ? ( | 1544 | {optRecord.paths?.includes('modifiedAuditRequest') ? ( |
1542 | <Button | 1545 | <Button |
1543 | className="p-0" | 1546 | className="p-0" |
@@ -1623,7 +1626,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1623,7 +1626,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1623 | ) : ( | 1626 | ) : ( |
1624 | '' | 1627 | '' |
1625 | )} | 1628 | )} |
1626 | - {optRecord.paths?.includes('saleCancelInvoicing') ? ( | 1629 | + {/* {optRecord.paths?.includes('saleCancelInvoicing') ? ( |
1627 | <ButtonConfirm | 1630 | <ButtonConfirm |
1628 | className="p-0" | 1631 | className="p-0" |
1629 | title="确认取消申请开票?" | 1632 | title="确认取消申请开票?" |
@@ -1643,7 +1646,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1643,7 +1646,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1643 | /> | 1646 | /> |
1644 | ) : ( | 1647 | ) : ( |
1645 | '' | 1648 | '' |
1646 | - )} | 1649 | + )} */} |
1647 | {optRecord.paths?.includes('noNeedInvoicingEdit') ? ( | 1650 | {optRecord.paths?.includes('noNeedInvoicingEdit') ? ( |
1648 | <Button | 1651 | <Button |
1649 | className="p-0" | 1652 | className="p-0" |
@@ -1841,7 +1844,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1841,7 +1844,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1841 | '' | 1844 | '' |
1842 | )} | 1845 | )} |
1843 | 1846 | ||
1844 | - {optRecord.paths?.includes('invoicing') ? ( | 1847 | + {/* {optRecord.paths?.includes('invoicing') ? ( |
1845 | <Button | 1848 | <Button |
1846 | className="p-0" | 1849 | className="p-0" |
1847 | type="link" | 1850 | type="link" |
@@ -1856,9 +1859,9 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1856,9 +1859,9 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1856 | </Button> | 1859 | </Button> |
1857 | ) : ( | 1860 | ) : ( |
1858 | '' | 1861 | '' |
1859 | - )} | 1862 | + )} */} |
1860 | 1863 | ||
1861 | - {optRecord.paths?.includes('applyInvoicing') ? ( | 1864 | + {/* {optRecord.paths?.includes('applyInvoicing') ? ( |
1862 | <Button | 1865 | <Button |
1863 | className="p-0" | 1866 | className="p-0" |
1864 | type="link" | 1867 | type="link" |
@@ -1873,7 +1876,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -1873,7 +1876,7 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
1873 | </Button> | 1876 | </Button> |
1874 | ) : ( | 1877 | ) : ( |
1875 | '' | 1878 | '' |
1876 | - )} | 1879 | + )} */} |
1877 | 1880 | ||
1878 | {optRecord.paths?.includes('applyInvoicing_old') ? ( | 1881 | {optRecord.paths?.includes('applyInvoicing_old') ? ( |
1879 | <Button | 1882 | <Button |
@@ -2736,6 +2739,42 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -2736,6 +2739,42 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
2736 | 2739 | ||
2737 | {roleCode === 'finance' ? <Divider type="vertical" /> : ''} | 2740 | {roleCode === 'finance' ? <Divider type="vertical" /> : ''} |
2738 | 2741 | ||
2742 | + {/* 添加付款审核状态 */} | ||
2743 | + <div> | ||
2744 | + <span className="text-[#8C8C8C]">付款状态:</span> | ||
2745 | + <span className="text-slate-700"> | ||
2746 | + {getPaymentStatusText(record.paymentAuditStatus)} | ||
2747 | + </span> | ||
2748 | + </div> | ||
2749 | + <Divider type="vertical" /> | ||
2750 | + | ||
2751 | + {/* 添加已回款金额 */} | ||
2752 | + <div> | ||
2753 | + <span className="text-[#8C8C8C]">已回款金额:¥</span> | ||
2754 | + <span className="text-slate-700"> | ||
2755 | + {record.payedMoney || '0.00'} | ||
2756 | + </span> | ||
2757 | + </div> | ||
2758 | + <Divider type="vertical" /> | ||
2759 | + | ||
2760 | + {/* 添加未回款金额 */} | ||
2761 | + <div> | ||
2762 | + <span className="text-[#8C8C8C]">未回款金额:¥</span> | ||
2763 | + <span className="text-slate-700"> | ||
2764 | + {record.unPayedMoney || '0.00'} | ||
2765 | + </span> | ||
2766 | + </div> | ||
2767 | + <Divider type="vertical" /> | ||
2768 | + | ||
2769 | + {/* 添加发票核销金额 */} | ||
2770 | + <div> | ||
2771 | + <span className="text-[#8C8C8C]">发票核销金额:¥</span> | ||
2772 | + <span className="text-slate-700"> | ||
2773 | + {record.invoiceMoney || '0.00'} | ||
2774 | + </span> | ||
2775 | + </div> | ||
2776 | + <Divider type="vertical" /> | ||
2777 | + | ||
2739 | <div title={record.notes}> | 2778 | <div title={record.notes}> |
2740 | <div | 2779 | <div |
2741 | className="max-w-[850px] whitespace-normal overflow-hidden overflow-ellipsis hover:cursor-pointer" | 2780 | className="max-w-[850px] whitespace-normal overflow-hidden overflow-ellipsis hover:cursor-pointer" |
@@ -2957,6 +2996,55 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -2957,6 +2996,55 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
2957 | ) : ( | 2996 | ) : ( |
2958 | '' | 2997 | '' |
2959 | )} | 2998 | )} |
2999 | + {record.paths?.includes('updateHirePurchase') ? ( | ||
3000 | + <Button | ||
3001 | + className="p-0" | ||
3002 | + type="link" | ||
3003 | + onClick={() => { | ||
3004 | + createOptObject(record.id, record.id); | ||
3005 | + setHirePurchaseUploadPayBillModalVisible(true); | ||
3006 | + }} | ||
3007 | + > | ||
3008 | + 回款 | ||
3009 | + </Button> | ||
3010 | + ) : ( | ||
3011 | + '' | ||
3012 | + )} | ||
3013 | + | ||
3014 | + {record.paths?.includes('refundHistory') ? ( | ||
3015 | + <Button | ||
3016 | + className="p-0" | ||
3017 | + type="link" | ||
3018 | + onClick={() => { | ||
3019 | + createOptObject(record.id, record.id); | ||
3020 | + setPaymentRecordModalVisible(true); | ||
3021 | + }} | ||
3022 | + > | ||
3023 | + 付款记录 | ||
3024 | + </Button> | ||
3025 | + ) : ( | ||
3026 | + '' | ||
3027 | + )} | ||
3028 | + | ||
3029 | + {/* 输出日志以检查权限和支付方式 */} | ||
3030 | + {console.log('Order info:', record.id, record.paths)} | ||
3031 | + {record.paths?.includes('auditPartialPaymentReceipt') ? ( | ||
3032 | + <Button | ||
3033 | + className="p-0" | ||
3034 | + type="link" | ||
3035 | + onClick={() => { | ||
3036 | + createOptObject(null, record.id); | ||
3037 | + setCheckVisible(true); | ||
3038 | + setOrderCheckType( | ||
3039 | + CHECK_TYPE.PARTIAL_PAYMENT_RECEIPTS_AUDIT, | ||
3040 | + ); | ||
3041 | + }} | ||
3042 | + > | ||
3043 | + 回款审核 | ||
3044 | + </Button> | ||
3045 | + ) : ( | ||
3046 | + '' | ||
3047 | + )} | ||
2960 | 3048 | ||
2961 | {record.paths?.includes('modifiedAuditRequest') ? ( | 3049 | {record.paths?.includes('modifiedAuditRequest') ? ( |
2962 | <Button | 3050 | <Button |
@@ -2990,6 +3078,8 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -2990,6 +3078,8 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
2990 | '' | 3078 | '' |
2991 | )} | 3079 | )} |
2992 | 3080 | ||
3081 | + {/* 第二个回款审核(分期)按钮已被移除,使用上面的带权限检查的按钮 */} | ||
3082 | + | ||
2993 | {record.paths?.includes('modifiedLeaderAuditRequest') ? ( | 3083 | {record.paths?.includes('modifiedLeaderAuditRequest') ? ( |
2994 | <Button | 3084 | <Button |
2995 | className="p-0" | 3085 | className="p-0" |
@@ -3135,6 +3225,36 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -3135,6 +3225,36 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
3135 | ) : ( | 3225 | ) : ( |
3136 | '' | 3226 | '' |
3137 | )} | 3227 | )} |
3228 | + {record.paths?.includes('saleCancelInvoicing') ? ( | ||
3229 | + <ButtonConfirm | ||
3230 | + className="p-0" | ||
3231 | + title="确认取消申请开票?" | ||
3232 | + text="取消申请(新)" | ||
3233 | + onConfirm={async () => { | ||
3234 | + let selectedSubOrders = subOrderSelectedMap.get( | ||
3235 | + record.id, | ||
3236 | + ); | ||
3237 | + if (selectedSubOrders === undefined) { | ||
3238 | + selectedSubOrders = record.subOrderInformationLists; | ||
3239 | + } | ||
3240 | + let subOrderIds = selectedSubOrders.map( | ||
3241 | + (item) => item.id, | ||
3242 | + ); | ||
3243 | + let res = await postServiceInvoiceCancelApply({ | ||
3244 | + data: { | ||
3245 | + subOrderIds: subOrderIds, | ||
3246 | + }, | ||
3247 | + }); | ||
3248 | + | ||
3249 | + if (res && res.result === RESPONSE_CODE.SUCCESS) { | ||
3250 | + message.success(res.message); | ||
3251 | + refreshTable(); | ||
3252 | + } | ||
3253 | + }} | ||
3254 | + /> | ||
3255 | + ) : ( | ||
3256 | + '' | ||
3257 | + )} | ||
3138 | 3258 | ||
3139 | {record.paths?.includes('leaderAudit') ? ( | 3259 | {record.paths?.includes('leaderAudit') ? ( |
3140 | <Button | 3260 | <Button |
@@ -5302,6 +5422,38 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | @@ -5302,6 +5422,38 @@ const OrderList = ({ paramsNew, searchShow, toolbarShow }) => { | ||
5302 | }} | 5422 | }} |
5303 | /> | 5423 | /> |
5304 | )} | 5424 | )} |
5425 | + | ||
5426 | + {hirePurchaseUploadPayBillModalVisible && data && currentOptMainId && ( | ||
5427 | + <HirePurchaseUploadPayBillModal | ||
5428 | + visible={hirePurchaseUploadPayBillModalVisible} | ||
5429 | + onCancel={() => { | ||
5430 | + setHirePurchaseUploadPayBillModalVisible(false); | ||
5431 | + clearOptObject(); | ||
5432 | + }} | ||
5433 | + onOk={() => { | ||
5434 | + setHirePurchaseUploadPayBillModalVisible(false); | ||
5435 | + message.success('回款凭证上传成功'); | ||
5436 | + refreshTable(); | ||
5437 | + }} | ||
5438 | + record={data.find((item) => item.id === currentOptMainId) || {}} | ||
5439 | + subOrders={ | ||
5440 | + data.find((item) => item.id === currentOptMainId) | ||
5441 | + ?.subOrderInformationLists || [] | ||
5442 | + } | ||
5443 | + /> | ||
5444 | + )} | ||
5445 | + | ||
5446 | + {paymentRecordModalVisible && currentOptMainId && ( | ||
5447 | + <PaymentRecordModal | ||
5448 | + visible={paymentRecordModalVisible} | ||
5449 | + mainOrderId={currentOptMainId} | ||
5450 | + onClose={() => { | ||
5451 | + setPaymentRecordModalVisible(false); | ||
5452 | + clearOptObject(); | ||
5453 | + }} | ||
5454 | + /> | ||
5455 | + )} | ||
5456 | + | ||
5305 | {feedbackRegistrationModalVisible && ( | 5457 | {feedbackRegistrationModalVisible && ( |
5306 | <FeedbackRegistrationModal | 5458 | <FeedbackRegistrationModal |
5307 | setVisible={(val: boolean) => { | 5459 | setVisible={(val: boolean) => { |
src/pages/Order/OrderList/PaymentRecordModal.tsx
0 → 100644
1 | +import { postServiceOrderRefundHistory } from '@/services'; | ||
2 | +import { Button, Empty, Image, Modal } from 'antd'; | ||
3 | +import React, { useEffect, useState } from 'react'; | ||
4 | + | ||
5 | +interface PaymentRecordModalProps { | ||
6 | + visible: boolean; | ||
7 | + mainOrderId: number; | ||
8 | + onClose: () => void; | ||
9 | +} | ||
10 | + | ||
11 | +interface PaymentRecord { | ||
12 | + id: number; | ||
13 | + mainOrderId: number; | ||
14 | + refundMoney: number; | ||
15 | + createTime: string; | ||
16 | + annex: string; | ||
17 | + isAudit: number; | ||
18 | + isDel: number; | ||
19 | + updateTime: string | null; | ||
20 | + paymentReceiptAnnexPartial: string | null; | ||
21 | +} | ||
22 | + | ||
23 | +const PaymentRecordModal: React.FC<PaymentRecordModalProps> = ({ | ||
24 | + visible, | ||
25 | + mainOrderId, | ||
26 | + onClose, | ||
27 | +}) => { | ||
28 | + const [paymentRecords, setPaymentRecords] = useState<PaymentRecord[]>([]); | ||
29 | + | ||
30 | + const fetchPaymentRecords = async () => { | ||
31 | + if (!mainOrderId) return; | ||
32 | + | ||
33 | + try { | ||
34 | + const response = await postServiceOrderRefundHistory({ | ||
35 | + data: { mainOrderId }, | ||
36 | + }); | ||
37 | + | ||
38 | + if (response.result === 0 && response.data) { | ||
39 | + setPaymentRecords(response.data); | ||
40 | + } else { | ||
41 | + setPaymentRecords([]); | ||
42 | + } | ||
43 | + } catch (error) { | ||
44 | + console.error('Failed to fetch payment records:', error); | ||
45 | + setPaymentRecords([]); | ||
46 | + } | ||
47 | + }; | ||
48 | + | ||
49 | + useEffect(() => { | ||
50 | + if (visible && mainOrderId) { | ||
51 | + fetchPaymentRecords(); | ||
52 | + } | ||
53 | + }, [visible, mainOrderId]); | ||
54 | + | ||
55 | + const parseAnnex = (annexString: string): string[] => { | ||
56 | + try { | ||
57 | + const parsed = JSON.parse(annexString); | ||
58 | + return parsed.map((item: { url: string }) => item.url); | ||
59 | + } catch (e) { | ||
60 | + console.error('Failed to parse annex:', e); | ||
61 | + return []; | ||
62 | + } | ||
63 | + }; | ||
64 | + | ||
65 | + return ( | ||
66 | + <Modal | ||
67 | + title="付款记录" | ||
68 | + open={visible} | ||
69 | + onCancel={onClose} | ||
70 | + footer={[ | ||
71 | + <Button key="close" onClick={onClose}> | ||
72 | + 关闭 | ||
73 | + </Button>, | ||
74 | + ]} | ||
75 | + width={500} | ||
76 | + > | ||
77 | + <div className="payment-record-container"> | ||
78 | + {paymentRecords.length > 0 ? ( | ||
79 | + paymentRecords.map((record, index) => { | ||
80 | + const imageUrls = record.annex ? parseAnnex(record.annex) : []; | ||
81 | + | ||
82 | + return ( | ||
83 | + <div key={record.id} className="payment-record-item"> | ||
84 | + <div className="payment-record-header"> | ||
85 | + {index < paymentRecords.length - 1 && ( | ||
86 | + <div className="payment-record-line" /> | ||
87 | + )} | ||
88 | + <div className="payment-record-circle" /> | ||
89 | + </div> | ||
90 | + <div className="payment-record-content"> | ||
91 | + <div className="payment-record-info"> | ||
92 | + <p> | ||
93 | + <strong>提交时间:</strong> {record.createTime} | ||
94 | + </p> | ||
95 | + <p> | ||
96 | + <strong>付款金额:</strong>{' '} | ||
97 | + {record.refundMoney.toFixed(2)} | ||
98 | + </p> | ||
99 | + {imageUrls.length > 0 && ( | ||
100 | + <p> | ||
101 | + <strong>付款凭证:</strong> | ||
102 | + </p> | ||
103 | + )} | ||
104 | + </div> | ||
105 | + {imageUrls.length > 0 && ( | ||
106 | + <div className="payment-record-images"> | ||
107 | + <Image.PreviewGroup> | ||
108 | + {imageUrls.map((url, imgIndex) => ( | ||
109 | + <Image | ||
110 | + key={imgIndex} | ||
111 | + width={120} | ||
112 | + src={url} | ||
113 | + className="payment-record-image" | ||
114 | + /> | ||
115 | + ))} | ||
116 | + </Image.PreviewGroup> | ||
117 | + </div> | ||
118 | + )} | ||
119 | + </div> | ||
120 | + </div> | ||
121 | + ); | ||
122 | + }) | ||
123 | + ) : ( | ||
124 | + <Empty description="暂无付款记录" className="payment-record-empty" /> | ||
125 | + )} | ||
126 | + </div> | ||
127 | + </Modal> | ||
128 | + ); | ||
129 | +}; | ||
130 | + | ||
131 | +export default PaymentRecordModal; |
src/pages/Order/OrderList/UploadPayBillModal.tsx
@@ -216,10 +216,24 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) => { | @@ -216,10 +216,24 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) => { | ||
216 | }} | 216 | }} |
217 | onOpenChange={setVisible} | 217 | onOpenChange={setVisible} |
218 | > | 218 | > |
219 | - <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div> | ||
220 | - <Upload {...props}> | ||
221 | - {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER ? uploadButton : ''} | ||
222 | - </Upload> | 219 | + <div className="pb-4 text-base font-medium"> |
220 | + 付款金额:¥{mainOrder?.totalPayment?.toLocaleString() || '0.00'} | ||
221 | + </div> | ||
222 | + <div className="flex items-start pb-4 text-base font-medium"> | ||
223 | + <div>付款凭证:</div> | ||
224 | + | ||
225 | + <div className="flex flex-col items-start ml-2"> | ||
226 | + <div className="mb-1 text-xs decoration-gray-50"> | ||
227 | + 可复制照片粘贴 | ||
228 | + </div> | ||
229 | + | ||
230 | + <Upload {...props}> | ||
231 | + {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER | ||
232 | + ? uploadButton | ||
233 | + : null} | ||
234 | + </Upload> | ||
235 | + </div> | ||
236 | + </div> | ||
223 | </ModalForm> | 237 | </ModalForm> |
224 | 238 | ||
225 | <Modal | 239 | <Modal |
src/pages/Order/OrderList/index.css
@@ -2,6 +2,14 @@ | @@ -2,6 +2,14 @@ | ||
2 | margin-inline: 0 !important; | 2 | margin-inline: 0 !important; |
3 | } | 3 | } |
4 | 4 | ||
5 | +.order-page-container .ant-table-cell { | ||
6 | + word-break: break-word; | ||
7 | + white-space: normal !important; | ||
8 | + overflow: hidden; | ||
9 | + max-width: 500px; | ||
10 | + box-sizing: border-box; | ||
11 | +} | ||
12 | + | ||
5 | .order-page-container td { | 13 | .order-page-container td { |
6 | font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial, | 14 | font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial, |
7 | 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', | 15 | 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', |
@@ -53,6 +61,8 @@ | @@ -53,6 +61,8 @@ | ||
53 | .order-page-container .ant-table-thead .ant-table-cell { | 61 | .order-page-container .ant-table-thead .ant-table-cell { |
54 | background-color: #fff !important; | 62 | background-color: #fff !important; |
55 | border-radius: 8px !important; | 63 | border-radius: 8px !important; |
64 | + overflow: hidden; | ||
65 | + white-space: normal !important; | ||
56 | } | 66 | } |
57 | 67 | ||
58 | #sub-table tbody td { | 68 | #sub-table tbody td { |
@@ -98,3 +108,78 @@ | @@ -98,3 +108,78 @@ | ||
98 | 108 | ||
99 | /* 设置行与行之间分割线的颜色 */ | 109 | /* 设置行与行之间分割线的颜色 */ |
100 | } | 110 | } |
111 | + | ||
112 | +/* 付款记录样式 */ | ||
113 | +.payment-record-container { | ||
114 | + padding: 10px 0; | ||
115 | +} | ||
116 | + | ||
117 | +.payment-record-item { | ||
118 | + position: relative; | ||
119 | + display: flex; | ||
120 | + margin-bottom: 16px; | ||
121 | +} | ||
122 | + | ||
123 | +.payment-record-header { | ||
124 | + position: relative; | ||
125 | + width: 24px; | ||
126 | + margin-right: 12px; | ||
127 | +} | ||
128 | + | ||
129 | +.payment-record-line { | ||
130 | + position: absolute; | ||
131 | + top: 0; | ||
132 | + bottom: 0; | ||
133 | + left: 50%; | ||
134 | + width: 1px; | ||
135 | + background-color: #e8e8e8; | ||
136 | + transform: translateX(-50%); | ||
137 | + z-index: 1; | ||
138 | +} | ||
139 | + | ||
140 | +.payment-record-circle { | ||
141 | + position: absolute; | ||
142 | + top: 12px; | ||
143 | + left: 50%; | ||
144 | + width: 12px; | ||
145 | + height: 12px; | ||
146 | + background-color: #d4b106; | ||
147 | + border-radius: 50%; | ||
148 | + transform: translateX(-50%); | ||
149 | + z-index: 2; | ||
150 | +} | ||
151 | + | ||
152 | +.payment-record-content { | ||
153 | + flex: 1; | ||
154 | + background-color: #f5f5f5; | ||
155 | + border-radius: 8px; | ||
156 | + padding: 12px 16px; | ||
157 | +} | ||
158 | + | ||
159 | +.payment-record-info p { | ||
160 | + margin-bottom: 8px; | ||
161 | +} | ||
162 | + | ||
163 | +.payment-record-images { | ||
164 | + display: flex; | ||
165 | + flex-wrap: wrap; | ||
166 | + gap: 8px; | ||
167 | + margin-top: 8px; | ||
168 | +} | ||
169 | + | ||
170 | +.payment-record-image { | ||
171 | + border: 1px solid #e8e8e8; | ||
172 | + border-radius: 4px; | ||
173 | +} | ||
174 | + | ||
175 | +.payment-record-divider { | ||
176 | + height: 1px; | ||
177 | + background-color: #e8e8e8; | ||
178 | + margin: 16px 0; | ||
179 | +} | ||
180 | + | ||
181 | +.payment-record-empty { | ||
182 | + text-align: center; | ||
183 | + color: #999; | ||
184 | + padding: 20px 0; | ||
185 | +} |
src/pages/Order/OrderList/index.less
@@ -106,3 +106,78 @@ | @@ -106,3 +106,78 @@ | ||
106 | // .order-tooltip .ant-tooltip-inner{ | 106 | // .order-tooltip .ant-tooltip-inner{ |
107 | // color: black !important; | 107 | // color: black !important; |
108 | // } | 108 | // } |
109 | + | ||
110 | +/* 付款记录样式 */ | ||
111 | +.payment-record-container { | ||
112 | + padding: 10px 0; | ||
113 | +} | ||
114 | + | ||
115 | +.payment-record-item { | ||
116 | + position: relative; | ||
117 | + display: flex; | ||
118 | + margin-bottom: 16px; | ||
119 | +} | ||
120 | + | ||
121 | +.payment-record-header { | ||
122 | + position: relative; | ||
123 | + width: 24px; | ||
124 | + margin-right: 12px; | ||
125 | +} | ||
126 | + | ||
127 | +.payment-record-line { | ||
128 | + position: absolute; | ||
129 | + top: 0; | ||
130 | + bottom: 0; | ||
131 | + left: 50%; | ||
132 | + width: 1px; | ||
133 | + background-color: #e8e8e8; | ||
134 | + transform: translateX(-50%); | ||
135 | + z-index: 1; | ||
136 | +} | ||
137 | + | ||
138 | +.payment-record-circle { | ||
139 | + position: absolute; | ||
140 | + top: 12px; | ||
141 | + left: 50%; | ||
142 | + width: 12px; | ||
143 | + height: 12px; | ||
144 | + background-color: #d4b106; | ||
145 | + border-radius: 50%; | ||
146 | + transform: translateX(-50%); | ||
147 | + z-index: 2; | ||
148 | +} | ||
149 | + | ||
150 | +.payment-record-content { | ||
151 | + flex: 1; | ||
152 | + background-color: #f5f5f5; | ||
153 | + border-radius: 8px; | ||
154 | + padding: 12px 16px; | ||
155 | +} | ||
156 | + | ||
157 | +.payment-record-info p { | ||
158 | + margin-bottom: 8px; | ||
159 | +} | ||
160 | + | ||
161 | +.payment-record-images { | ||
162 | + display: flex; | ||
163 | + flex-wrap: wrap; | ||
164 | + gap: 8px; | ||
165 | + margin-top: 8px; | ||
166 | +} | ||
167 | + | ||
168 | +.payment-record-image { | ||
169 | + border: 1px solid #e8e8e8; | ||
170 | + border-radius: 4px; | ||
171 | +} | ||
172 | + | ||
173 | +.payment-record-divider { | ||
174 | + height: 1px; | ||
175 | + background-color: #e8e8e8; | ||
176 | + margin: 16px 0; | ||
177 | +} | ||
178 | + | ||
179 | +.payment-record-empty { | ||
180 | + text-align: center; | ||
181 | + color: #999; | ||
182 | + padding: 20px 0; | ||
183 | +} |
src/pages/Order/constant.ts
@@ -7,11 +7,13 @@ import { getReceivingCompanyOptions, isSupplier } from '@/utils/order'; | @@ -7,11 +7,13 @@ import { getReceivingCompanyOptions, isSupplier } from '@/utils/order'; | ||
7 | export const COMFIR_RECEIPT_IMAGES_NUMBER = 3; | 7 | export const COMFIR_RECEIPT_IMAGES_NUMBER = 3; |
8 | 8 | ||
9 | export const PAYMENT_CHANNEL_OPTIONS = { | 9 | export const PAYMENT_CHANNEL_OPTIONS = { |
10 | - ALIPAY: '支付宝', | ||
11 | - WECHAT: '微信', | ||
12 | BANK_TRANSFER: '银行转账', | 10 | BANK_TRANSFER: '银行转账', |
13 | - BALANCE: '预存款', | ||
14 | - OFFLINE: '线下付款', | 11 | + WECHAT: '微信支付', |
12 | + ALIPAY: '支付宝支付', | ||
13 | + BALANCE: '扣预存', | ||
14 | + PLATFORM: '平台结算', | ||
15 | + OFFLINE: '线下支付', | ||
16 | + TAOBAO: '淘宝已付', | ||
15 | }; | 17 | }; |
16 | 18 | ||
17 | export const RECEIPTS_RECORD_TYPES = { | 19 | export const RECEIPTS_RECORD_TYPES = { |
@@ -26,7 +28,7 @@ export const PAYMENT_METHOD_OPTIONS = { | @@ -26,7 +28,7 @@ export const PAYMENT_METHOD_OPTIONS = { | ||
26 | TAOBAO_ORDER_HAS_BEEN_PAID: '淘宝订单已付款', | 28 | TAOBAO_ORDER_HAS_BEEN_PAID: '淘宝订单已付款', |
27 | OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID: '官网订单已付款', | 29 | OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID: '官网订单已付款', |
28 | PAYMENT_IN_ADVANCE: '预付款', | 30 | PAYMENT_IN_ADVANCE: '预付款', |
29 | - WITHHOLDING_ADVANCE_DEPOSIT: '扣预存', | 31 | + WITHHOLDING_ADVANCE_DEPOSIT: '预付', |
30 | PLATFORM_SETTLEMENT: '平台结算', | 32 | PLATFORM_SETTLEMENT: '平台结算', |
31 | CASH_ON_DELIVERY: '货到付款', | 33 | CASH_ON_DELIVERY: '货到付款', |
32 | HIRE_PURCHASE: '分期付款', | 34 | HIRE_PURCHASE: '分期付款', |
@@ -35,15 +37,9 @@ export const PAYMENT_METHOD_OPTIONS = { | @@ -35,15 +37,9 @@ export const PAYMENT_METHOD_OPTIONS = { | ||
35 | }; | 37 | }; |
36 | 38 | ||
37 | export const PAYMENT_METHOD_OPTIONS_4_ADD = { | 39 | export const PAYMENT_METHOD_OPTIONS_4_ADD = { |
38 | - UNPAID: '未付款', | ||
39 | - TAOBAO_ORDER_HAS_BEEN_PAID: '淘宝订单已付款', | ||
40 | - OFFICIAL_WEBSITE_ORDER_HAS_BEEN_PAID: '官网订单已付款', | ||
41 | - PAYMENT_IN_ADVANCE: '预付款', | ||
42 | - WITHHOLDING_ADVANCE_DEPOSIT: '扣预存', | ||
43 | - PLATFORM_SETTLEMENT: '平台结算', | 40 | + PAYMENT_IN_ADVANCE: '预付', |
44 | CASH_ON_DELIVERY: '货到付款', | 41 | CASH_ON_DELIVERY: '货到付款', |
45 | HIRE_PURCHASE: '分期付款', | 42 | HIRE_PURCHASE: '分期付款', |
46 | - PREPAID_NO_NEED_SEND: '预存款无需发货', | ||
47 | }; | 43 | }; |
48 | 44 | ||
49 | export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = { | 45 | export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = { |
@@ -125,6 +121,7 @@ export const CHECK_TYPE = { | @@ -125,6 +121,7 @@ export const CHECK_TYPE = { | ||
125 | URGENT_INVOICE_AUDITING: 'URGENT_INVOICE_AUDITING', | 121 | URGENT_INVOICE_AUDITING: 'URGENT_INVOICE_AUDITING', |
126 | URGENT_INVOICE_AUDITING_OLD: 'URGENT_INVOICE_AUDITING_OLD', | 122 | URGENT_INVOICE_AUDITING_OLD: 'URGENT_INVOICE_AUDITING_OLD', |
127 | PAYMENT_RECEIPTS_AUDIT: 'PAYMENT_RECEIPTS_AUDIT', | 123 | PAYMENT_RECEIPTS_AUDIT: 'PAYMENT_RECEIPTS_AUDIT', |
124 | + PARTIAL_PAYMENT_RECEIPTS_AUDIT: 'PARTIAL_PAYMENT_RECEIPTS_AUDIT', | ||
128 | CONFIRM_REISSUE: 'CONFIRM_REISSUE', | 125 | CONFIRM_REISSUE: 'CONFIRM_REISSUE', |
129 | CONFIRM_REISSUE_OLD: 'CONFIRM_REISSUE_OLD', | 126 | CONFIRM_REISSUE_OLD: 'CONFIRM_REISSUE_OLD', |
130 | PREPAID_AUDIT: 'PREPAID_AUDIT', | 127 | PREPAID_AUDIT: 'PREPAID_AUDIT', |
@@ -193,9 +190,11 @@ export const POST_AUDIT_OPTIONS = { | @@ -193,9 +190,11 @@ export const POST_AUDIT_OPTIONS = { | ||
193 | }; | 190 | }; |
194 | 191 | ||
195 | export const PAYMENT_RECEIPTS_STATUS_OPTIONS = { | 192 | export const PAYMENT_RECEIPTS_STATUS_OPTIONS = { |
196 | - WAIT_AUDIT: '回款待审核', | ||
197 | - AUDIT_PASS: '回款已审核', | ||
198 | - AUDIT_NOTPASS: '回款审核失败', | 193 | + WAIT_AUDIT: '审核中', |
194 | + AUDIT_PASS: '审核通过', | ||
195 | + AUDIT_NOTPASS: '未通过', | ||
196 | + NOT_RECEIVED: '待提交', | ||
197 | + PARTIAL_RECEIVED: '待提交', | ||
199 | }; | 198 | }; |
200 | 199 | ||
201 | export const ORDER_STATUS_OPTIONS = { | 200 | export const ORDER_STATUS_OPTIONS = { |
src/services/definition.ts
@@ -1556,32 +1556,6 @@ export interface ExchangeRecordsRequestDto { | @@ -1556,32 +1556,6 @@ export interface ExchangeRecordsRequestDto { | ||
1556 | total?: number; | 1556 | total?: number; |
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | -export interface File { | ||
1560 | - absolute?: boolean; | ||
1561 | - absoluteFile?: File; | ||
1562 | - absolutePath?: string; | ||
1563 | - canonicalFile?: File; | ||
1564 | - canonicalPath?: string; | ||
1565 | - directory?: boolean; | ||
1566 | - executable?: boolean; | ||
1567 | - file?: boolean; | ||
1568 | - /** @format int64 */ | ||
1569 | - freeSpace?: number; | ||
1570 | - hidden?: boolean; | ||
1571 | - /** @format int64 */ | ||
1572 | - lastModified?: number; | ||
1573 | - name?: string; | ||
1574 | - parent?: string; | ||
1575 | - parentFile?: File; | ||
1576 | - path?: string; | ||
1577 | - readable?: boolean; | ||
1578 | - /** @format int64 */ | ||
1579 | - totalSpace?: number; | ||
1580 | - /** @format int64 */ | ||
1581 | - usableSpace?: number; | ||
1582 | - writable?: boolean; | ||
1583 | -} | ||
1584 | - | ||
1585 | export interface FilePathDto { | 1559 | export interface FilePathDto { |
1586 | url?: string; | 1560 | url?: string; |
1587 | } | 1561 | } |
@@ -1613,6 +1587,29 @@ export interface GroupExchangeRecordsRequestDto { | @@ -1613,6 +1587,29 @@ export interface GroupExchangeRecordsRequestDto { | ||
1613 | 1587 | ||
1614 | export type InputStream = any; | 1588 | export type InputStream = any; |
1615 | 1589 | ||
1590 | +export interface InstallmentPaymentDTO { | ||
1591 | + /** | ||
1592 | + * @description | ||
1593 | + * 回款单 | ||
1594 | + */ | ||
1595 | + filePaths?: Array<FilePathDto>; | ||
1596 | + /** | ||
1597 | + * @description | ||
1598 | + * 分期付款备注 | ||
1599 | + */ | ||
1600 | + installmentComment?: string; | ||
1601 | + /** | ||
1602 | + * @description | ||
1603 | + * 分期付款金额 | ||
1604 | + */ | ||
1605 | + installmentMoney?: number; | ||
1606 | + /** | ||
1607 | + * @description | ||
1608 | + * 子订单id | ||
1609 | + */ | ||
1610 | + subOrderIds?: Array<number>; | ||
1611 | +} | ||
1612 | + | ||
1616 | export interface InventoryMaterialStockReq { | 1613 | export interface InventoryMaterialStockReq { |
1617 | auxPropId?: string; | 1614 | auxPropId?: string; |
1618 | isShowStockPosition?: boolean; | 1615 | isShowStockPosition?: boolean; |
@@ -4282,7 +4279,7 @@ export interface ResetPwdVO { | @@ -4282,7 +4279,7 @@ export interface ResetPwdVO { | ||
4282 | 4279 | ||
4283 | export interface Resource { | 4280 | export interface Resource { |
4284 | description?: string; | 4281 | description?: string; |
4285 | - file?: File; | 4282 | + file?: TsgFile; |
4286 | filename?: string; | 4283 | filename?: string; |
4287 | inputStream?: InputStream; | 4284 | inputStream?: InputStream; |
4288 | open?: boolean; | 4285 | open?: boolean; |
@@ -4403,6 +4400,7 @@ export interface SubOrder { | @@ -4403,6 +4400,7 @@ export interface SubOrder { | ||
4403 | paymentChannel?: string; | 4400 | paymentChannel?: string; |
4404 | paymentMethod?: string; | 4401 | paymentMethod?: string; |
4405 | paymentReceiptAnnex?: string; | 4402 | paymentReceiptAnnex?: string; |
4403 | + paymentReceiptAnnexPartial?: string; | ||
4406 | paymentReceiptNotes?: string; | 4404 | paymentReceiptNotes?: string; |
4407 | paymentReceiptStatus?: string; | 4405 | paymentReceiptStatus?: string; |
4408 | paymentStatus?: string; | 4406 | paymentStatus?: string; |
@@ -4904,6 +4902,11 @@ export interface UserPrivatePocketBalanceUpdateRequest { | @@ -4904,6 +4902,11 @@ export interface UserPrivatePocketBalanceUpdateRequest { | ||
4904 | * @format int32 | 4902 | * @format int32 |
4905 | */ | 4903 | */ |
4906 | uid?: number; | 4904 | uid?: number; |
4905 | + /** | ||
4906 | + * @description | ||
4907 | + * 修改人 | ||
4908 | + */ | ||
4909 | + updateBy?: string; | ||
4907 | } | 4910 | } |
4908 | 4911 | ||
4909 | export interface UserPrivatePocketDeleteRequest { | 4912 | export interface UserPrivatePocketDeleteRequest { |
@@ -5138,6 +5141,32 @@ export interface CompanyInfo { | @@ -5138,6 +5141,32 @@ export interface CompanyInfo { | ||
5138 | taxIdIsNotNull?: boolean; | 5141 | taxIdIsNotNull?: boolean; |
5139 | } | 5142 | } |
5140 | 5143 | ||
5144 | +export interface TsgFile { | ||
5145 | + absolute?: boolean; | ||
5146 | + absoluteFile?: TsgFile; | ||
5147 | + absolutePath?: string; | ||
5148 | + canonicalFile?: TsgFile; | ||
5149 | + canonicalPath?: string; | ||
5150 | + directory?: boolean; | ||
5151 | + executable?: boolean; | ||
5152 | + file?: boolean; | ||
5153 | + /** @format int64 */ | ||
5154 | + freeSpace?: number; | ||
5155 | + hidden?: boolean; | ||
5156 | + /** @format int64 */ | ||
5157 | + lastModified?: number; | ||
5158 | + name?: string; | ||
5159 | + parent?: string; | ||
5160 | + parentFile?: TsgFile; | ||
5161 | + path?: string; | ||
5162 | + readable?: boolean; | ||
5163 | + /** @format int64 */ | ||
5164 | + totalSpace?: number; | ||
5165 | + /** @format int64 */ | ||
5166 | + usableSpace?: number; | ||
5167 | + writable?: boolean; | ||
5168 | +} | ||
5169 | + | ||
5141 | export interface InvoiceDetail { | 5170 | export interface InvoiceDetail { |
5142 | createByName?: string; | 5171 | createByName?: string; |
5143 | /** @format date-time */ | 5172 | /** @format date-time */ |
src/services/request.ts
@@ -60,6 +60,7 @@ import type { | @@ -60,6 +60,7 @@ import type { | ||
60 | ExchangeRecordsRequestDto, | 60 | ExchangeRecordsRequestDto, |
61 | FeedbackRegistrationDTO, | 61 | FeedbackRegistrationDTO, |
62 | GroupExchangeRecordsRequestDto, | 62 | GroupExchangeRecordsRequestDto, |
63 | + InstallmentPaymentDTO, | ||
63 | InventoryMaterialStockReq, | 64 | InventoryMaterialStockReq, |
64 | InvoiceBatchDownloadDto, | 65 | InvoiceBatchDownloadDto, |
65 | InvoiceDto, | 66 | InvoiceDto, |
@@ -23367,6 +23368,77 @@ export const postServiceOrderGetReissueInfo = /* #__PURE__ */ (() => { | @@ -23367,6 +23368,77 @@ export const postServiceOrderGetReissueInfo = /* #__PURE__ */ (() => { | ||
23367 | return request; | 23368 | return request; |
23368 | })(); | 23369 | })(); |
23369 | 23370 | ||
23371 | +/** @description request parameter type for postServiceOrderHirePurchase */ | ||
23372 | +export interface PostServiceOrderHirePurchaseOption { | ||
23373 | + /** | ||
23374 | + * @description | ||
23375 | + * dto | ||
23376 | + */ | ||
23377 | + body: { | ||
23378 | + /** | ||
23379 | + @description | ||
23380 | + dto */ | ||
23381 | + dto: InstallmentPaymentDTO; | ||
23382 | + }; | ||
23383 | +} | ||
23384 | + | ||
23385 | +/** @description response type for postServiceOrderHirePurchase */ | ||
23386 | +export interface PostServiceOrderHirePurchaseResponse { | ||
23387 | + /** | ||
23388 | + * @description | ||
23389 | + * OK | ||
23390 | + */ | ||
23391 | + 200: ServerResult; | ||
23392 | + /** | ||
23393 | + * @description | ||
23394 | + * Created | ||
23395 | + */ | ||
23396 | + 201: any; | ||
23397 | + /** | ||
23398 | + * @description | ||
23399 | + * Unauthorized | ||
23400 | + */ | ||
23401 | + 401: any; | ||
23402 | + /** | ||
23403 | + * @description | ||
23404 | + * Forbidden | ||
23405 | + */ | ||
23406 | + 403: any; | ||
23407 | + /** | ||
23408 | + * @description | ||
23409 | + * Not Found | ||
23410 | + */ | ||
23411 | + 404: any; | ||
23412 | +} | ||
23413 | + | ||
23414 | +export type PostServiceOrderHirePurchaseResponseSuccess = | ||
23415 | + PostServiceOrderHirePurchaseResponse[200]; | ||
23416 | +/** | ||
23417 | + * @description | ||
23418 | + * 分期付款 | ||
23419 | + * @tags 内部订单 | ||
23420 | + * @produces * | ||
23421 | + * @consumes application/json | ||
23422 | + */ | ||
23423 | +export const postServiceOrderHirePurchase = /* #__PURE__ */ (() => { | ||
23424 | + const method = 'post'; | ||
23425 | + const url = '/service/order/hirePurchase'; | ||
23426 | + function request( | ||
23427 | + option: PostServiceOrderHirePurchaseOption, | ||
23428 | + ): Promise<PostServiceOrderHirePurchaseResponseSuccess> { | ||
23429 | + return requester(request.url, { | ||
23430 | + method: request.method, | ||
23431 | + ...option, | ||
23432 | + }) as unknown as Promise<PostServiceOrderHirePurchaseResponseSuccess>; | ||
23433 | + } | ||
23434 | + | ||
23435 | + /** http method */ | ||
23436 | + request.method = method; | ||
23437 | + /** request url */ | ||
23438 | + request.url = url; | ||
23439 | + return request; | ||
23440 | +})(); | ||
23441 | + | ||
23370 | /** @description request parameter type for postServiceOrderImportExcel */ | 23442 | /** @description request parameter type for postServiceOrderImportExcel */ |
23371 | export interface PostServiceOrderImportExcelOption { | 23443 | export interface PostServiceOrderImportExcelOption { |
23372 | /** | 23444 | /** |
@@ -25818,6 +25890,77 @@ export const postServiceOrderQuerySupplier = /* #__PURE__ */ (() => { | @@ -25818,6 +25890,77 @@ export const postServiceOrderQuerySupplier = /* #__PURE__ */ (() => { | ||
25818 | return request; | 25890 | return request; |
25819 | })(); | 25891 | })(); |
25820 | 25892 | ||
25893 | +/** @description request parameter type for postServiceOrderRefundHistory */ | ||
25894 | +export interface PostServiceOrderRefundHistoryOption { | ||
25895 | + /** | ||
25896 | + * @description | ||
25897 | + * mainOrderId | ||
25898 | + */ | ||
25899 | + body: { | ||
25900 | + /** | ||
25901 | + @description | ||
25902 | + mainOrderId */ | ||
25903 | + mainOrderId: number; | ||
25904 | + }; | ||
25905 | +} | ||
25906 | + | ||
25907 | +/** @description response type for postServiceOrderRefundHistory */ | ||
25908 | +export interface PostServiceOrderRefundHistoryResponse { | ||
25909 | + /** | ||
25910 | + * @description | ||
25911 | + * OK | ||
25912 | + */ | ||
25913 | + 200: ServerResult; | ||
25914 | + /** | ||
25915 | + * @description | ||
25916 | + * Created | ||
25917 | + */ | ||
25918 | + 201: any; | ||
25919 | + /** | ||
25920 | + * @description | ||
25921 | + * Unauthorized | ||
25922 | + */ | ||
25923 | + 401: any; | ||
25924 | + /** | ||
25925 | + * @description | ||
25926 | + * Forbidden | ||
25927 | + */ | ||
25928 | + 403: any; | ||
25929 | + /** | ||
25930 | + * @description | ||
25931 | + * Not Found | ||
25932 | + */ | ||
25933 | + 404: any; | ||
25934 | +} | ||
25935 | + | ||
25936 | +export type PostServiceOrderRefundHistoryResponseSuccess = | ||
25937 | + PostServiceOrderRefundHistoryResponse[200]; | ||
25938 | +/** | ||
25939 | + * @description | ||
25940 | + * 根据主订单ID查询退款历史记录 | ||
25941 | + * @tags 内部订单 | ||
25942 | + * @produces * | ||
25943 | + * @consumes application/json | ||
25944 | + */ | ||
25945 | +export const postServiceOrderRefundHistory = /* #__PURE__ */ (() => { | ||
25946 | + const method = 'post'; | ||
25947 | + const url = '/service/order/refundHistory'; | ||
25948 | + function request( | ||
25949 | + option: PostServiceOrderRefundHistoryOption, | ||
25950 | + ): Promise<PostServiceOrderRefundHistoryResponseSuccess> { | ||
25951 | + return requester(request.url, { | ||
25952 | + method: request.method, | ||
25953 | + ...option, | ||
25954 | + }) as unknown as Promise<PostServiceOrderRefundHistoryResponseSuccess>; | ||
25955 | + } | ||
25956 | + | ||
25957 | + /** http method */ | ||
25958 | + request.method = method; | ||
25959 | + /** request url */ | ||
25960 | + request.url = url; | ||
25961 | + return request; | ||
25962 | +})(); | ||
25963 | + | ||
25821 | /** @description request parameter type for postServiceOrderRemindShipping */ | 25964 | /** @description request parameter type for postServiceOrderRemindShipping */ |
25822 | export interface PostServiceOrderRemindShippingOption { | 25965 | export interface PostServiceOrderRemindShippingOption { |
25823 | /** | 25966 | /** |