Commit 8586bf0f94805adea7e812f6e98b1be3fe09a398

Authored by boyang
2 parents 9d2cc6bc 0ef6ed3f

Merge branch 'warningNew'

# Conflicts:
#	src/pages/Order/Order/components/FeedbackRegistrationModal.tsx
#	src/pages/Order/OrderList/FeedbackRegistrationModal.tsx
#	src/pages/Order/OrderWarning/components/FeedbackRegistrationModal.tsx
.umirc.ts
... ... @@ -153,7 +153,7 @@ export default defineConfig({
153 153 routes: [
154 154 {
155 155 name: '客户列表',
156   - path: 'clint',
  156 + path: 'client',
157 157 component: './Client/Client',
158 158 },
159 159 {
... ...
src/pages/Client/Client/Components/ClientInformationModal.tsx
1 1 import { RESPONSE_CODE } from '@/constants/enum';
2   -import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg';
3 2 import {
4 3 postAdminClientAddOrModifyClientComunicationInfo,
5 4 postAdminClientQueryClientPage,
... ... @@ -10,19 +9,43 @@ import {
10 9 } from '@/services';
11 10 import { enumToSelect } from '@/utils';
12 11 import {
  12 + FormListActionType,
13 13 ModalForm,
  14 + ProCard,
14 15 ProFormDateTimePicker,
  16 + ProFormList,
15 17 ProFormSelect,
16 18 ProFormText,
17 19 ProFormTextArea,
18 20 ProFormUploadDragger,
19 21 } from '@ant-design/pro-components';
20   -import { Button, Col, Form, Row, message } from 'antd';
  22 +import { Button, Form, message } from 'antd';
21 23 import { RcFile } from 'antd/es/upload';
  24 +import { useRef } from 'react';
22 25 import './style.css';
23 26 export default ({ data, type, reloadTable }) => {
24 27 const [form] = Form.useForm();
  28 + const actionRef = useRef<
  29 + FormListActionType<{
  30 + name: string;
  31 + }>
  32 + >();
  33 + const fileList: any = [];
25 34 const onfinish = async (values) => {
  35 + let list = values.ticketsList;
  36 + list = list.map((item) => {
  37 + let itemAnnexUrl = null;
  38 + // 尝试从 item.filePaths 中获取 annexUrl
  39 + if (item?.filePaths) {
  40 + itemAnnexUrl = item?.filePaths?.[0]?.response?.data?.[0] || null;
  41 + } else {
  42 + itemAnnexUrl = null;
  43 + }
  44 + item.annexUrl = itemAnnexUrl;
  45 + return item;
  46 + });
  47 +
  48 + values.list = list;
26 49 const resSearchId = await postAdminClientQueryClientPage({
27 50 data: {
28 51 groupFilter: 'all',
... ... @@ -54,25 +77,32 @@ export default ({ data, type, reloadTable }) =&gt; {
54 77 const editOnfinish = async (values) => {
55 78 // setEditClientId(data.clientId);
56 79 values.clientId = data.clientId;
57   - console.log(values, '5656editClientId');
58   -
59   - // const resSearchId = await postAdminClientQueryClientPage({
60   - // data: {
61   - // groupFilter: 'all',
62   - // },
63   - // });
64   - // const matchingItem = resSearchId.data.data.find(
65   - // (item) => item.id === values.name,
66   - // );
  80 + let list = values.ticketsList;
  81 + list = list.map((item, index) => {
  82 + // 尝试从 item.filePaths 中获取 annexUrl
  83 + const itemAnnexUrl = item?.filePaths?.[0]?.response?.data?.[0] || null;
67 84  
  85 + // 如果 itemAnnexUrl 为 null,则使用 data.ticketsList 对应的 annexUrl
  86 + if (
  87 + itemAnnexUrl === null &&
  88 + data.ticketsList[index]?.annexUrl &&
  89 + index < data.ticketsList.length
  90 + ) {
  91 + item.annexUrl = data.ticketsList[index].annexUrl; // 确保对比中的 annesUrl 也是 null
  92 + } else {
  93 + item.annexUrl = itemAnnexUrl; // 否则,使用从 item.filePaths 中获取的值
  94 + }
  95 + return item;
  96 + });
  97 + values.list = list;
68 98 const res = await postAdminClientAddOrModifyClientComunicationInfo({
69 99 data: {
70 100 ...values,
71 101 // ticketsAttachments: form.getFieldValue("ticketsAttachments"),
72   - ticketsAttachments:
73   - form.getFieldValue('ticketsAttachments') !== undefined
74   - ? form.getFieldValue('ticketsAttachments')
75   - : data?.ticketsAttachments,
  102 + // ticketsAttachments:
  103 + // form.getFieldValue('ticketsAttachments') !== undefined
  104 + // ? form.getFieldValue('ticketsAttachments')
  105 + // : data?.ticketsAttachments,
76 106 // ticketsAttachments: data?.annexUrl,
77 107 },
78 108 });
... ... @@ -150,18 +180,6 @@ export default ({ data, type, reloadTable }) =&gt; {
150 180 groupFilter: 'all',
151 181 },
152 182 });
153   - console.log(data, '5656data?.nameedit');
154   - // const namesArray = res.data.data.map((item) => item.name);
155   - // const formattedObject = res.data.data.reduce((acc, name) => {
156   - // acc[name] = name; // 将名称作为键和值
157   - // return acc;
158   - // }, {});
159   - // console.log(namesArray, '5656namesArray');
160   - // const formattedObject = res.data.data.reduce((acc, item) => {
161   - // acc[item.name] = item.name; // 使用 name 作为键,id 作为值
162   - // return acc;
163   - // }, {});
164   - // return enumToSelect(formattedObject);
165 183 const options = res.data.data.reduce((acc, item) => {
166 184 acc.push({ label: item.name, value: item.id }); // 使用 name 作为 label,id 作为 value
167 185 return acc;
... ... @@ -180,7 +198,7 @@ export default ({ data, type, reloadTable }) =&gt; {
180 198 label="联系人"
181 199 width="sm"
182 200 placeholder="请输入联系人"
183   - initialValue={data?.content}
  201 + initialValue={data?.contact}
184 202 readonly={optType[type].readOnly}
185 203 rules={[
186 204 {
... ... @@ -194,7 +212,7 @@ export default ({ data, type, reloadTable }) =&gt; {
194 212 label="联系电话"
195 213 width="sm"
196 214 placeholder="请输入联系电话"
197   - initialValue={data?.content}
  215 + initialValue={data?.contactPhone}
198 216 readonly={optType[type].readOnly}
199 217 rules={[
200 218 {
... ... @@ -314,7 +332,168 @@ export default ({ data, type, reloadTable }) =&gt; {
314 332 hidden
315 333 ></ProFormText>
316 334 <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
317   - <div className="styled-text">
  335 + <h2>工单指派</h2>
  336 + <ProFormList
  337 + // creatorButtonProps={{ disabled: optType('after-sales-check') }}
  338 + // deleteIconProps={!optType('after-sales-check')}
  339 + deleteIconProps={true}
  340 + name="ticketsList"
  341 + label=""
  342 + copyIconProps={false} //复制按钮不显示
  343 + // initialValue={[
  344 + // {
  345 + // ticketsType: '',
  346 + // ticketsDetail: '',
  347 + // assignPeople: '',
  348 + // ticketsAttachment: '',
  349 + // ticketsAttachments: '',
  350 + // },
  351 + // ]}
  352 + initialValue={
  353 + optType[type].title === '修改跟进记录'
  354 + ? data.ticketsList || []
  355 + : [
  356 + {
  357 + type: '',
  358 + detailText: '',
  359 + assignPeople: '',
  360 + annexUrl: '',
  361 + },
  362 + ]
  363 + }
  364 + actionGuard={{
  365 + beforeRemoveRow: async () => {
  366 + return new Promise((resolve) => {
  367 + let list = form.getFieldValue('ticketsList');
  368 + if (list && list.length === 1) {
  369 + message.error('至少需要保留一个工单');
  370 + resolve(false);
  371 + return;
  372 + }
  373 + resolve(true);
  374 + });
  375 + },
  376 + }}
  377 + itemRender={(doms, listMeta) => {
  378 + if (optType[type].title === '修改跟进记录') {
  379 + // let i = 0;
  380 + // // let defaultFileList = data.ticketsList?.annexUrl?.map((annex) => {
  381 + // // return {
  382 + // // uid: i++,
  383 + // // name: annex,
  384 + // // status: 'uploaded',
  385 + // // url: annex,
  386 + // // response: { data: [annex] },
  387 + // // };
  388 + // // });
  389 + let defaultFileList = [
  390 + {
  391 + uid: listMeta.index,
  392 + name: data.ticketsList[listMeta.index]?.annexUrl,
  393 + status: 'uploaded',
  394 + url: data.ticketsList[listMeta.index]?.annexUrl,
  395 + response: {
  396 + data: [data.ticketsList[listMeta.index]?.annexUrl],
  397 + },
  398 + },
  399 + ];
  400 + fileList[listMeta.index] = defaultFileList;
  401 + }
  402 + let itemFileList = fileList[listMeta.index];
  403 + return (
  404 + <ProCard
  405 + bordered
  406 + extra={doms.action}
  407 + title={'工单指派' + (listMeta.index + 1)}
  408 + style={{
  409 + marginBlockEnd: 8,
  410 + }}
  411 + >
  412 + {[
  413 + <ProFormSelect
  414 + key={'type' + listMeta.index}
  415 + name="type"
  416 + label="工单类型"
  417 + width="sm"
  418 + placeholder="请输入工单类型"
  419 + readonly={optType[type].readOnly}
  420 + fieldProps={{
  421 + labelInValue: false,
  422 + }}
  423 + // initialValue={data?.ticketsList?.type ? data?.ticketsList?.type + '' : null}
  424 + initialValue={
  425 + data?.ticketsList ? data?.ticketsList?.type + '' : null
  426 + }
  427 + request={async () => {
  428 + return [
  429 + { label: '问题', value: 'QUESTION' },
  430 + { label: '需求', value: 'DEMAND' },
  431 + { label: '建议', value: 'ADVICE' },
  432 + ];
  433 + }}
  434 + />,
  435 + <ProFormTextArea
  436 + key={'detailText' + listMeta.index}
  437 + name="detailText"
  438 + label="工单详情"
  439 + placeholder="请输入工单详情"
  440 + initialValue={data?.detailText ? data?.detailText + '' : null}
  441 + readonly={optType[type].readOnly}
  442 + ></ProFormTextArea>,
  443 + <ProFormSelect
  444 + key={'assignPeople' + listMeta.index}
  445 + name="assignPeople"
  446 + width="sm"
  447 + readonly={optType[type].readOnly}
  448 + fieldProps={{
  449 + labelInValue: false,
  450 + }}
  451 + initialValue={
  452 + data?.assignPeople ? data?.assignPeople + '' : null
  453 + }
  454 + label="指派人员"
  455 + request={async () => {
  456 + const res = await postOrderErpUsersListByPage({
  457 + data: {
  458 + pageSize: 10000,
  459 + },
  460 + });
  461 +
  462 + const userOptions = res.data.records
  463 + ? res.data.records.map((user) => ({
  464 + label: user.userName, // 或者使用其他需要的属性
  465 + value: user.userName, // 作为value的字段
  466 + }))
  467 + : [];
  468 + return userOptions;
  469 + }}
  470 + ></ProFormSelect>,
  471 + <>
  472 + <ProFormUploadDragger
  473 + key={'filePaths' + listMeta.index}
  474 + label="附件"
  475 + name="filePaths"
  476 + action="/api/service/order/fileProcess"
  477 + fieldProps={{
  478 + headers: {
  479 + Authorization: localStorage.getItem('token'),
  480 + },
  481 + // headers: {
  482 + // 'Content-Type':
  483 + // 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  484 + // },
  485 + itemFileList,
  486 + }}
  487 + max={1}
  488 + />
  489 + </>,
  490 + ]}
  491 + </ProCard>
  492 + );
  493 + }}
  494 + actionRef={actionRef}
  495 + ></ProFormList>
  496 + {/* <div className="styled-text">
318 497 <div className="vertical-line"></div>
319 498 <span className="text">工单指派</span>
320 499 </div>
... ... @@ -342,7 +521,7 @@ export default ({ data, type, reloadTable }) =&gt; {
342 521 placeholder="请输入工单详情"
343 522 initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null}
344 523 readonly={optType[type].readOnly}
345   - ></ProFormTextArea>
  524 + ></ProFormTextArea> */}
346 525 {/* <ProFormUploadDragger
347 526 label="工单附件"
348 527 name="ticketsAttachment"
... ... @@ -371,7 +550,7 @@ export default ({ data, type, reloadTable }) =&gt; {
371 550 }}
372 551 max={1}
373 552 /> */}
374   - <Row>
  553 + {/* <Row>
375 554 <Col span={4}>附件:</Col>
376 555 <Col span={20}>
377 556 <UploadC
... ... @@ -426,13 +605,13 @@ export default ({ data, type, reloadTable }) =&gt; {
426 605  
427 606 const userOptions = res.data.records
428 607 ? res.data.records.map((user) => ({
429   - label: user.userName, // 或者使用其他需要的属性
430   - value: user.userName, // 作为value的字段
431   - }))
  608 + label: user.userName, // 或者使用其他需要的属性
  609 + value: user.userName, // 作为value的字段
  610 + }))
432 611 : [];
433 612 return userOptions;
434 613 }}
435   - ></ProFormSelect>
  614 + ></ProFormSelect> */}
436 615 </ModalForm>
437 616 );
438 617 };
... ...
src/pages/Client/Client/Components/ClientModal.tsx
1 1 import { RESPONSE_CODE } from '@/constants/enum';
2   -import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg';
3 2 import {
4 3 postAdminClientAddOrModifyClientComunicationInfo,
5 4 postAdminClientQueryClientPage,
... ... @@ -10,74 +9,43 @@ import {
10 9 } from '@/services';
11 10 import { enumToSelect } from '@/utils';
12 11 import {
  12 + FormListActionType,
13 13 ModalForm,
  14 + ProCard,
14 15 ProFormDateTimePicker,
  16 + ProFormList,
15 17 ProFormSelect,
16 18 ProFormText,
17 19 ProFormTextArea,
18 20 ProFormUploadDragger,
19 21 } from '@ant-design/pro-components';
20   -import { Button, Col, Form, Row, message } from 'antd';
  22 +import { Button, Form, message } from 'antd';
21 23 import { RcFile } from 'antd/es/upload';
  24 +import { useRef } from 'react';
22 25 import './style.css';
23   -// import { useRef, useState } from 'react';
24 26 export default ({ data, type, reloadTable }) => {
25   - // const initialItems = [
26   - // { label: 'Tab 1', children: 'Content of Tab 1', key: '1' },
27   - // ];
28   - // const [activeKey, setActiveKey] = useState(initialItems[0].key);
29   - // const [items, setItems] = useState(initialItems);
30   - // const newTabIndex = useRef(1);
31   -
32   - // const onChange = (newActiveKey: string) => {
33   - // setActiveKey(newActiveKey);
34   - // };
35   -
36   - // const add = () => {
37   - // // 生成新的标签名,格式为 'Tab {num}'
38   - // const newTabLabel = `Tab ${newTabIndex.current + 1}`;
39   - // // 增加索引,保证下次生成新的Tab名称时,num会递增
40   - // newTabIndex.current++;
41   - // // 创建新的panes,追加新Tab
42   - // const newActiveKey = `newTab${newTabIndex.current}`;
43   - // const newPanes = [...items];
44   - // newPanes.push({ label: newTabLabel, children: 'Content of new Tab', key: newActiveKey });
45   - // setItems(newPanes);
46   - // setActiveKey(newActiveKey);
47   - // };
48   -
49   - // const remove = (targetKey: TargetKey) => {
50   - // let newActiveKey = activeKey;
51   - // let lastIndex = -1;
52   - // items.forEach((item, i) => {
53   - // if (item.key === targetKey) {
54   - // lastIndex = i - 1;
55   - // }
56   - // });
57   - // const newPanes = items.filter((item) => item.key !== targetKey);
58   - // if (newPanes.length && newActiveKey === targetKey) {
59   - // if (lastIndex >= 0) {
60   - // newActiveKey = newPanes[lastIndex].key;
61   - // } else {
62   - // newActiveKey = newPanes[0].key;
63   - // }
64   - // }
65   - // setItems(newPanes);
66   - // setActiveKey(newActiveKey);
67   - // };
68   -
69   - // const onEdit = (
70   - // targetKey: React.MouseEvent | React.KeyboardEvent | string,
71   - // action: 'add' | 'remove',
72   - // ) => {
73   - // if (action === 'add') {
74   - // add();
75   - // } else {
76   - // remove(targetKey);
77   - // }
78   - // };
79 27 const [form] = Form.useForm();
  28 + const actionRef = useRef<
  29 + FormListActionType<{
  30 + name: string;
  31 + }>
  32 + >();
  33 + const fileList: any = [];
80 34 const onfinish = async (values) => {
  35 + let list = values.list;
  36 +
  37 + list = list.map((item) => {
  38 + let itemAnnexUrl = null;
  39 + // 尝试从 item.filePaths 中获取 annexUrl
  40 + if (item?.filePaths) {
  41 + itemAnnexUrl = item?.filePaths?.[0]?.response?.data?.[0] || null;
  42 + } else {
  43 + itemAnnexUrl = null;
  44 + }
  45 + item.annexUrl = itemAnnexUrl;
  46 + return item;
  47 + });
  48 + values.list = list;
81 49 const res = await postAdminClientAddOrModifyClientComunicationInfo({
82 50 data: {
83 51 ...values,
... ... @@ -184,7 +152,7 @@ export default ({ data, type, reloadTable }) =&gt; {
184 152 label="联系人"
185 153 width="sm"
186 154 placeholder="请输入联系人"
187   - initialValue={data?.content}
  155 + initialValue={data?.contact}
188 156 readonly={optType[type].readOnly}
189 157 rules={[
190 158 {
... ... @@ -198,7 +166,7 @@ export default ({ data, type, reloadTable }) =&gt; {
198 166 label="联系电话"
199 167 width="sm"
200 168 placeholder="请输入联系电话"
201   - initialValue={data?.content}
  169 + initialValue={data?.contactPhone}
202 170 readonly={optType[type].readOnly}
203 171 rules={[
204 172 {
... ... @@ -318,132 +286,140 @@ export default ({ data, type, reloadTable }) =&gt; {
318 286 hidden
319 287 ></ProFormText>
320 288 <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
321   - {/* <Tabs
322   - type="editable-card"
323   - onChange={onChange}
324   - activeKey={activeKey}
325   - onEdit={onEdit}
326   - items={items}
327   - /> */}
328   - <div className="styled-text">
329   - <div className="vertical-line"></div>
330   - <span className="text">工单指派</span>
331   - </div>
332   - <ProFormSelect
333   - name="ticketsType"
334   - label="工单类型"
335   - width="sm"
336   - placeholder="请输入工单类型"
337   - readonly={optType[type].readOnly}
338   - fieldProps={{
339   - labelInValue: false,
340   - }}
341   - initialValue={data?.type ? data?.type + '' : null}
342   - request={async () => {
343   - return [
344   - { label: '问题', value: 'QUESTION' },
345   - { label: '需求', value: 'DEMAND' },
346   - { label: '建议', value: 'ADVICE' },
347   - ];
348   - }}
349   - />
350   - <ProFormTextArea
351   - name="ticketsDetail"
352   - label="工单详情"
353   - placeholder="请输入工单详情"
354   - initialValue={data?.detailText ? data?.detailText + '' : null}
355   - readonly={optType[type].readOnly}
356   - ></ProFormTextArea>
357   - <Row>
358   - <Col span={4}>附件:</Col>
359   - <Col span={20}>
360   - <UploadC
361   - onFilesChange={async (newFileList) => {
362   - if (newFileList.length > 0) {
363   - const urls = []; // 创建一个数组来存储所有的 URL
364   -
365   - for (const file of newFileList) {
366   - const formData = new FormData();
367   - formData.append('file', file.originFileObj as RcFile);
368   -
369   - const res = await postOrderErpOrderStagesUpload({
370   - data: formData,
371   - headers: {
372   - 'Content-Type':
373   - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
374   - },
375   - });
376   -
377   - const url = res.data; // 获取响应中的 URL
378   - urls.push(url); // 将每个 URL 追加到数组中
379   - }
380   -
381   - // 将所有 URL 使用 ',' 进行拼接
382   - const combinedUrl = urls.join(',');
383   - form.setFieldValue('ticketsAttachments', combinedUrl); // 设置表单字段值为拼接后的 URL
384   - } else {
385   - form.setFieldValue('ticketsAttachments', null); // 如果没有文件,则清空 URL
  289 + <h2>工单指派</h2>
  290 + <ProFormList
  291 + // creatorButtonProps={{ disabled: optType('after-sales-check') }}
  292 + // deleteIconProps={!optType('after-sales-check')}
  293 + deleteIconProps={true}
  294 + name="list"
  295 + label=""
  296 + copyIconProps={false} //复制按钮不显示
  297 + initialValue={[
  298 + {
  299 + type: '',
  300 + detailText: '',
  301 + assignPeople: '',
  302 + annexUrl: '',
  303 + },
  304 + ]}
  305 + actionGuard={{
  306 + beforeRemoveRow: async () => {
  307 + return new Promise((resolve) => {
  308 + let list = form.getFieldValue('list');
  309 + if (list && list.length === 1) {
  310 + message.error('至少需要保留一个工单');
  311 + resolve(false);
  312 + return;
386 313 }
387   - }}
388   - ></UploadC>
389   - </Col>
390   - </Row>
391   - {/* <ProFormUploadDragger
392   - label="工单附件"
393   - name="ticketsAttachment"
394   - action="upload.do"
395   - hidden={optType[type].readOnly}
396   - onChange={(info) => {
397   - const uploadFile = async ({ fileList: newFileList }) => {
398   - if (newFileList.length > 0) {
399   - const formData = new FormData();
400   - formData.append('file', newFileList[0].originFileObj as RcFile);
401   - const res = await postOrderErpOrderStagesUpload({
402   - data: formData,
403   - headers: {
404   - 'Content-Type':
405   - 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
406   - },
407   - });
408   - const url = res.data;
409   - console.log('ticketsAttachments' + JSON.stringify(url));
410   - form.setFieldValue('ticketsAttachments', url);
411   - } else {
412   - form.setFieldValue('ticketsAttachments', null);
413   - }
414   - };
415   - uploadFile(info);
416   - }}
417   - max={1}
418   - /> */}
419   - <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download>
420   - 下载附件
421   - </a>
422   - <ProFormSelect
423   - name="assignPeople"
424   - width="sm"
425   - readonly={optType[type].readOnly}
426   - fieldProps={{
427   - labelInValue: false,
  314 + resolve(true);
  315 + });
  316 + },
428 317 }}
429   - initialValue={data?.assignPeople ? data?.assignPeople + '' : null}
430   - label="指派人员"
431   - request={async () => {
432   - const res = await postOrderErpUsersListByPage({
433   - data: {
434   - pageSize: 10000,
435   - },
436   - });
  318 + itemRender={(doms, listMeta) => {
  319 + if (optType[type].modify || optType[type].add || optType[type].add2) {
  320 + let i = 0;
  321 + let defaultFileList = listMeta.record?.listAnnex?.map((annex) => {
  322 + return {
  323 + uid: i++,
  324 + name: annex,
  325 + status: 'uploaded',
  326 + url: annex,
  327 + response: { data: [annex] },
  328 + };
  329 + });
  330 + fileList[listMeta.index] = defaultFileList;
  331 + }
  332 + let itemFileList = fileList[listMeta.index];
  333 + return (
  334 + <ProCard
  335 + bordered
  336 + extra={doms.action}
  337 + title={'工单指派' + (listMeta.index + 1)}
  338 + style={{
  339 + marginBlockEnd: 8,
  340 + }}
  341 + >
  342 + {[
  343 + <ProFormSelect
  344 + key={'type' + listMeta.index}
  345 + name="type"
  346 + label="工单类型"
  347 + width="sm"
  348 + placeholder="请输入工单类型"
  349 + readonly={optType[type].readOnly}
  350 + fieldProps={{
  351 + labelInValue: false,
  352 + }}
  353 + initialValue={data?.type ? data?.type + '' : null}
  354 + request={async () => {
  355 + return [
  356 + { label: '问题', value: 'QUESTION' },
  357 + { label: '需求', value: 'DEMAND' },
  358 + { label: '建议', value: 'ADVICE' },
  359 + ];
  360 + }}
  361 + />,
  362 + <ProFormTextArea
  363 + key={'detailText' + listMeta.index}
  364 + name="detailText"
  365 + label="工单详情"
  366 + placeholder="请输入工单详情"
  367 + initialValue={data?.detailText ? data?.detailText + '' : null}
  368 + readonly={optType[type].readOnly}
  369 + ></ProFormTextArea>,
  370 + <ProFormSelect
  371 + key={'assignPeople' + listMeta.index}
  372 + name="assignPeople"
  373 + width="sm"
  374 + readonly={optType[type].readOnly}
  375 + fieldProps={{
  376 + labelInValue: false,
  377 + }}
  378 + initialValue={
  379 + data?.assignPeople ? data?.assignPeople + '' : null
  380 + }
  381 + label="指派人员"
  382 + request={async () => {
  383 + const res = await postOrderErpUsersListByPage({
  384 + data: {
  385 + pageSize: 10000,
  386 + },
  387 + });
437 388  
438   - const userOptions = res.data.records
439   - ? res.data.records.map((user) => ({
440   - label: user.userName, // 或者使用其他需要的属性
441   - value: user.userName, // 作为value的字段
442   - }))
443   - : [];
444   - return userOptions;
  389 + const userOptions = res.data.records
  390 + ? res.data.records.map((user) => ({
  391 + label: user.userName, // 或者使用其他需要的属性
  392 + value: user.userName, // 作为value的字段
  393 + }))
  394 + : [];
  395 + return userOptions;
  396 + }}
  397 + ></ProFormSelect>,
  398 + <>
  399 + <ProFormUploadDragger
  400 + key={'filePaths' + listMeta.index}
  401 + label="附件"
  402 + name="filePaths"
  403 + action="/api/service/order/fileProcess"
  404 + fieldProps={{
  405 + headers: {
  406 + Authorization: localStorage.getItem('token'),
  407 + },
  408 + // headers: {
  409 + // 'Content-Type':
  410 + // 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  411 + // },
  412 + itemFileList,
  413 + }}
  414 + max={1}
  415 + />
  416 + </>,
  417 + ]}
  418 + </ProCard>
  419 + );
445 420 }}
446   - ></ProFormSelect>
  421 + actionRef={actionRef}
  422 + ></ProFormList>
447 423 </ModalForm>
448 424 );
449 425 };
... ...
src/pages/Client/Client/Components/InformationHistoryModal.tsx
... ... @@ -27,10 +27,6 @@ export default ({ data, reloadTable }) =&gt; {
27 27 const [createTime, setCreateTime] = useState(null); // 创建时间
28 28 const [attachments, setAttachments] = useState(); //附件
29 29 const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称
30   - const [ticketsType, setTicketsType] = useState(''); // 附件名称
31   - const [ticketsDetail, setTicketsDetail] = useState(''); // 附件名称
32   - const [ticketsAttachment, setTicketsAttachment] = useState(''); // 附件名称
33   - const [assignPeople, setAssignPeople] = useState(''); // 附件名称
34 30 const [comment, setComment] = useState(''); // 客户评价
35 31  
36 32 useEffect(() => {
... ... @@ -56,10 +52,6 @@ export default ({ data, reloadTable }) =&gt; {
56 52 }
57 53 }
58 54 setComment(dataSearch.comment);
59   - setTicketsType(dataSearch.ticketsTypeText);
60   - setTicketsDetail(dataSearch.ticketsDetail);
61   - setTicketsAttachment(dataSearch.ticketsAttachments);
62   - setAssignPeople(dataSearch.assignPeople);
63 55 setDatetime(dataSearch.datetime); // 设置跟进日期
64 56 // setDateRange(data.dateRange || []); // 设置跟进时间范围
65 57 setCreateByName(dataSearch.createByName); // 设置跟进人员
... ... @@ -115,26 +107,6 @@ export default ({ data, reloadTable }) =&gt; {
115 107 },
116 108 {
117 109 key: '8',
118   - label: '工单类型',
119   - children: ticketsType, // 跟进状态
120   - },
121   - {
122   - key: '9',
123   - label: '工单详情',
124   - children: ticketsDetail, // 跟进状态
125   - },
126   - // {
127   - // key: '10',
128   - // label: '工单附件',
129   - // children: ticketsAttachment, // 跟进状态
130   - // },
131   - {
132   - key: '10',
133   - label: '指派人员',
134   - children: assignPeople, // 跟进状态
135   - },
136   - {
137   - key: '11',
138 110 label: '客户评价',
139 111 children: comment, // 跟进状态
140 112 },
... ... @@ -151,6 +123,40 @@ export default ({ data, reloadTable }) =&gt; {
151 123 actionRef?.current?.reload(); // 重新加载表格数据
152 124 }
153 125 };
  126 + const TicketDescriptions = ({ data }) => {
  127 + return (
  128 + <div>
  129 + {data.ticketsList && data.ticketsList.length > 0 ? (
  130 + data.ticketsList.map((ticket, index) => (
  131 + <div key={index} style={{ marginBottom: '20px' }}>
  132 + <Descriptions title={`工单 ${index + 1}`} column={1}>
  133 + <Descriptions.Item label="工单类型">
  134 + {ticket.typeText}
  135 + </Descriptions.Item>
  136 + <Descriptions.Item label="工单详情">
  137 + {ticket.detailText}
  138 + </Descriptions.Item>
  139 + <Descriptions.Item label="指派人员">
  140 + {ticket.assignPeople}
  141 + </Descriptions.Item>
  142 + </Descriptions>
  143 + {ticket.annexUrl && (
  144 + <a
  145 + href={ticket.annexUrl}
  146 + target="_blank"
  147 + rel="noopener noreferrer"
  148 + >
  149 + 下载工单附件
  150 + </a>
  151 + )}
  152 + </div>
  153 + ))
  154 + ) : (
  155 + <p></p>
  156 + )}
  157 + </div>
  158 + );
  159 + };
154 160 return (
155 161 <Space>
156 162 <ModalForm
... ... @@ -215,11 +221,6 @@ export default ({ data, reloadTable }) =&gt; {
215 221 }}
216 222 >
217 223 <Descriptions items={items} column={1} />
218   - {/* {attachmentsName && (
219   - <a href={attachments} download>
220   - 附件:{attachmentsName}
221   - </a>
222   - )} */}
223 224 {attachmentsName && (
224 225 <div>
225 226 {attachmentsName.endsWith('.png') ||
... ... @@ -242,6 +243,12 @@ export default ({ data, reloadTable }) =&gt; {
242 243 )}
243 244 </div>
244 245 )}
  246 + <TicketDescriptions data={data} />
  247 + {/* {attachmentsName && (
  248 + <a href={attachments} download>
  249 + 附件:{attachmentsName}
  250 + </a>
  251 + )} */}
245 252  
246 253 <div></div>
247 254 {/* {ticketsAttachment && (
... ... @@ -271,12 +278,12 @@ export default ({ data, reloadTable }) =&gt; {
271 278 )}
272 279 </div>
273 280 )} */}
274   - {ticketsAttachment && (
  281 + {/* {ticketsAttachment && (
275 282 <div>
276 283 {ticketsAttachment.split(',').map((ticketsAttachment, index) => (
277 284 <div key={index}>
278 285 {ticketsAttachment.includes('jpg') ||
279   - ticketsAttachment.includes('png') ? (
  286 + ticketsAttachment.includes('png') ? (
280 287 <>
281 288 <img
282 289 src={ticketsAttachment}
... ... @@ -292,7 +299,7 @@ export default ({ data, reloadTable }) =&gt; {
292 299 </div>
293 300 ))}
294 301 </div>
295   - )}
  302 + )} */}
296 303 </ModalForm>
297 304 </Space>
298 305 );
... ...
src/pages/Client/FollowRecord/Components/ClientModal.tsx
1 1 import { RESPONSE_CODE } from '@/constants/enum';
2   -import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg';
3 2 import {
4 3 postAdminClientAddOrModifyClientComunicationInfo,
5 4 postAdminClientQueryClientPage,
... ... @@ -10,21 +9,43 @@ import {
10 9 } from '@/services';
11 10 import { enumToSelect } from '@/utils';
12 11 import {
  12 + FormListActionType,
13 13 ModalForm,
  14 + ProCard,
14 15 ProFormDateTimePicker,
  16 + ProFormList,
15 17 ProFormSelect,
16 18 ProFormText,
17 19 ProFormTextArea,
18 20 ProFormUploadDragger,
19 21 } from '@ant-design/pro-components';
20   -import { Button, Col, Form, Row, message } from 'antd';
  22 +import { Button, Form, message } from 'antd';
21 23 import { RcFile } from 'antd/es/upload';
22   -import { useEffect } from 'react';
  24 +import { useEffect, useRef } from 'react';
23 25 import './style.css';
24 26 export default ({ data, type, reloadTable }) => {
25 27 useEffect(() => {});
26 28 const [form] = Form.useForm();
  29 + const actionRef = useRef<
  30 + FormListActionType<{
  31 + name: string;
  32 + }>
  33 + >();
  34 + const fileList: any = [];
27 35 const onfinish = async (values) => {
  36 + let list = values.ticketsList;
  37 + list = list.map((item) => {
  38 + let itemAnnexUrl = null;
  39 + // 尝试从 item.filePaths 中获取 annexUrl
  40 + if (item?.filePaths) {
  41 + itemAnnexUrl = item?.filePaths?.[0]?.response?.data?.[0] || null;
  42 + } else {
  43 + itemAnnexUrl = null;
  44 + }
  45 + item.annexUrl = itemAnnexUrl;
  46 + return item;
  47 + });
  48 + values.list = list;
28 49 const resSearchId = await postAdminClientQueryClientPage({
29 50 data: {
30 51 groupFilter: 'all',
... ... @@ -43,7 +64,7 @@ export default ({ data, type, reloadTable }) =&gt; {
43 64 const res = await postAdminClientAddOrModifyClientComunicationInfo({
44 65 data: {
45 66 ...values,
46   - ticketsAttachments: form.getFieldValue('ticketsAttachments'),
  67 + // ticketsAttachments: form.getFieldValue('ticketsAttachments'),
47 68 clientId: matchedId,
48 69 },
49 70 });
... ... @@ -58,24 +79,35 @@ export default ({ data, type, reloadTable }) =&gt; {
58 79 const editOnfinish = async (values) => {
59 80 // setEditClientId(data.clientId);
60 81 values.clientId = data.clientId;
61   -
62   - // const resSearchId = await postAdminClientQueryClientPage({
63   - // data: {
64   - // groupFilter: 'all',
65   - // },
  82 + let list = values.ticketsList;
  83 + // list = list.map((item) => {
  84 + // // item.annexUrl = item.filePaths?.map((file) => {
  85 + // // return { url: file.response.data[0] };
  86 + // // });
  87 + // // item.annexUrl = item?.filePaths[0].response?.data[0];
  88 + // item.annexUrl = item?.filePaths?.[0]?.response?.data?.[0] || null; // 使用 null 或默认值
  89 + // return item;
66 90 // });
67   - // const matchingItem = resSearchId.data.data.find(
68   - // (item) => item.id === values.name,
69   - // );
  91 + list = list.map((item, index) => {
  92 + // 尝试从 item.filePaths 中获取 annexUrl
  93 + const itemAnnexUrl = item?.filePaths?.[0]?.response?.data?.[0] || null;
  94 +
  95 + // 如果 itemAnnexUrl 为 null,则使用 data.ticketsList 对应的 annexUrl
  96 + if (
  97 + itemAnnexUrl === null &&
  98 + data.ticketsList[index]?.annexUrl &&
  99 + index < data.ticketsList.length
  100 + ) {
  101 + item.annexUrl = data.ticketsList[index].annexUrl; // 确保对比中的 annesUrl 也是 null
  102 + } else {
  103 + item.annexUrl = itemAnnexUrl; // 否则,使用从 item.filePaths 中获取的值
  104 + }
  105 + return item;
  106 + });
  107 + values.list = list;
70 108 const res = await postAdminClientAddOrModifyClientComunicationInfo({
71 109 data: {
72 110 ...values,
73   - // ticketsAttachments: form.getFieldValue("ticketsAttachments"),
74   - ticketsAttachments:
75   - form.getFieldValue('ticketsAttachments') !== undefined
76   - ? form.getFieldValue('ticketsAttachments')
77   - : data?.ticketsAttachments,
78   - // ticketsAttachments: data?.annexUrl,
79 111 },
80 112 });
81 113 if (res.result === RESPONSE_CODE.SUCCESS) {
... ... @@ -315,7 +347,168 @@ export default ({ data, type, reloadTable }) =&gt; {
315 347 hidden
316 348 ></ProFormText>
317 349 <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
318   - <div className="styled-text">
  350 + <h2>工单指派</h2>
  351 + <ProFormList
  352 + // creatorButtonProps={{ disabled: optType('after-sales-check') }}
  353 + // deleteIconProps={!optType('after-sales-check')}
  354 + deleteIconProps={true}
  355 + name="ticketsList"
  356 + label=""
  357 + copyIconProps={false} //复制按钮不显示
  358 + // initialValue={[
  359 + // {
  360 + // ticketsType: '',
  361 + // ticketsDetail: '',
  362 + // assignPeople: '',
  363 + // ticketsAttachment: '',
  364 + // ticketsAttachments: '',
  365 + // },
  366 + // ]}
  367 + initialValue={
  368 + optType[type].title === '修改跟进记录'
  369 + ? data.ticketsList || []
  370 + : [
  371 + {
  372 + type: '',
  373 + detailText: '',
  374 + assignPeople: '',
  375 + annexUrl: '',
  376 + },
  377 + ]
  378 + }
  379 + actionGuard={{
  380 + beforeRemoveRow: async () => {
  381 + return new Promise((resolve) => {
  382 + let list = form.getFieldValue('ticketsList');
  383 + if (list && list.length === 1) {
  384 + message.error('至少需要保留一个工单');
  385 + resolve(false);
  386 + return;
  387 + }
  388 + resolve(true);
  389 + });
  390 + },
  391 + }}
  392 + itemRender={(doms, listMeta) => {
  393 + if (optType[type].title === '修改跟进记录') {
  394 + // let i = 0;
  395 + // // let defaultFileList = data.ticketsList?.annexUrl?.map((annex) => {
  396 + // // return {
  397 + // // uid: i++,
  398 + // // name: annex,
  399 + // // status: 'uploaded',
  400 + // // url: annex,
  401 + // // response: { data: [annex] },
  402 + // // };
  403 + // // });
  404 + let defaultFileList = [
  405 + {
  406 + uid: listMeta.index,
  407 + name: data.ticketsList[listMeta.index]?.annexUrl,
  408 + status: 'uploaded',
  409 + url: data.ticketsList[listMeta.index]?.annexUrl,
  410 + response: {
  411 + data: [data.ticketsList[listMeta.index]?.annexUrl],
  412 + },
  413 + },
  414 + ];
  415 + fileList[listMeta.index] = defaultFileList;
  416 + }
  417 + let itemFileList = fileList[listMeta.index];
  418 + return (
  419 + <ProCard
  420 + bordered
  421 + extra={doms.action}
  422 + title={'工单指派' + (listMeta.index + 1)}
  423 + style={{
  424 + marginBlockEnd: 8,
  425 + }}
  426 + >
  427 + {[
  428 + <ProFormSelect
  429 + key={'type' + listMeta.index}
  430 + name="type"
  431 + label="工单类型"
  432 + width="sm"
  433 + placeholder="请输入工单类型"
  434 + readonly={optType[type].readOnly}
  435 + fieldProps={{
  436 + labelInValue: false,
  437 + }}
  438 + // initialValue={data?.ticketsList?.type ? data?.ticketsList?.type + '' : null}
  439 + initialValue={
  440 + data?.ticketsList ? data?.ticketsList?.type + '' : null
  441 + }
  442 + request={async () => {
  443 + return [
  444 + { label: '问题', value: 'QUESTION' },
  445 + { label: '需求', value: 'DEMAND' },
  446 + { label: '建议', value: 'ADVICE' },
  447 + ];
  448 + }}
  449 + />,
  450 + <ProFormTextArea
  451 + key={'detailText' + listMeta.index}
  452 + name="detailText"
  453 + label="工单详情"
  454 + placeholder="请输入工单详情"
  455 + initialValue={data?.detailText ? data?.detailText + '' : null}
  456 + readonly={optType[type].readOnly}
  457 + ></ProFormTextArea>,
  458 + <ProFormSelect
  459 + key={'assignPeople' + listMeta.index}
  460 + name="assignPeople"
  461 + width="sm"
  462 + readonly={optType[type].readOnly}
  463 + fieldProps={{
  464 + labelInValue: false,
  465 + }}
  466 + initialValue={
  467 + data?.assignPeople ? data?.assignPeople + '' : null
  468 + }
  469 + label="指派人员"
  470 + request={async () => {
  471 + const res = await postOrderErpUsersListByPage({
  472 + data: {
  473 + pageSize: 10000,
  474 + },
  475 + });
  476 +
  477 + const userOptions = res.data.records
  478 + ? res.data.records.map((user) => ({
  479 + label: user.userName, // 或者使用其他需要的属性
  480 + value: user.userName, // 作为value的字段
  481 + }))
  482 + : [];
  483 + return userOptions;
  484 + }}
  485 + ></ProFormSelect>,
  486 + <>
  487 + <ProFormUploadDragger
  488 + key={'filePaths' + listMeta.index}
  489 + label="附件"
  490 + name="filePaths"
  491 + action="/api/service/order/fileProcess"
  492 + fieldProps={{
  493 + headers: {
  494 + Authorization: localStorage.getItem('token'),
  495 + },
  496 + // headers: {
  497 + // 'Content-Type':
  498 + // 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  499 + // },
  500 + itemFileList,
  501 + }}
  502 + max={1}
  503 + />
  504 + </>,
  505 + ]}
  506 + </ProCard>
  507 + );
  508 + }}
  509 + actionRef={actionRef}
  510 + ></ProFormList>
  511 + {/* <div className="styled-text">
319 512 <div className="vertical-line"></div>
320 513 <span className="text">工单指派</span>
321 514 </div>
... ... @@ -348,7 +541,7 @@ export default ({ data, type, reloadTable }) =&gt; {
348 541 }}
349 542 initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null}
350 543 readonly={optType[type].readOnly}
351   - ></ProFormTextArea>
  544 + ></ProFormTextArea> */}
352 545 {/* <ProFormUploadDragger
353 546 label="工单附件"
354 547 name="ticketsAttachment"
... ... @@ -377,7 +570,7 @@ export default ({ data, type, reloadTable }) =&gt; {
377 570 }}
378 571 max={1}
379 572 /> */}
380   - <Row>
  573 + {/* <Row>
381 574 <Col span={4}>附件:</Col>
382 575 <Col span={20}>
383 576 <UploadC
... ... @@ -416,7 +609,6 @@ export default ({ data, type, reloadTable }) =&gt; {
416 609 </Col>
417 610 </Row>
418 611 <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download>
419   - {/* <a href={data?.annexUrl} download> */}
420 612 下载附件
421 613 </a>
422 614 <ProFormSelect
... ... @@ -443,7 +635,7 @@ export default ({ data, type, reloadTable }) =&gt; {
443 635 : [];
444 636 return userOptions;
445 637 }}
446   - ></ProFormSelect>
  638 + ></ProFormSelect> */}
447 639 </ModalForm>
448 640 );
449 641 };
... ...
src/pages/Client/FollowRecord/Components/CommunicationHistoryModal.tsx
... ... @@ -15,23 +15,13 @@ export default ({ data, reloadTable }) =&gt; {
15 15 const [datetime, setDatetime] = useState(); // 跟进日期
16 16 const [createByName, setCreateByName] = useState(''); // 跟进人员
17 17 const [clientName, setClientName] = useState(''); // 客户名称
18   - // const [clientAddress, setClientAddress] = useState(''); // 客户地址
19 18 const [way, setWay] = useState(); // 跟进方式
20 19 const [tradeStatusText, setTradeStatusText] = useState(); // 状态
21   - // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询
22   - // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询
23   - // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态
24   - // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询
25 20 const [content, setContent] = useState(''); // 跟进详情
26 21 const [createTime, setCreateTime] = useState(null); // 创建时间
27 22 const [attachments, setAttachments] = useState(); //附件
28 23 const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称
29   - const [ticketsType, setTicketsType] = useState(''); // 附件名称
30   - const [ticketsDetail, setTicketsDetail] = useState(''); // 附件名称
31   - const [ticketsAttachment, setTicketsAttachment] = useState(); // 附件名称
32   - // const [ticketsAttachmentName, setTicketsAttachmentName] = useState(''); // 附件名称
33 24 const [comment, setComment] = useState(''); // 客户评价
34   - const [assignPeople, setAssignPeople] = useState(''); // 附件名称
35 25 useEffect(() => {
36 26 const request = async () => {
37 27 const res = await postAdminClientQueryClientComunicationInfo({
... ... @@ -81,10 +71,6 @@ export default ({ data, reloadTable }) =&gt; {
81 71 // }
82 72 // }
83 73 setComment(dataSearch.comment);
84   - setTicketsType(dataSearch.ticketsTypeText);
85   - setTicketsDetail(dataSearch.ticketsDetail);
86   - setTicketsAttachment(dataSearch.ticketsAttachments);
87   - setAssignPeople(dataSearch.assignPeople);
88 74 setComment(dataSearch.comment);
89 75 setDatetime(dataSearch.datetime); // 设置跟进日期
90 76 // setDateRange(data.dateRange || []); // 设置跟进时间范围
... ... @@ -141,29 +127,24 @@ export default ({ data, reloadTable }) =&gt; {
141 127 },
142 128 {
143 129 key: '8',
144   - label: '工单类型',
145   - children: ticketsType, // 跟进状态
146   - },
147   - {
148   - key: '9',
149   - label: '工单详情',
150   - children: ticketsDetail, // 跟进状态
151   - },
152   - // {
153   - // key: '12',
154   - // label: '工单附件',
155   - // children: ticketsAttachment, // 跟进状态
156   - // },
157   - {
158   - key: '10',
159   - label: '指派人员',
160   - children: assignPeople, // 跟进状态
161   - },
162   - {
163   - key: '11',
164 130 label: '客户评价',
165 131 children: comment, // 跟进状态
166 132 },
  133 + // {
  134 + // key: '9',
  135 + // label: '工单类型',
  136 + // children: ticketsType, // 跟进状态
  137 + // },
  138 + // {
  139 + // key: '10',
  140 + // label: '工单详情',
  141 + // children: ticketsDetail, // 跟进状态
  142 + // },
  143 + // {
  144 + // key: '11',
  145 + // label: '指派人员',
  146 + // children: assignPeople, // 跟进状态
  147 + // },
167 148 ];
168 149 const handleDelete = async () => {
169 150 // 调用删除接口
... ... @@ -177,6 +158,40 @@ export default ({ data, reloadTable }) =&gt; {
177 158 actionRef?.current?.reload(); // 重新加载表格数据
178 159 }
179 160 };
  161 + const TicketDescriptions = ({ data }) => {
  162 + return (
  163 + <div>
  164 + {data.ticketsList && data.ticketsList.length > 0 ? (
  165 + data.ticketsList.map((ticket, index) => (
  166 + <div key={index} style={{ marginBottom: '20px' }}>
  167 + <Descriptions title={`工单 ${index + 1}`} column={1}>
  168 + <Descriptions.Item label="工单类型">
  169 + {ticket.typeText}
  170 + </Descriptions.Item>
  171 + <Descriptions.Item label="工单详情">
  172 + {ticket.detailText}
  173 + </Descriptions.Item>
  174 + <Descriptions.Item label="指派人员">
  175 + {ticket.assignPeople}
  176 + </Descriptions.Item>
  177 + </Descriptions>
  178 + {ticket.annexUrl && (
  179 + <a
  180 + href={ticket.annexUrl}
  181 + target="_blank"
  182 + rel="noopener noreferrer"
  183 + >
  184 + 下载工单附件
  185 + </a>
  186 + )}
  187 + </div>
  188 + ))
  189 + ) : (
  190 + <p></p>
  191 + )}
  192 + </div>
  193 + );
  194 + };
180 195 return (
181 196 <Space>
182 197 <ModalForm
... ... @@ -241,17 +256,6 @@ export default ({ data, reloadTable }) =&gt; {
241 256 }}
242 257 >
243 258 <Descriptions items={items} column={1} />
244   - {/* {attachmentsName && (
245   - <a href={attachments} download>
246   - 附件:{attachmentsName}
247   - </a>
248   - )}
249   - <div></div>
250   - {ticketsAttachment && (
251   - <a href={ticketsAttachment} download>
252   - 工单附件:{ticketsAttachment}
253   - </a>
254   - )} */}
255 259 {attachmentsName && (
256 260 <div>
257 261 {attachmentsName.endsWith('.png') ||
... ... @@ -274,6 +278,18 @@ export default ({ data, reloadTable }) =&gt; {
274 278 )}
275 279 </div>
276 280 )}
  281 + <TicketDescriptions data={data} />
  282 + {/* {attachmentsName && (
  283 + <a href={attachments} download>
  284 + 附件:{attachmentsName}
  285 + </a>
  286 + )}
  287 + <div></div>
  288 + {ticketsAttachment && (
  289 + <a href={ticketsAttachment} download>
  290 + 工单附件:{ticketsAttachment}
  291 + </a>
  292 + )} */}
277 293  
278 294 <div></div>
279 295 {/* {ticketsAttachment && (
... ... @@ -303,28 +319,6 @@ export default ({ data, reloadTable }) =&gt; {
303 319 )}
304 320 </div>
305 321 )} */}
306   - {ticketsAttachment && (
307   - <div>
308   - {ticketsAttachment.split(',').map((ticketsAttachment, index) => (
309   - <div key={index}>
310   - {ticketsAttachment.includes('jpg') ||
311   - ticketsAttachment.includes('png') ? (
312   - <>
313   - <img
314   - src={ticketsAttachment}
315   - alt={`附件 ${index + 1}`}
316   - style={{ maxWidth: '300px', height: 'auto' }}
317   - />
318   - <div></div>
319   - </>
320   - ) : null}
321   - <a href={ticketsAttachment} download>
322   - 工单附件:{ticketsAttachment}
323   - </a>
324   - </div>
325   - ))}
326   - </div>
327   - )}
328 322 </ModalForm>
329 323 </Space>
330 324 );
... ...
src/pages/Client/FollowRecord/index.tsx
... ... @@ -246,7 +246,6 @@ export default () =&gt; {
246 246 data={record}
247 247 // reloadTable={() => {
248 248 // actionRef.current.reload();
249   - // console.log('5656flush');
250 249 // }}
251 250 reloadTable={reload}
252 251 />,
... ...
src/pages/Order/OrderWarning/components/FeedbackRegistrationModal.tsx
... ... @@ -7,9 +7,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
7 7 const [isModalOpen] = useState(true);
8 8 const { TextArea } = Input;
9 9 const [textValue, setTextValue] = useState('');
  10 + console.log(mainOrder);
10 11  
11 12 const handleOk = async () => {
12   - console.log(subOrders, '', mainOrder);
13 13 await postServiceOrderFeedbackRegistration({
14 14 data: {
15 15 id: subOrders[0].id,
... ...