Commit e5743afc96a6448f0e47f71a35885f1b82aaf177
Merge branch 'clientBy'
Showing
13 changed files
with
1697 additions
and
263 deletions
src/pages/Client/Client/Components/ClientDrawer.tsx
... | ... | @@ -5,15 +5,14 @@ import { |
5 | 5 | postDistrictSelectByLevel, |
6 | 6 | postDistrictSelectByNameAndLevel, |
7 | 7 | postDistrictSelOrderProvince, |
8 | + postResearchGroupsNameSet, | |
8 | 9 | postServiceConstClientLevels, |
9 | 10 | postServiceConstClientSource, |
10 | - postServiceConstTradeStatus, | |
11 | 11 | } from '@/services'; |
12 | 12 | |
13 | 13 | import { enumToSelect } from '@/utils'; |
14 | 14 | import { |
15 | 15 | DrawerForm, |
16 | - ProFormDatePicker, | |
17 | 16 | ProFormSelect, |
18 | 17 | ProFormText, |
19 | 18 | } from '@ant-design/pro-components'; |
... | ... | @@ -23,17 +22,10 @@ import { useState } from 'react'; |
23 | 22 | |
24 | 23 | export default ({ optType, record, onFinish }) => { |
25 | 24 | const [form] = Form.useForm(); |
26 | - const requirementsEnum = { | |
27 | - EXPERIMENTAL_EQUIPMENT: '实验设备', | |
28 | - EXPERIMENTAL_MATERIALS: '实验材料', | |
29 | - OTHER: '其他', | |
30 | - PILOT_TEST_VALIDATION_SERVICES: '中式验证服务', | |
31 | - }; | |
32 | 25 | //省市区 |
33 | 26 | const [province, setProvince] = useState(''); |
34 | 27 | const [city, setCity] = useState(''); |
35 | 28 | const [showReferrers, setShowReferrers] = useState(false); // 控制显示的状态,初始为false |
36 | - const [showQuoteDatetime, setShowQuoteDatetime] = useState(false); // 控制显示的状态,初始为false | |
37 | 29 | const optTypeEnum = { |
38 | 30 | add: { |
39 | 31 | text: '新增', |
... | ... | @@ -82,15 +74,6 @@ export default ({ optType, record, onFinish }) => { |
82 | 74 | } |
83 | 75 | // 在这里可以添加其他逻辑,比如根据选择更新其他表单项的值 |
84 | 76 | }; |
85 | - const handleSchemeChange = (value) => { | |
86 | - console.log(value); | |
87 | - if (value === true) { | |
88 | - setShowQuoteDatetime(true); | |
89 | - } else { | |
90 | - setShowQuoteDatetime(false); | |
91 | - } | |
92 | - // 在这里可以添加其他逻辑,比如根据选择更新其他表单项的值 | |
93 | - }; | |
94 | 77 | |
95 | 78 | // MODIFIED: 增加处理非 JSON 格式字符串的逻辑 |
96 | 79 | const parsedRecord = record |
... | ... | @@ -314,13 +297,13 @@ export default ({ optType, record, onFinish }) => { |
314 | 297 | ]} |
315 | 298 | /> |
316 | 299 | <ProFormText |
317 | - name="contacts" | |
318 | - label="联系人" | |
319 | - placeholder="请输入联系人" | |
300 | + name="leaderName" | |
301 | + label="负责人" | |
302 | + placeholder="请输入负责人" | |
320 | 303 | rules={[ |
321 | 304 | { |
322 | 305 | required: true, |
323 | - message: '请输入联系人', | |
306 | + message: '请输入负责人', | |
324 | 307 | }, |
325 | 308 | ]} |
326 | 309 | /> |
... | ... | @@ -336,6 +319,60 @@ export default ({ optType, record, onFinish }) => { |
336 | 319 | ]} |
337 | 320 | /> |
338 | 321 | <ProFormSelect |
322 | + key={'institutionContactName'} | |
323 | + width="md" | |
324 | + showSearch | |
325 | + name="institutionContactName" | |
326 | + rules={[{ required: true, message: '请输入课题组名称!' }]} | |
327 | + request={async (value) => { | |
328 | + const keywords = value.keyWords; | |
329 | + const res = await postResearchGroupsNameSet({ | |
330 | + data: { | |
331 | + status: 'ADD_AUDIT_PASS', | |
332 | + groupName: keywords, | |
333 | + }, | |
334 | + }); | |
335 | + let options = res?.data?.map((c: any) => { | |
336 | + return { | |
337 | + label: c, | |
338 | + value: c, | |
339 | + key: c, | |
340 | + }; | |
341 | + }); | |
342 | + return options; | |
343 | + }} | |
344 | + fieldProps={{ | |
345 | + filterOption() { | |
346 | + return true; | |
347 | + }, | |
348 | + }} | |
349 | + debounceTime={1000} | |
350 | + label="课题组名称" | |
351 | + placeholder="请输入名称" | |
352 | + /> | |
353 | + <ProFormText | |
354 | + name="department" | |
355 | + label="部门" | |
356 | + placeholder="请输入部门" | |
357 | + rules={[ | |
358 | + { | |
359 | + required: false, | |
360 | + message: '请输入部门', | |
361 | + }, | |
362 | + ]} | |
363 | + /> | |
364 | + <ProFormText | |
365 | + name="gradePosition" | |
366 | + label="年级/职位" | |
367 | + placeholder="请输入年级/职位" | |
368 | + rules={[ | |
369 | + { | |
370 | + required: false, | |
371 | + message: '请输入年级/职位', | |
372 | + }, | |
373 | + ]} | |
374 | + /> | |
375 | + <ProFormSelect | |
339 | 376 | name="source" |
340 | 377 | label="客户来源" |
341 | 378 | placeholder="请选择客户来源" |
... | ... | @@ -360,7 +397,7 @@ export default ({ optType, record, onFinish }) => { |
360 | 397 | placeholder="请输入推荐人" |
361 | 398 | /> |
362 | 399 | )} |
363 | - <ProFormSelect | |
400 | + {/* <ProFormSelect | |
364 | 401 | name="requirements" |
365 | 402 | label="客户需求" |
366 | 403 | placeholder="请输入客户需求" |
... | ... | @@ -380,38 +417,7 @@ export default ({ optType, record, onFinish }) => { |
380 | 417 | // console.log(res.data, '5656require'); |
381 | 418 | // return enumToSelect(res.data); |
382 | 419 | // }} |
383 | - /> | |
384 | - <ProFormSelect | |
385 | - name="hasScheme" | |
386 | - label="是否已报方案" | |
387 | - placeholder="请选择是否已报方案" | |
388 | - options={[ | |
389 | - { | |
390 | - label: '是', | |
391 | - value: true, | |
392 | - }, | |
393 | - { | |
394 | - label: '否', | |
395 | - value: false, | |
396 | - }, | |
397 | - ]} | |
398 | - rules={[ | |
399 | - { | |
400 | - required: true, | |
401 | - message: '请选择是否已报方案', | |
402 | - }, | |
403 | - ]} | |
404 | - fieldProps={{ | |
405 | - onChange: handleSchemeChange, // 添加onChange事件处理函数 | |
406 | - }} | |
407 | - /> | |
408 | - {showQuoteDatetime && ( | |
409 | - <ProFormDatePicker | |
410 | - name="quoteDatetime" | |
411 | - label="报价时间" | |
412 | - placeholder="请输入报价时间" | |
413 | - /> | |
414 | - )} | |
420 | + /> */} | |
415 | 421 | <ProFormSelect |
416 | 422 | name="level" |
417 | 423 | label="客户等级" |
... | ... | @@ -437,21 +443,6 @@ export default ({ optType, record, onFinish }) => { |
437 | 443 | return enumToSelectLevel(res.data); |
438 | 444 | }} |
439 | 445 | /> |
440 | - <ProFormSelect | |
441 | - name="tradeStatus" | |
442 | - label="跟进状态" | |
443 | - placeholder="请输入跟进状态" | |
444 | - rules={[ | |
445 | - { | |
446 | - required: true, | |
447 | - message: '请输入跟进状态', | |
448 | - }, | |
449 | - ]} | |
450 | - request={async () => { | |
451 | - const res = await postServiceConstTradeStatus(); | |
452 | - return enumToSelect(res.data); | |
453 | - }} | |
454 | - /> | |
455 | 446 | <ProFormText name="notes" label="备注" placeholder="请输入备注" /> |
456 | 447 | </DrawerForm> |
457 | 448 | ); | ... | ... |
src/pages/Client/Client/Components/ClientInformationModal.tsx
1 | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | |
2 | 3 | import { |
3 | 4 | postAdminClientAddOrModifyClientComunicationInfo, |
4 | 5 | postAdminClientQueryClientPage, |
5 | 6 | postOrderErpOrderStagesUpload, |
7 | + postOrderErpUsersListByPage, | |
6 | 8 | postServiceConstClientWay, |
9 | + postServiceConstTradeStatus, | |
7 | 10 | } from '@/services'; |
8 | 11 | import { enumToSelect } from '@/utils'; |
9 | 12 | import { |
... | ... | @@ -14,8 +17,9 @@ import { |
14 | 17 | ProFormTextArea, |
15 | 18 | ProFormUploadDragger, |
16 | 19 | } from '@ant-design/pro-components'; |
17 | -import { Button, Form, message } from 'antd'; | |
20 | +import { Button, Col, Form, Row, message } from 'antd'; | |
18 | 21 | import { RcFile } from 'antd/es/upload'; |
22 | +import './style.css'; | |
19 | 23 | export default ({ data, type, reloadTable }) => { |
20 | 24 | const [form] = Form.useForm(); |
21 | 25 | const onfinish = async (values) => { |
... | ... | @@ -64,6 +68,12 @@ export default ({ data, type, reloadTable }) => { |
64 | 68 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
65 | 69 | data: { |
66 | 70 | ...values, |
71 | + // ticketsAttachments: form.getFieldValue("ticketsAttachments"), | |
72 | + ticketsAttachments: | |
73 | + form.getFieldValue('ticketsAttachments') !== undefined | |
74 | + ? form.getFieldValue('ticketsAttachments') | |
75 | + : data?.ticketsAttachments, | |
76 | + // ticketsAttachments: data?.annexUrl, | |
67 | 77 | }, |
68 | 78 | }); |
69 | 79 | if (res.result === RESPONSE_CODE.SUCCESS) { |
... | ... | @@ -165,9 +175,37 @@ export default ({ data, type, reloadTable }) => { |
165 | 175 | }, |
166 | 176 | ]} |
167 | 177 | ></ProFormSelect> |
178 | + <ProFormText | |
179 | + name="contact" | |
180 | + label="联系人" | |
181 | + width="sm" | |
182 | + placeholder="请输入联系人" | |
183 | + initialValue={data?.content} | |
184 | + readonly={optType[type].readOnly} | |
185 | + rules={[ | |
186 | + { | |
187 | + required: true, | |
188 | + message: '请输入联系人', | |
189 | + }, | |
190 | + ]} | |
191 | + ></ProFormText> | |
192 | + <ProFormText | |
193 | + name="contactPhone" | |
194 | + label="联系电话" | |
195 | + width="sm" | |
196 | + placeholder="请输入联系电话" | |
197 | + initialValue={data?.content} | |
198 | + readonly={optType[type].readOnly} | |
199 | + rules={[ | |
200 | + { | |
201 | + required: true, | |
202 | + message: '请输入联系电话', | |
203 | + }, | |
204 | + ]} | |
205 | + ></ProFormText> | |
168 | 206 | <ProFormDateTimePicker |
169 | 207 | name="datetime" |
170 | - label="日期" | |
208 | + label="跟进日期" | |
171 | 209 | initialValue={data ? data?.datetime + '' : null} |
172 | 210 | placeholder="请选择跟进时间" |
173 | 211 | width="sm" |
... | ... | @@ -179,6 +217,27 @@ export default ({ data, type, reloadTable }) => { |
179 | 217 | ]} |
180 | 218 | /> |
181 | 219 | <ProFormSelect |
220 | + name="tradeStatus" | |
221 | + label="跟进状态" | |
222 | + width="sm" | |
223 | + placeholder="请输入跟进状态" | |
224 | + readonly={optType[type].readOnly} | |
225 | + fieldProps={{ | |
226 | + labelInValue: false, | |
227 | + }} | |
228 | + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null} | |
229 | + rules={[ | |
230 | + { | |
231 | + required: true, | |
232 | + message: '请输入跟进状态', | |
233 | + }, | |
234 | + ]} | |
235 | + request={async () => { | |
236 | + const res = await postServiceConstTradeStatus(); | |
237 | + return enumToSelect(res.data); | |
238 | + }} | |
239 | + /> | |
240 | + <ProFormSelect | |
182 | 241 | name="way" |
183 | 242 | width="sm" |
184 | 243 | readonly={optType[type].readOnly} |
... | ... | @@ -186,7 +245,7 @@ export default ({ data, type, reloadTable }) => { |
186 | 245 | labelInValue: false, |
187 | 246 | }} |
188 | 247 | initialValue={data?.way ? data?.way + '' : null} |
189 | - label="类型" | |
248 | + label="跟进方式" | |
190 | 249 | request={async () => { |
191 | 250 | const res = await postServiceConstClientWay(); |
192 | 251 | return enumToSelect(res.data); |
... | ... | @@ -194,7 +253,7 @@ export default ({ data, type, reloadTable }) => { |
194 | 253 | rules={[ |
195 | 254 | { |
196 | 255 | required: true, |
197 | - message: '请选择跟进类型', | |
256 | + message: '请选择跟进方式', | |
198 | 257 | }, |
199 | 258 | ]} |
200 | 259 | ></ProFormSelect> |
... | ... | @@ -242,12 +301,138 @@ export default ({ data, type, reloadTable }) => { |
242 | 301 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> |
243 | 302 | 下载附件 |
244 | 303 | </a> |
304 | + <ProFormTextArea | |
305 | + name="comment" | |
306 | + label="客户评价" | |
307 | + placeholder="请输入客户评价" | |
308 | + initialValue={data?.comment} | |
309 | + readonly={optType[type].readOnly} | |
310 | + ></ProFormTextArea> | |
245 | 311 | <ProFormText |
246 | 312 | initialValue={data?.attachments} |
247 | 313 | name="attachments" |
248 | 314 | hidden |
249 | 315 | ></ProFormText> |
250 | 316 | <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> |
317 | + <div className="styled-text"> | |
318 | + <div className="vertical-line"></div> | |
319 | + <span className="text">工单指派</span> | |
320 | + </div> | |
321 | + <ProFormSelect | |
322 | + name="ticketsType" | |
323 | + label="工单类型" | |
324 | + width="sm" | |
325 | + placeholder="请输入工单类型" | |
326 | + readonly={optType[type].readOnly} | |
327 | + fieldProps={{ | |
328 | + labelInValue: false, | |
329 | + }} | |
330 | + initialValue={data?.ticketsType ? data?.ticketsType + '' : null} | |
331 | + request={async () => { | |
332 | + return [ | |
333 | + { label: '问题', value: 'QUESTION' }, | |
334 | + { label: '需求', value: 'DEMAND' }, | |
335 | + { label: '建议', value: 'ADVICE' }, | |
336 | + ]; | |
337 | + }} | |
338 | + /> | |
339 | + <ProFormTextArea | |
340 | + name="ticketsDetail" | |
341 | + label="工单详情" | |
342 | + placeholder="请输入工单详情" | |
343 | + initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null} | |
344 | + readonly={optType[type].readOnly} | |
345 | + ></ProFormTextArea> | |
346 | + {/* <ProFormUploadDragger | |
347 | + label="工单附件" | |
348 | + name="ticketsAttachment" | |
349 | + action="upload.do" | |
350 | + hidden={optType[type].readOnly} | |
351 | + onChange={(info) => { | |
352 | + const uploadFile = async ({ fileList: newFileList }) => { | |
353 | + if (newFileList.length > 0) { | |
354 | + const formData = new FormData(); | |
355 | + formData.append('file', newFileList[0].originFileObj as RcFile); | |
356 | + const res = await postOrderErpOrderStagesUpload({ | |
357 | + data: formData, | |
358 | + headers: { | |
359 | + 'Content-Type': | |
360 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
361 | + }, | |
362 | + }); | |
363 | + const url = res.data; | |
364 | + console.log('ticketsAttachments' + JSON.stringify(url)); | |
365 | + form.setFieldValue('ticketsAttachments', url); | |
366 | + } else { | |
367 | + form.setFieldValue('ticketsAttachments', null); | |
368 | + } | |
369 | + }; | |
370 | + uploadFile(info); | |
371 | + }} | |
372 | + max={1} | |
373 | + /> */} | |
374 | + <Row> | |
375 | + <Col span={4}>附件:</Col> | |
376 | + <Col span={20}> | |
377 | + <UploadC | |
378 | + onFilesChange={async (newFileList) => { | |
379 | + if (newFileList.length > 0) { | |
380 | + const urls = []; // 创建一个数组来存储所有的 URL | |
381 | + | |
382 | + for (const file of newFileList) { | |
383 | + const formData = new FormData(); | |
384 | + formData.append('file', file.originFileObj as RcFile); | |
385 | + | |
386 | + const res = await postOrderErpOrderStagesUpload({ | |
387 | + data: formData, | |
388 | + headers: { | |
389 | + 'Content-Type': | |
390 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
391 | + }, | |
392 | + }); | |
393 | + | |
394 | + const url = res.data; // 获取响应中的 URL | |
395 | + urls.push(url); // 将每个 URL 追加到数组中 | |
396 | + } | |
397 | + | |
398 | + // 将所有 URL 使用 ',' 进行拼接 | |
399 | + const combinedUrl = urls.join(','); | |
400 | + form.setFieldValue('ticketsAttachments', combinedUrl); // 设置表单字段值为拼接后的 URL | |
401 | + } else { | |
402 | + form.setFieldValue('ticketsAttachments', null); // 如果没有文件,则清空 URL | |
403 | + } | |
404 | + }} | |
405 | + ></UploadC> | |
406 | + </Col> | |
407 | + </Row> | |
408 | + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download> | |
409 | + 下载附件 | |
410 | + </a> | |
411 | + <ProFormSelect | |
412 | + name="assignPeople" | |
413 | + width="sm" | |
414 | + readonly={optType[type].readOnly} | |
415 | + fieldProps={{ | |
416 | + labelInValue: false, | |
417 | + }} | |
418 | + initialValue={data?.assignPeople ? data?.assignPeople + '' : null} | |
419 | + label="指派人员" | |
420 | + request={async () => { | |
421 | + const res = await postOrderErpUsersListByPage({ | |
422 | + data: { | |
423 | + pageSize: 10000, | |
424 | + }, | |
425 | + }); | |
426 | + | |
427 | + const userOptions = res.data.records | |
428 | + ? res.data.records.map((user) => ({ | |
429 | + label: user.userName, // 或者使用其他需要的属性 | |
430 | + value: user.userName, // 作为value的字段 | |
431 | + })) | |
432 | + : []; | |
433 | + return userOptions; | |
434 | + }} | |
435 | + ></ProFormSelect> | |
251 | 436 | </ModalForm> |
252 | 437 | ); |
253 | 438 | }; | ... | ... |
src/pages/Client/Client/Components/ClientModal.tsx
1 | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | |
2 | 3 | import { |
3 | 4 | postAdminClientAddOrModifyClientComunicationInfo, |
4 | 5 | postAdminClientQueryClientPage, |
5 | 6 | postOrderErpOrderStagesUpload, |
7 | + postOrderErpUsersListByPage, | |
6 | 8 | postServiceConstClientWay, |
9 | + postServiceConstTradeStatus, | |
7 | 10 | } from '@/services'; |
8 | 11 | import { enumToSelect } from '@/utils'; |
9 | 12 | import { |
... | ... | @@ -14,13 +17,12 @@ import { |
14 | 17 | ProFormTextArea, |
15 | 18 | ProFormUploadDragger, |
16 | 19 | } from '@ant-design/pro-components'; |
17 | -import { Button, Form, message } from 'antd'; | |
20 | +import { Button, Col, Form, Row, message } from 'antd'; | |
18 | 21 | import { RcFile } from 'antd/es/upload'; |
22 | +import './style.css'; | |
19 | 23 | export default ({ data, type, reloadTable }) => { |
20 | 24 | const [form] = Form.useForm(); |
21 | 25 | const onfinish = async (values) => { |
22 | - console.log(data, '5656datatest'); | |
23 | - console.log(values, '5656...values'); | |
24 | 26 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
25 | 27 | data: { |
26 | 28 | ...values, |
... | ... | @@ -111,7 +113,6 @@ export default ({ data, type, reloadTable }) => { |
111 | 113 | groupFilter: 'all', |
112 | 114 | }, |
113 | 115 | }); |
114 | - console.log(data?.datetime, '5656data?.datetime'); | |
115 | 116 | const namesArray = res.data.data.map((item) => item.name); |
116 | 117 | return enumToSelect(namesArray); |
117 | 118 | }} |
... | ... | @@ -123,9 +124,37 @@ export default ({ data, type, reloadTable }) => { |
123 | 124 | ]} |
124 | 125 | disabled |
125 | 126 | ></ProFormSelect> |
127 | + <ProFormText | |
128 | + name="contact" | |
129 | + label="联系人" | |
130 | + width="sm" | |
131 | + placeholder="请输入联系人" | |
132 | + initialValue={data?.content} | |
133 | + readonly={optType[type].readOnly} | |
134 | + rules={[ | |
135 | + { | |
136 | + required: true, | |
137 | + message: '请输入联系人', | |
138 | + }, | |
139 | + ]} | |
140 | + ></ProFormText> | |
141 | + <ProFormText | |
142 | + name="contactPhone" | |
143 | + label="联系电话" | |
144 | + width="sm" | |
145 | + placeholder="请输入联系电话" | |
146 | + initialValue={data?.content} | |
147 | + readonly={optType[type].readOnly} | |
148 | + rules={[ | |
149 | + { | |
150 | + required: true, | |
151 | + message: '请输入联系电话', | |
152 | + }, | |
153 | + ]} | |
154 | + ></ProFormText> | |
126 | 155 | <ProFormDateTimePicker |
127 | 156 | name="datetime" |
128 | - label="日期" | |
157 | + label="跟进日期" | |
129 | 158 | initialValue={data.datetime ? data?.datetime + '' : null} |
130 | 159 | placeholder="请选择跟进时间" |
131 | 160 | width="sm" |
... | ... | @@ -137,6 +166,27 @@ export default ({ data, type, reloadTable }) => { |
137 | 166 | ]} |
138 | 167 | /> |
139 | 168 | <ProFormSelect |
169 | + name="tradeStatus" | |
170 | + label="跟进状态" | |
171 | + width="sm" | |
172 | + placeholder="请输入跟进状态" | |
173 | + readonly={optType[type].readOnly} | |
174 | + fieldProps={{ | |
175 | + labelInValue: false, | |
176 | + }} | |
177 | + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null} | |
178 | + rules={[ | |
179 | + { | |
180 | + required: true, | |
181 | + message: '请输入跟进状态', | |
182 | + }, | |
183 | + ]} | |
184 | + request={async () => { | |
185 | + const res = await postServiceConstTradeStatus(); | |
186 | + return enumToSelect(res.data); | |
187 | + }} | |
188 | + /> | |
189 | + <ProFormSelect | |
140 | 190 | name="way" |
141 | 191 | width="sm" |
142 | 192 | readonly={optType[type].readOnly} |
... | ... | @@ -200,12 +250,138 @@ export default ({ data, type, reloadTable }) => { |
200 | 250 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> |
201 | 251 | 下载附件 |
202 | 252 | </a> |
253 | + <ProFormTextArea | |
254 | + name="comment" | |
255 | + label="客户评价" | |
256 | + placeholder="请输入客户评价" | |
257 | + initialValue={data?.comment} | |
258 | + readonly={optType[type].readOnly} | |
259 | + ></ProFormTextArea> | |
203 | 260 | <ProFormText |
204 | 261 | initialValue={data?.attachments} |
205 | 262 | name="attachments" |
206 | 263 | hidden |
207 | 264 | ></ProFormText> |
208 | 265 | <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> |
266 | + <div className="styled-text"> | |
267 | + <div className="vertical-line"></div> | |
268 | + <span className="text">工单指派</span> | |
269 | + </div> | |
270 | + <ProFormSelect | |
271 | + name="ticketsType" | |
272 | + label="工单类型" | |
273 | + width="sm" | |
274 | + placeholder="请输入工单类型" | |
275 | + readonly={optType[type].readOnly} | |
276 | + fieldProps={{ | |
277 | + labelInValue: false, | |
278 | + }} | |
279 | + initialValue={data?.type ? data?.type + '' : null} | |
280 | + request={async () => { | |
281 | + return [ | |
282 | + { label: '问题', value: 'QUESTION' }, | |
283 | + { label: '需求', value: 'DEMAND' }, | |
284 | + { label: '建议', value: 'ADVICE' }, | |
285 | + ]; | |
286 | + }} | |
287 | + /> | |
288 | + <ProFormTextArea | |
289 | + name="ticketsDetail" | |
290 | + label="工单详情" | |
291 | + placeholder="请输入工单详情" | |
292 | + initialValue={data?.detailText ? data?.detailText + '' : null} | |
293 | + readonly={optType[type].readOnly} | |
294 | + ></ProFormTextArea> | |
295 | + <Row> | |
296 | + <Col span={4}>附件:</Col> | |
297 | + <Col span={20}> | |
298 | + <UploadC | |
299 | + onFilesChange={async (newFileList) => { | |
300 | + if (newFileList.length > 0) { | |
301 | + const urls = []; // 创建一个数组来存储所有的 URL | |
302 | + | |
303 | + for (const file of newFileList) { | |
304 | + const formData = new FormData(); | |
305 | + formData.append('file', file.originFileObj as RcFile); | |
306 | + | |
307 | + const res = await postOrderErpOrderStagesUpload({ | |
308 | + data: formData, | |
309 | + headers: { | |
310 | + 'Content-Type': | |
311 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
312 | + }, | |
313 | + }); | |
314 | + | |
315 | + const url = res.data; // 获取响应中的 URL | |
316 | + urls.push(url); // 将每个 URL 追加到数组中 | |
317 | + } | |
318 | + | |
319 | + // 将所有 URL 使用 ',' 进行拼接 | |
320 | + const combinedUrl = urls.join(','); | |
321 | + form.setFieldValue('ticketsAttachments', combinedUrl); // 设置表单字段值为拼接后的 URL | |
322 | + } else { | |
323 | + form.setFieldValue('ticketsAttachments', null); // 如果没有文件,则清空 URL | |
324 | + } | |
325 | + }} | |
326 | + ></UploadC> | |
327 | + </Col> | |
328 | + </Row> | |
329 | + {/* <ProFormUploadDragger | |
330 | + label="工单附件" | |
331 | + name="ticketsAttachment" | |
332 | + action="upload.do" | |
333 | + hidden={optType[type].readOnly} | |
334 | + onChange={(info) => { | |
335 | + const uploadFile = async ({ fileList: newFileList }) => { | |
336 | + if (newFileList.length > 0) { | |
337 | + const formData = new FormData(); | |
338 | + formData.append('file', newFileList[0].originFileObj as RcFile); | |
339 | + const res = await postOrderErpOrderStagesUpload({ | |
340 | + data: formData, | |
341 | + headers: { | |
342 | + 'Content-Type': | |
343 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
344 | + }, | |
345 | + }); | |
346 | + const url = res.data; | |
347 | + console.log('ticketsAttachments' + JSON.stringify(url)); | |
348 | + form.setFieldValue('ticketsAttachments', url); | |
349 | + } else { | |
350 | + form.setFieldValue('ticketsAttachments', null); | |
351 | + } | |
352 | + }; | |
353 | + uploadFile(info); | |
354 | + }} | |
355 | + max={1} | |
356 | + /> */} | |
357 | + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download> | |
358 | + 下载附件 | |
359 | + </a> | |
360 | + <ProFormSelect | |
361 | + name="assignPeople" | |
362 | + width="sm" | |
363 | + readonly={optType[type].readOnly} | |
364 | + fieldProps={{ | |
365 | + labelInValue: false, | |
366 | + }} | |
367 | + initialValue={data?.assignPeople ? data?.assignPeople + '' : null} | |
368 | + label="指派人员" | |
369 | + request={async () => { | |
370 | + const res = await postOrderErpUsersListByPage({ | |
371 | + data: { | |
372 | + pageSize: 10000, | |
373 | + }, | |
374 | + }); | |
375 | + | |
376 | + const userOptions = res.data.records | |
377 | + ? res.data.records.map((user) => ({ | |
378 | + label: user.userName, // 或者使用其他需要的属性 | |
379 | + value: user.userName, // 作为value的字段 | |
380 | + })) | |
381 | + : []; | |
382 | + return userOptions; | |
383 | + }} | |
384 | + ></ProFormSelect> | |
209 | 385 | </ModalForm> |
210 | 386 | ); |
211 | 387 | }; | ... | ... |
src/pages/Client/Client/Components/CommunicationHistoryModal.tsx
... | ... | @@ -4,6 +4,7 @@ import { |
4 | 4 | postAdminClientQueryClientComunicationInfo, |
5 | 5 | postAdminClientRemoveClientComunicationInfo, |
6 | 6 | postServiceConstClientWay, |
7 | + postServiceConstTradeStatus, | |
7 | 8 | } from '@/services'; |
8 | 9 | import { enumToSelect } from '@/utils'; |
9 | 10 | import { |
... | ... | @@ -25,7 +26,6 @@ export default ({ record }) => { |
25 | 26 | |
26 | 27 | const reloadInformationHistoryModal = () => { |
27 | 28 | actionRef.current.reload(); // 重新加载数据 |
28 | - console.log('5656flush'); | |
29 | 29 | |
30 | 30 | // 更新 refreshKey,强制刷新 CommunicationHistoryModal |
31 | 31 | setRefreshKey((prevKey) => prevKey + 1); |
... | ... | @@ -56,8 +56,19 @@ export default ({ record }) => { |
56 | 56 | }, |
57 | 57 | }, |
58 | 58 | { |
59 | - title: '内容', | |
60 | - width: 100, | |
59 | + title: '跟进状态', | |
60 | + width: 50, | |
61 | + dataIndex: 'tradeStatus', | |
62 | + rules: [{ required: true, message: '请选择方式' }], | |
63 | + render: (text, record) => record.tradeStatusLike, // 显示 wayText | |
64 | + request: async () => { | |
65 | + const res = await postServiceConstTradeStatus(); | |
66 | + return enumToSelect(res.data); | |
67 | + }, | |
68 | + }, | |
69 | + { | |
70 | + title: '跟进详情', | |
71 | + width: 80, | |
61 | 72 | valueType: 'textarea', |
62 | 73 | rules: [{ required: true, message: '请输入内容' }], |
63 | 74 | dataIndex: 'content', |
... | ... | @@ -65,7 +76,7 @@ export default ({ record }) => { |
65 | 76 | { |
66 | 77 | title: '操作', |
67 | 78 | valueType: 'option', |
68 | - width: 50, | |
79 | + width: 60, | |
69 | 80 | render: (text, record, _, action) => [ |
70 | 81 | // <a |
71 | 82 | // key="editable" |
... | ... | @@ -112,14 +123,13 @@ export default ({ record }) => { |
112 | 123 | }, |
113 | 124 | ]; |
114 | 125 | const [name, setName] = useState(''); // 客户名称 |
115 | - const [contacts, setContacts] = useState(''); // 联系人 | |
126 | + const [leaderName, setLeaderName] = useState(''); // 负责人 | |
116 | 127 | const [sourceText, setSourceText] = useState(''); // 来源文本 |
117 | 128 | const [phoneNumber, setPhoneNumber] = useState(''); // 联系电话 |
118 | - const [hasSchemeText, setHasSchemeText] = useState(''); // 报方案状态文本 | |
119 | - const [quoteDatetime, setQuoteDatetime] = useState(null); // 报价时间 | |
129 | + const [institutionContactName, setInstitutionContactName] = useState(''); // 联系电话 | |
130 | + const [department, setDepartment] = useState(''); // 联系电话 | |
131 | + const [gradePosition, setGradePosition] = useState(''); // 联系电话 | |
120 | 132 | const [referrers, setReferrers] = useState(''); // 推荐人 |
121 | - const [requirementsText, setRequirementsText] = useState(''); // 需求文本 | |
122 | - const [tradeStatusText, setTradeStatusText] = useState(''); // 跟进状态文本 | |
123 | 133 | const [levelText, setLevelText] = useState(''); // 客户等级文本 |
124 | 134 | const [createTime, setCreateTime] = useState(null); // 最新沟通时间 |
125 | 135 | const [address, setAddress] = useState(''); // 客户地址 |
... | ... | @@ -152,14 +162,13 @@ export default ({ record }) => { |
152 | 162 | } |
153 | 163 | setRecordSave(record); |
154 | 164 | setName(record.name); |
155 | - setContacts(record.contacts); | |
165 | + setLeaderName(record.leaderName); | |
156 | 166 | setSourceText(record.sourceText); |
157 | 167 | setPhoneNumber(record.phoneNumber); |
158 | - setHasSchemeText(record.hasSchemeText); | |
159 | - setQuoteDatetime(record.quoteDatetime); | |
168 | + setInstitutionContactName(record.institutionContactName); | |
169 | + setDepartment(record.department); | |
170 | + setGradePosition(record.gradePosition); | |
160 | 171 | setReferrers(record.referrers); |
161 | - setRequirementsText(record.requirementsText); | |
162 | - setTradeStatusText(record.tradeStatusText); | |
163 | 172 | setLevelText(record.levelText); |
164 | 173 | setCreateTime(record.createTime); |
165 | 174 | setAddress(record.address); |
... | ... | @@ -176,8 +185,8 @@ export default ({ record }) => { |
176 | 185 | }, |
177 | 186 | { |
178 | 187 | key: '2', |
179 | - label: '联系人', | |
180 | - children: contacts, // 联系人 | |
188 | + label: '负责人', | |
189 | + children: leaderName, // 负责人 | |
181 | 190 | }, |
182 | 191 | { |
183 | 192 | key: '3', |
... | ... | @@ -191,28 +200,23 @@ export default ({ record }) => { |
191 | 200 | }, |
192 | 201 | { |
193 | 202 | key: '5', |
194 | - label: '是否已报方案', | |
195 | - children: hasSchemeText, // 报方案状态文本 | |
203 | + label: '课题组', | |
204 | + children: institutionContactName, // 推荐人 | |
196 | 205 | }, |
197 | 206 | { |
198 | 207 | key: '6', |
199 | - label: '报价时间', | |
200 | - children: quoteDatetime, // 报价时间 | |
208 | + label: '部门', | |
209 | + children: department, // 推荐人 | |
201 | 210 | }, |
202 | 211 | { |
203 | 212 | key: '7', |
204 | - label: '推荐人', | |
205 | - children: referrers, // 推荐人 | |
213 | + label: '年级/职位', | |
214 | + children: gradePosition, // 推荐人 | |
206 | 215 | }, |
207 | 216 | { |
208 | 217 | key: '8', |
209 | - label: '需求', | |
210 | - children: requirementsText, // 需求文本 | |
211 | - }, | |
212 | - { | |
213 | - key: '9', | |
214 | - label: '跟进状态', | |
215 | - children: tradeStatusText, // 跟进状态文本 | |
218 | + label: '推荐人', | |
219 | + children: referrers, // 推荐人 | |
216 | 220 | }, |
217 | 221 | { |
218 | 222 | key: '10', |
... | ... | @@ -265,7 +269,6 @@ export default ({ record }) => { |
265 | 269 | }} |
266 | 270 | type={'add2'} |
267 | 271 | /> |
268 | - , | |
269 | 272 | <EditableProTable |
270 | 273 | rowKey="tid" |
271 | 274 | formRef={ref} | ... | ... |
src/pages/Client/Client/Components/InformationHistoryModal.tsx
... | ... | @@ -10,8 +10,6 @@ import { Button, Descriptions, Space } from 'antd'; |
10 | 10 | import { useEffect, useRef, useState } from 'react'; |
11 | 11 | |
12 | 12 | export default ({ data, reloadTable }) => { |
13 | - console.log(data, '5656datafirstshowclient'); | |
14 | - | |
15 | 13 | // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 |
16 | 14 | const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 |
17 | 15 | |
... | ... | @@ -23,22 +21,26 @@ export default ({ data, reloadTable }) => { |
23 | 21 | // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 |
24 | 22 | // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 |
25 | 23 | // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 |
26 | - // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询 | |
24 | + const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询 | |
27 | 25 | const [content, setContent] = useState(''); // 跟进详情 |
28 | 26 | const [createTime, setCreateTime] = useState(null); // 创建时间 |
29 | 27 | const [attachments, setAttachments] = useState(); //附件 |
30 | 28 | const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称 |
29 | + const [ticketsType, setTicketsType] = useState(''); // 附件名称 | |
30 | + const [ticketsDetail, setTicketsDetail] = useState(''); // 附件名称 | |
31 | + const [ticketsAttachment, setTicketsAttachment] = useState(''); // 附件名称 | |
32 | + const [assignPeople, setAssignPeople] = useState(''); // 附件名称 | |
33 | + const [comment, setComment] = useState(''); // 客户评价 | |
31 | 34 | |
32 | 35 | useEffect(() => { |
33 | 36 | const request = async () => { |
34 | - console.log(data, '5656datasearch'); | |
35 | 37 | const res = await postAdminClientQueryClientComunicationInfo({ |
36 | 38 | data: { |
37 | 39 | id: data.id, |
38 | 40 | }, |
39 | 41 | }); |
40 | - console.log(res, '5656res'); | |
41 | 42 | const dataSearch = res.data.data[0]; |
43 | + | |
42 | 44 | if (dataSearch) { |
43 | 45 | if (dataSearch.attachments) { |
44 | 46 | const url = dataSearch.attachments; |
... | ... | @@ -52,6 +54,11 @@ export default ({ data, reloadTable }) => { |
52 | 54 | setAttachmentsName(decodedStr); // 设置跟进日期 |
53 | 55 | } |
54 | 56 | } |
57 | + setComment(dataSearch.comment); | |
58 | + setTicketsType(dataSearch.ticketsTypeText); | |
59 | + setTicketsDetail(dataSearch.ticketsDetail); | |
60 | + setTicketsAttachment(dataSearch.ticketsAttachments); | |
61 | + setAssignPeople(dataSearch.assignPeople); | |
55 | 62 | setDatetime(dataSearch.datetime); // 设置跟进日期 |
56 | 63 | // setDateRange(data.dateRange || []); // 设置跟进时间范围 |
57 | 64 | setCreateByName(dataSearch.createByName); // 设置跟进人员 |
... | ... | @@ -60,13 +67,12 @@ export default ({ data, reloadTable }) => { |
60 | 67 | // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 |
61 | 68 | // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 |
62 | 69 | // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 |
63 | - // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询 | |
70 | + setTradeStatusLike(data.tradeStatusLike); // 设置客户状态模糊查询 | |
64 | 71 | setContent(dataSearch.content); // 设置跟进详情 |
65 | 72 | setCreateTime(dataSearch.createTime); // 设置创建时间 |
66 | 73 | setWay(dataSearch.wayText); |
67 | 74 | setAttachments(dataSearch.attachments); |
68 | 75 | } |
69 | - console.log(attachments, '5656attachments'); | |
70 | 76 | }; |
71 | 77 | request(); |
72 | 78 | }, []); |
... | ... | @@ -101,9 +107,38 @@ export default ({ data, reloadTable }) => { |
101 | 107 | label: '跟进类型', |
102 | 108 | children: way, // 跟进类型 |
103 | 109 | }, |
110 | + { | |
111 | + key: '7', | |
112 | + label: '跟进状态', | |
113 | + children: tradeStatusLike, // 跟进类型 | |
114 | + }, | |
115 | + { | |
116 | + key: '8', | |
117 | + label: '工单类型', | |
118 | + children: ticketsType, // 跟进状态 | |
119 | + }, | |
120 | + { | |
121 | + key: '9', | |
122 | + label: '工单详情', | |
123 | + children: ticketsDetail, // 跟进状态 | |
124 | + }, | |
125 | + // { | |
126 | + // key: '10', | |
127 | + // label: '工单附件', | |
128 | + // children: ticketsAttachment, // 跟进状态 | |
129 | + // }, | |
130 | + { | |
131 | + key: '10', | |
132 | + label: '指派人员', | |
133 | + children: assignPeople, // 跟进状态 | |
134 | + }, | |
135 | + { | |
136 | + key: '11', | |
137 | + label: '客户评价', | |
138 | + children: comment, // 跟进状态 | |
139 | + }, | |
104 | 140 | ]; |
105 | 141 | const handleDelete = async () => { |
106 | - console.log(JSON.stringify(data), '5656record'); | |
107 | 142 | // 调用删除接口 |
108 | 143 | const success = await postAdminClientRemoveClientComunicationInfo({ |
109 | 144 | query: { |
... | ... | @@ -142,7 +177,6 @@ export default ({ data, reloadTable }) => { |
142 | 177 | actionRef?.current?.reload(); // 重新加载表格数据 |
143 | 178 | props.submit(); |
144 | 179 | reloadTable(); |
145 | - console.log('5656close'); | |
146 | 180 | }} |
147 | 181 | type={'modify'} |
148 | 182 | onFinish={() => { |
... | ... | @@ -178,10 +212,83 @@ export default ({ data, reloadTable }) => { |
178 | 212 | }} |
179 | 213 | > |
180 | 214 | <Descriptions items={items} column={1} /> |
181 | - {attachmentsName && ( | |
215 | + {/* {attachmentsName && ( | |
182 | 216 | <a href={attachments} download> |
183 | 217 | 附件:{attachmentsName} |
184 | 218 | </a> |
219 | + )} */} | |
220 | + {attachmentsName && ( | |
221 | + <div> | |
222 | + {attachmentsName.endsWith('.png') || | |
223 | + attachmentsName.endsWith('.jpg') ? ( | |
224 | + <> | |
225 | + <img | |
226 | + src={attachments} | |
227 | + alt={attachmentsName} | |
228 | + style={{ maxWidth: '300px', height: 'auto' }} | |
229 | + /> | |
230 | + <div></div> | |
231 | + <a href={attachments} download> | |
232 | + 附件:{attachmentsName} | |
233 | + </a> | |
234 | + </> | |
235 | + ) : ( | |
236 | + <a href={attachments} download> | |
237 | + 附件:{attachmentsName} | |
238 | + </a> | |
239 | + )} | |
240 | + </div> | |
241 | + )} | |
242 | + | |
243 | + <div></div> | |
244 | + {/* {ticketsAttachment && ( | |
245 | + <a href={ticketsAttachment} download> | |
246 | + 工单附件:{ticketsAttachment} | |
247 | + </a> | |
248 | + )} */} | |
249 | + {/* {ticketsAttachment && ( | |
250 | + <div> | |
251 | + {ticketsAttachment.includes('jpg') || | |
252 | + ticketsAttachment.includes('png') ? ( | |
253 | + <> | |
254 | + <img | |
255 | + src={ticketsAttachment} | |
256 | + alt={ticketsAttachment} | |
257 | + style={{ maxWidth: '300px', height: 'auto' }} | |
258 | + /> | |
259 | + <div></div> | |
260 | + <a href={ticketsAttachment} download> | |
261 | + 工单附件:{ticketsAttachment} | |
262 | + </a> | |
263 | + </> | |
264 | + ) : ( | |
265 | + <a href={ticketsAttachment} download> | |
266 | + 工单附件:{ticketsAttachment} | |
267 | + </a> | |
268 | + )} | |
269 | + </div> | |
270 | + )} */} | |
271 | + {ticketsAttachment && ( | |
272 | + <div> | |
273 | + {ticketsAttachment.split(',').map((ticketsAttachment, index) => ( | |
274 | + <div key={index}> | |
275 | + {ticketsAttachment.includes('jpg') || | |
276 | + ticketsAttachment.includes('png') ? ( | |
277 | + <> | |
278 | + <img | |
279 | + src={ticketsAttachment} | |
280 | + alt={`附件 ${index + 1}`} | |
281 | + style={{ maxWidth: '300px', height: 'auto' }} | |
282 | + /> | |
283 | + <div></div> | |
284 | + </> | |
285 | + ) : null} | |
286 | + <a href={ticketsAttachment} download> | |
287 | + 工单附件:{ticketsAttachment} | |
288 | + </a> | |
289 | + </div> | |
290 | + ))} | |
291 | + </div> | |
185 | 292 | )} |
186 | 293 | </ModalForm> |
187 | 294 | </Space> | ... | ... |
src/pages/Client/Client/Components/style.css
0 → 100644
1 | +.styled-text { | |
2 | + display: flex; | |
3 | + align-items: center; | |
4 | + margin-bottom: 20px; | |
5 | +} | |
6 | + | |
7 | +.vertical-line { | |
8 | + width: 2px; /* 线的宽度 */ | |
9 | + height: 20px; /* 线的高度 */ | |
10 | + background-color: black; /* 线的颜色 */ | |
11 | + margin-right: 10px; /* 线与文本之间的间距 */ | |
12 | +} | |
13 | + | |
14 | +.text { | |
15 | + font-size: 20px; /* 文本大小 */ | |
16 | + font-family: Arial, sans-serif; /* 字体样式 */ | |
17 | + color: black; /* 文本颜色 */ | |
18 | +} | ... | ... |
src/pages/Client/Client/index.tsx
... | ... | @@ -8,9 +8,8 @@ import { |
8 | 8 | postAdminClientGetStatisticalData, |
9 | 9 | postAdminClientQueryClientPage, |
10 | 10 | postServiceConstClientLevels, |
11 | - postServiceConstClientRequirements, | |
12 | 11 | postServiceConstClientSource, |
13 | - postServiceConstTradeStatus, | |
12 | + postServiceOrderQueryCustomerInformation, | |
14 | 13 | } from '@/services'; |
15 | 14 | import { downloadFile } from '@/services/order'; |
16 | 15 | import { enumToSelect } from '@/utils'; |
... | ... | @@ -41,6 +40,12 @@ const columns = [ |
41 | 40 | // hideInSearch: true, |
42 | 41 | // }, |
43 | 42 | { |
43 | + title: '客户名称', | |
44 | + dataIndex: 'nameLike', | |
45 | + valueType: 'Text', | |
46 | + hideInTable: true, | |
47 | + }, | |
48 | + { | |
44 | 49 | title: '客户地址', |
45 | 50 | width: 250, |
46 | 51 | ellipsis: true, |
... | ... | @@ -48,10 +53,10 @@ const columns = [ |
48 | 53 | hideInSearch: false, |
49 | 54 | }, |
50 | 55 | { |
51 | - title: '联系人', | |
56 | + title: '负责人', | |
52 | 57 | width: 150, |
53 | 58 | ellipsis: true, |
54 | - dataIndex: 'contacts', | |
59 | + dataIndex: 'leaderName', | |
55 | 60 | hideInSearch: false, |
56 | 61 | }, |
57 | 62 | { |
... | ... | @@ -62,73 +67,110 @@ const columns = [ |
62 | 67 | hideInSearch: true, |
63 | 68 | }, |
64 | 69 | { |
65 | - title: '客户来源', | |
70 | + title: '课题组', | |
71 | + dataIndex: 'institutionContactName', | |
66 | 72 | width: 150, |
67 | 73 | ellipsis: true, |
68 | - dataIndex: 'sourceText', | |
69 | 74 | hideInSearch: true, |
70 | 75 | }, |
71 | 76 | { |
72 | - title: '客户来源', | |
77 | + title: '课题组', | |
78 | + dataIndex: 'institutionContactName', | |
73 | 79 | valueType: 'select', |
74 | 80 | hideInTable: true, |
75 | - dataIndex: 'source', | |
76 | - request: async () => { | |
77 | - const res = await postServiceConstClientSource(); | |
78 | - return enumToSelect(res.data); | |
81 | + fieldProps: { | |
82 | + showSearch: true, | |
83 | + // mode: 'tags', // 允许自定义输入 | |
84 | + }, | |
85 | + request: async (value, { params }) => { | |
86 | + const keywords = value.keyWords; | |
87 | + const { data } = await postServiceOrderQueryCustomerInformation({ | |
88 | + data: { | |
89 | + name: 'institutionContactName', | |
90 | + institutionContactName: keywords, | |
91 | + }, | |
92 | + params: params, | |
93 | + }); | |
94 | + let options = data | |
95 | + .filter((c: any) => { | |
96 | + return c.orderName === 'institutionCustomerUser'; | |
97 | + }) | |
98 | + .map((item: any) => { | |
99 | + return { | |
100 | + label: item.orderValue, | |
101 | + value: item.orderValue, | |
102 | + }; | |
103 | + }); | |
104 | + return options; | |
79 | 105 | }, |
80 | 106 | }, |
81 | 107 | { |
82 | - title: '推荐人', | |
83 | - dataIndex: 'referrers', | |
108 | + title: '部门', | |
109 | + width: 150, | |
110 | + ellipsis: true, | |
111 | + dataIndex: 'department', | |
112 | + hideInSearch: true, | |
113 | + }, | |
114 | + { | |
115 | + title: '年级/职位', | |
84 | 116 | width: 150, |
85 | 117 | ellipsis: true, |
118 | + dataIndex: 'gradePosition', | |
86 | 119 | hideInSearch: true, |
87 | 120 | }, |
88 | 121 | { |
89 | - title: '客户需求', | |
90 | - width: 240, | |
122 | + title: '客户来源', | |
123 | + width: 150, | |
91 | 124 | ellipsis: true, |
92 | - dataIndex: 'requirementsText', | |
125 | + dataIndex: 'sourceText', | |
93 | 126 | hideInSearch: true, |
94 | 127 | }, |
95 | 128 | { |
96 | - title: '客户需求', | |
97 | - dataIndex: 'requirements', | |
129 | + title: '客户来源', | |
98 | 130 | valueType: 'select', |
99 | 131 | hideInTable: true, |
132 | + dataIndex: 'source', | |
100 | 133 | request: async () => { |
101 | - const res = await postServiceConstClientRequirements(); | |
102 | - // function enumToSelect(data: any) { | |
103 | - // const keys = Object.keys(data); | |
104 | - // return keys.map((value) => { | |
105 | - // return { label: data[value], value: value }; | |
106 | - // }); | |
107 | - // } | |
134 | + const res = await postServiceConstClientSource(); | |
108 | 135 | return enumToSelect(res.data); |
109 | 136 | }, |
110 | 137 | }, |
111 | 138 | { |
112 | - title: '是否已报方案', | |
113 | - width: 150, | |
114 | - ellipsis: true, | |
115 | - dataIndex: 'hasSchemeText', | |
116 | - hideInSearch: true, | |
117 | - }, | |
118 | - { | |
119 | - title: '报价时间', | |
120 | - key: 'since', | |
139 | + title: '推荐人', | |
140 | + dataIndex: 'referrers', | |
121 | 141 | width: 150, |
122 | 142 | ellipsis: true, |
123 | - dataIndex: 'quoteDatetime', | |
124 | - valueType: 'date', | |
125 | 143 | hideInSearch: true, |
126 | 144 | }, |
145 | + // { | |
146 | + // title: '客户需求', | |
147 | + // width: 240, | |
148 | + // ellipsis: true, | |
149 | + // dataIndex: 'requirementsText', | |
150 | + // hideInSearch: true, | |
151 | + // }, | |
152 | + // { | |
153 | + // title: '客户需求', | |
154 | + // dataIndex: 'requirements', | |
155 | + // valueType: 'select', | |
156 | + // hideInTable: true, | |
157 | + // hideInSearch: true, | |
158 | + // request: async () => { | |
159 | + // const res = await postServiceConstClientRequirements(); | |
160 | + // // function enumToSelect(data: any) { | |
161 | + // // const keys = Object.keys(data); | |
162 | + // // return keys.map((value) => { | |
163 | + // // return { label: data[value], value: value }; | |
164 | + // // }); | |
165 | + // // } | |
166 | + // return enumToSelect(res.data); | |
167 | + // }, | |
168 | + // }, | |
127 | 169 | { |
128 | - title: '跟进状态', | |
170 | + title: '创建人', | |
129 | 171 | width: 150, |
130 | 172 | ellipsis: true, |
131 | - dataIndex: 'tradeStatusText', | |
173 | + dataIndex: 'createByName', | |
132 | 174 | hideInSearch: true, |
133 | 175 | }, |
134 | 176 | { |
... | ... | @@ -165,41 +207,30 @@ const columns = [ |
165 | 207 | // valueType: 'dateTime', |
166 | 208 | // hideInSearch: true, |
167 | 209 | // }, |
168 | - { | |
169 | - title: '客户名称', | |
170 | - dataIndex: 'nameLike', | |
171 | - valueType: 'Text', | |
172 | - hideInTable: true, | |
173 | - }, | |
174 | 210 | // { |
175 | 211 | // title: '单位名称', |
176 | 212 | // dataIndex: 'companyNameLike', |
177 | 213 | // valueType: 'Text', |
178 | 214 | // hideInTable: true, |
179 | 215 | // }, |
180 | - { | |
181 | - title: '联系电话', | |
182 | - dataIndex: 'phoneNumberLike', | |
183 | - valueType: 'Text', | |
184 | - hideInTable: true, | |
185 | - }, | |
186 | - { | |
187 | - title: '是否已报方案', | |
188 | - dataIndex: 'hasScheme', | |
189 | - valueType: 'select', | |
190 | - width: 1550, | |
191 | - valueEnum: { | |
192 | - true: { | |
193 | - text: '是', | |
194 | - value: true, | |
195 | - }, | |
196 | - false: { | |
197 | - text: '否', | |
198 | - value: false, | |
199 | - }, | |
200 | - }, | |
201 | - hideInTable: true, | |
202 | - }, | |
216 | + // { | |
217 | + // title: '联系电话', | |
218 | + // dataIndex: 'phoneNumberLike', | |
219 | + // valueType: 'Text', | |
220 | + // hideInTable: true, | |
221 | + // }, | |
222 | + // { | |
223 | + // title: '部门', | |
224 | + // dataIndex: 'department', | |
225 | + // valueType: 'Text', | |
226 | + // hideInTable: false, | |
227 | + // }, | |
228 | + // { | |
229 | + // title: '年级/职位', | |
230 | + // dataIndex: 'gradePosition', | |
231 | + // valueType: 'Text', | |
232 | + // hideInTable: false, | |
233 | + // }, | |
203 | 234 | { |
204 | 235 | title: '客户等级', |
205 | 236 | dataIndex: 'level', |
... | ... | @@ -218,25 +249,30 @@ const columns = [ |
218 | 249 | }, |
219 | 250 | }, |
220 | 251 | { |
221 | - title: '跟进状态', | |
222 | - dataIndex: 'tradeStatus', | |
223 | - valueType: 'select', | |
252 | + title: '创建时间', | |
253 | + valueType: 'dateRange', | |
224 | 254 | hideInTable: true, |
225 | - request: async () => { | |
226 | - const res = await postServiceConstTradeStatus(); | |
227 | - return enumToSelect(res.data); | |
255 | + search: { | |
256 | + transform: (value) => { | |
257 | + if (value) { | |
258 | + return { | |
259 | + createTimeGe: value[0], | |
260 | + createTimeLe: value[1], | |
261 | + }; | |
262 | + } | |
263 | + }, | |
228 | 264 | }, |
229 | 265 | }, |
230 | 266 | { |
231 | - title: '创建时间', | |
267 | + title: '最新跟进时间', | |
232 | 268 | valueType: 'dateRange', |
233 | 269 | hideInTable: true, |
234 | 270 | search: { |
235 | 271 | transform: (value) => { |
236 | 272 | if (value) { |
237 | 273 | return { |
238 | - createTimeGe: value[0], | |
239 | - createTimeLe: value[1], | |
274 | + updateTimeGe: value[0], | |
275 | + updateTimeLe: value[1], | |
240 | 276 | }; |
241 | 277 | } |
242 | 278 | }, |
... | ... | @@ -249,7 +285,6 @@ const columns = [ |
249 | 285 | width: 200, |
250 | 286 | render: (text, record, index, action) => { |
251 | 287 | const handleDelete = async () => { |
252 | - console.log(JSON.stringify(record), '5656record1'); | |
253 | 288 | // 调用删除接口 |
254 | 289 | const success = await postAdminClientDeleteAdminClient({ |
255 | 290 | query: { |
... | ... | @@ -260,7 +295,6 @@ const columns = [ |
260 | 295 | action.reload(); // 刷新表格 |
261 | 296 | } |
262 | 297 | }; |
263 | - console.log(JSON.stringify(record), '5656record2'); | |
264 | 298 | return [ |
265 | 299 | <CommunicationHistoryModal |
266 | 300 | key={'communicationHistory'} |
... | ... | @@ -323,11 +357,11 @@ export default () => { |
323 | 357 | const pullStatistic = async () => { |
324 | 358 | let statisticalData = await postAdminClientGetStatisticalData(); |
325 | 359 | console.log('stati' + JSON.stringify(statisticalData.data)); |
360 | + console.log(clientStatistic); | |
326 | 361 | setClientStatistic(statisticalData.data); |
327 | - setWarningClientStatistic(statisticalData.data[1].value); | |
362 | + setWarningClientStatistic(statisticalData?.data[1].value); | |
328 | 363 | // setAllClientStatistic(statisticalData.data[0].value); |
329 | 364 | setTimeout(() => { |
330 | - console.log(clientStatistic, '5656groupFilterOptions1'); | |
331 | 365 | // groupFilterOptions[0].label = groupFilterOptions[0].label + '(' + clientStatistic + ')'; |
332 | 366 | }, 100); |
333 | 367 | actionRef.current?.reload(); // 可能需要在这里刷新 |
... | ... | @@ -361,8 +395,6 @@ export default () => { |
361 | 395 | // }, []); |
362 | 396 | useEffect(() => { |
363 | 397 | // console.log(groupFilterOptions, '5656groupFilterOptions2'); |
364 | - console.log(clientStatistic, '5656clientStatistic'); | |
365 | - console.log(warningClientStatistic, '5656warningClientStatistic'); | |
366 | 398 | actionRef.current?.reload(); |
367 | 399 | }, [groupFilter]); |
368 | 400 | return ( |
... | ... | @@ -411,7 +443,6 @@ export default () => { |
411 | 443 | 'POST', |
412 | 444 | values, |
413 | 445 | () => { |
414 | - console.log(searchConfig, '5656searchConfig'); | |
415 | 446 | messageApi.destroy(); |
416 | 447 | }, |
417 | 448 | ); | ... | ... |
src/pages/Client/FollowRecord/Components/ClientModal.tsx
1 | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | |
2 | 3 | import { |
3 | 4 | postAdminClientAddOrModifyClientComunicationInfo, |
4 | 5 | postAdminClientQueryClientPage, |
5 | 6 | postOrderErpOrderStagesUpload, |
7 | + postOrderErpUsersListByPage, | |
6 | 8 | postServiceConstClientWay, |
9 | + postServiceConstTradeStatus, | |
7 | 10 | } from '@/services'; |
8 | 11 | import { enumToSelect } from '@/utils'; |
9 | 12 | import { |
... | ... | @@ -14,8 +17,9 @@ import { |
14 | 17 | ProFormTextArea, |
15 | 18 | ProFormUploadDragger, |
16 | 19 | } from '@ant-design/pro-components'; |
17 | -import { Button, Form, message } from 'antd'; | |
20 | +import { Button, Col, Form, Row, message } from 'antd'; | |
18 | 21 | import { RcFile } from 'antd/es/upload'; |
22 | +import './style.css'; | |
19 | 23 | export default ({ data, type, reloadTable }) => { |
20 | 24 | const [form] = Form.useForm(); |
21 | 25 | const onfinish = async (values) => { |
... | ... | @@ -37,6 +41,7 @@ export default ({ data, type, reloadTable }) => { |
37 | 41 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
38 | 42 | data: { |
39 | 43 | ...values, |
44 | + ticketsAttachments: form.getFieldValue('ticketsAttachments'), | |
40 | 45 | clientId: matchedId, |
41 | 46 | }, |
42 | 47 | }); |
... | ... | @@ -47,10 +52,10 @@ export default ({ data, type, reloadTable }) => { |
47 | 52 | } |
48 | 53 | // 不返回不会关闭弹框 |
49 | 54 | }; |
55 | + | |
50 | 56 | const editOnfinish = async (values) => { |
51 | 57 | // setEditClientId(data.clientId); |
52 | 58 | values.clientId = data.clientId; |
53 | - console.log(values, '5656editClientId'); | |
54 | 59 | |
55 | 60 | // const resSearchId = await postAdminClientQueryClientPage({ |
56 | 61 | // data: { |
... | ... | @@ -60,10 +65,15 @@ export default ({ data, type, reloadTable }) => { |
60 | 65 | // const matchingItem = resSearchId.data.data.find( |
61 | 66 | // (item) => item.id === values.name, |
62 | 67 | // ); |
63 | - | |
64 | 68 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
65 | 69 | data: { |
66 | 70 | ...values, |
71 | + // ticketsAttachments: form.getFieldValue("ticketsAttachments"), | |
72 | + ticketsAttachments: | |
73 | + form.getFieldValue('ticketsAttachments') !== undefined | |
74 | + ? form.getFieldValue('ticketsAttachments') | |
75 | + : data?.ticketsAttachments, | |
76 | + // ticketsAttachments: data?.annexUrl, | |
67 | 77 | }, |
68 | 78 | }); |
69 | 79 | if (res.result === RESPONSE_CODE.SUCCESS) { |
... | ... | @@ -140,7 +150,6 @@ export default ({ data, type, reloadTable }) => { |
140 | 150 | groupFilter: 'all', |
141 | 151 | }, |
142 | 152 | }); |
143 | - console.log(data, '5656data?.nameedit'); | |
144 | 153 | // const namesArray = res.data.data.map((item) => item.name); |
145 | 154 | // const formattedObject = res.data.data.reduce((acc, name) => { |
146 | 155 | // acc[name] = name; // 将名称作为键和值 |
... | ... | @@ -165,18 +174,67 @@ export default ({ data, type, reloadTable }) => { |
165 | 174 | }, |
166 | 175 | ]} |
167 | 176 | ></ProFormSelect> |
177 | + <ProFormText | |
178 | + name="contact" | |
179 | + label="联系人" | |
180 | + width="sm" | |
181 | + placeholder="请输入联系人" | |
182 | + initialValue={data?.content} | |
183 | + readonly={optType[type].readOnly} | |
184 | + rules={[ | |
185 | + { | |
186 | + required: true, | |
187 | + message: '请输入联系人', | |
188 | + }, | |
189 | + ]} | |
190 | + ></ProFormText> | |
191 | + <ProFormText | |
192 | + name="contactPhone" | |
193 | + label="联系电话" | |
194 | + width="sm" | |
195 | + placeholder="请输入联系电话" | |
196 | + initialValue={data?.content} | |
197 | + readonly={optType[type].readOnly} | |
198 | + rules={[ | |
199 | + { | |
200 | + required: true, | |
201 | + message: '请输入联系电话', | |
202 | + }, | |
203 | + ]} | |
204 | + ></ProFormText> | |
168 | 205 | <ProFormDateTimePicker |
169 | 206 | name="datetime" |
170 | - label="日期" | |
207 | + label="跟进日期" | |
171 | 208 | initialValue={data ? data?.datetime + '' : null} |
172 | 209 | placeholder="请选择跟进时间" |
173 | 210 | width="sm" |
174 | 211 | rules={[ |
175 | 212 | { |
176 | 213 | required: true, |
177 | - message: '请选择日期', | |
214 | + message: '请选择跟进日期', | |
215 | + }, | |
216 | + ]} | |
217 | + /> | |
218 | + <ProFormSelect | |
219 | + name="tradeStatus" | |
220 | + label="跟进状态" | |
221 | + width="sm" | |
222 | + placeholder="请输入跟进状态" | |
223 | + readonly={optType[type].readOnly} | |
224 | + fieldProps={{ | |
225 | + labelInValue: false, | |
226 | + }} | |
227 | + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null} | |
228 | + rules={[ | |
229 | + { | |
230 | + required: true, | |
231 | + message: '请输入跟进状态', | |
178 | 232 | }, |
179 | 233 | ]} |
234 | + request={async () => { | |
235 | + const res = await postServiceConstTradeStatus(); | |
236 | + return enumToSelect(res.data); | |
237 | + }} | |
180 | 238 | /> |
181 | 239 | <ProFormSelect |
182 | 240 | name="way" |
... | ... | @@ -186,7 +244,7 @@ export default ({ data, type, reloadTable }) => { |
186 | 244 | labelInValue: false, |
187 | 245 | }} |
188 | 246 | initialValue={data?.way ? data?.way + '' : null} |
189 | - label="类型" | |
247 | + label="跟进方式" | |
190 | 248 | request={async () => { |
191 | 249 | const res = await postServiceConstClientWay(); |
192 | 250 | return enumToSelect(res.data); |
... | ... | @@ -194,20 +252,20 @@ export default ({ data, type, reloadTable }) => { |
194 | 252 | rules={[ |
195 | 253 | { |
196 | 254 | required: true, |
197 | - message: '请选择跟进类型', | |
255 | + message: '请选择跟进方式', | |
198 | 256 | }, |
199 | 257 | ]} |
200 | 258 | ></ProFormSelect> |
201 | 259 | <ProFormTextArea |
202 | 260 | name="content" |
203 | - label="详情" | |
204 | - placeholder="请输入详情" | |
261 | + label="跟进详情" | |
262 | + placeholder="请输入跟进详情" | |
205 | 263 | initialValue={data?.content} |
206 | 264 | readonly={optType[type].readOnly} |
207 | 265 | rules={[ |
208 | 266 | { |
209 | 267 | required: true, |
210 | - message: '请输入详情', | |
268 | + message: '请输入跟进详情', | |
211 | 269 | }, |
212 | 270 | ]} |
213 | 271 | ></ProFormTextArea> |
... | ... | @@ -242,12 +300,138 @@ export default ({ data, type, reloadTable }) => { |
242 | 300 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> |
243 | 301 | 下载附件 |
244 | 302 | </a> |
303 | + <ProFormTextArea | |
304 | + name="comment" | |
305 | + label="客户评价" | |
306 | + placeholder="请输入客户评价" | |
307 | + initialValue={data?.comment} | |
308 | + readonly={optType[type].readOnly} | |
309 | + ></ProFormTextArea> | |
245 | 310 | <ProFormText |
246 | 311 | initialValue={data?.attachments} |
247 | 312 | name="attachments" |
248 | 313 | hidden |
249 | 314 | ></ProFormText> |
250 | 315 | <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> |
316 | + <div className="styled-text"> | |
317 | + <div className="vertical-line"></div> | |
318 | + <span className="text">工单指派</span> | |
319 | + </div> | |
320 | + <ProFormSelect | |
321 | + name="ticketsType" | |
322 | + label="工单类型" | |
323 | + width="sm" | |
324 | + placeholder="请输入工单类型" | |
325 | + readonly={optType[type].readOnly} | |
326 | + fieldProps={{ | |
327 | + labelInValue: false, | |
328 | + }} | |
329 | + initialValue={data?.ticketsType ? data?.ticketsType + '' : null} | |
330 | + request={async () => { | |
331 | + return [ | |
332 | + { label: '问题', value: 'QUESTION' }, | |
333 | + { label: '需求', value: 'DEMAND' }, | |
334 | + { label: '建议', value: 'ADVICE' }, | |
335 | + ]; | |
336 | + }} | |
337 | + /> | |
338 | + <ProFormTextArea | |
339 | + name="ticketsDetail" | |
340 | + label="工单详情" | |
341 | + placeholder="请输入工单详情" | |
342 | + initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null} | |
343 | + readonly={optType[type].readOnly} | |
344 | + ></ProFormTextArea> | |
345 | + {/* <ProFormUploadDragger | |
346 | + label="工单附件" | |
347 | + name="ticketsAttachment" | |
348 | + action="upload.do" | |
349 | + hidden={optType[type].readOnly} | |
350 | + onChange={(info) => { | |
351 | + const uploadFile = async ({ fileList: newFileList }) => { | |
352 | + if (newFileList.length > 0) { | |
353 | + const formData = new FormData(); | |
354 | + formData.append('file', newFileList[0].originFileObj as RcFile); | |
355 | + const res = await postOrderErpOrderStagesUpload({ | |
356 | + data: formData, | |
357 | + headers: { | |
358 | + 'Content-Type': | |
359 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
360 | + }, | |
361 | + }); | |
362 | + const url = res.data; | |
363 | + console.log('ticketsAttachments' + JSON.stringify(url)); | |
364 | + form.setFieldValue('ticketsAttachments', url); | |
365 | + } else { | |
366 | + form.setFieldValue('ticketsAttachments', null); | |
367 | + } | |
368 | + }; | |
369 | + uploadFile(info); | |
370 | + }} | |
371 | + max={1} | |
372 | + /> */} | |
373 | + <Row> | |
374 | + <Col span={4}>附件:</Col> | |
375 | + <Col span={20}> | |
376 | + <UploadC | |
377 | + onFilesChange={async (newFileList) => { | |
378 | + if (newFileList.length > 0) { | |
379 | + const urls = []; // 创建一个数组来存储所有的 URL | |
380 | + | |
381 | + for (const file of newFileList) { | |
382 | + const formData = new FormData(); | |
383 | + formData.append('file', file.originFileObj as RcFile); | |
384 | + | |
385 | + const res = await postOrderErpOrderStagesUpload({ | |
386 | + data: formData, | |
387 | + headers: { | |
388 | + 'Content-Type': | |
389 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
390 | + }, | |
391 | + }); | |
392 | + | |
393 | + const url = res.data; // 获取响应中的 URL | |
394 | + urls.push(url); // 将每个 URL 追加到数组中 | |
395 | + } | |
396 | + | |
397 | + // 将所有 URL 使用 ',' 进行拼接 | |
398 | + const combinedUrl = urls.join(','); | |
399 | + form.setFieldValue('ticketsAttachments', combinedUrl); // 设置表单字段值为拼接后的 URL | |
400 | + } else { | |
401 | + form.setFieldValue('ticketsAttachments', null); // 如果没有文件,则清空 URL | |
402 | + } | |
403 | + }} | |
404 | + ></UploadC> | |
405 | + </Col> | |
406 | + </Row> | |
407 | + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download> | |
408 | + {/* <a href={data?.annexUrl} download> */} | |
409 | + 下载附件 | |
410 | + </a> | |
411 | + <ProFormSelect | |
412 | + name="assignPeople" | |
413 | + width="sm" | |
414 | + readonly={optType[type].readOnly} | |
415 | + fieldProps={{ | |
416 | + labelInValue: false, | |
417 | + }} | |
418 | + initialValue={data?.assignPeople ? data?.assignPeople + '' : null} | |
419 | + label="指派人员" | |
420 | + request={async () => { | |
421 | + const res = await postOrderErpUsersListByPage({ | |
422 | + data: { | |
423 | + pageSize: 10000, | |
424 | + }, | |
425 | + }); | |
426 | + const userOptions = res.data.records | |
427 | + ? res.data.records.map((user) => ({ | |
428 | + label: user.userName, // 或者使用其他需要的属性 | |
429 | + value: user.userName, // 作为value的字段 | |
430 | + })) | |
431 | + : []; | |
432 | + return userOptions; | |
433 | + }} | |
434 | + ></ProFormSelect> | |
251 | 435 | </ModalForm> |
252 | 436 | ); |
253 | 437 | }; | ... | ... |
src/pages/Client/FollowRecord/Components/ClientModal2.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | |
3 | +import { | |
4 | + postAdminClientAddOrModifyClientComunicationInfo, | |
5 | + postAdminClientQueryClientPage, | |
6 | + postOrderErpOrderStagesUpload, | |
7 | + postOrderErpUsersListByPage, | |
8 | + postServiceConstClientWay, | |
9 | + postServiceConstTradeStatus, | |
10 | +} from '@/services'; | |
11 | +import { enumToSelect } from '@/utils'; | |
12 | +import { | |
13 | + ModalForm, | |
14 | + ProFormDateTimePicker, | |
15 | + ProFormSelect, | |
16 | + ProFormText, | |
17 | + ProFormTextArea, | |
18 | + ProFormUploadDragger, | |
19 | +} from '@ant-design/pro-components'; | |
20 | +import { Button, Col, Form, Row, message } from 'antd'; | |
21 | +import { RcFile } from 'antd/es/upload'; | |
22 | +import './style.css'; | |
23 | +export default ({ data, type, reloadTable }) => { | |
24 | + const [form] = Form.useForm(); | |
25 | + const onfinish = async (values) => { | |
26 | + const resSearchId = await postAdminClientQueryClientPage({ | |
27 | + data: { | |
28 | + groupFilter: 'all', | |
29 | + }, | |
30 | + }); | |
31 | + const matchingItem = resSearchId.data.data.find( | |
32 | + (item) => item.id === values.name, | |
33 | + ); | |
34 | + let matchedId; | |
35 | + if (matchingItem) { | |
36 | + matchedId = matchingItem.id; // 匹配成功,取出 id | |
37 | + values.name = matchingItem.name; | |
38 | + } else { | |
39 | + matchedId = null; // 如果没有匹配项,可以设置为 null 或其他值 | |
40 | + } | |
41 | + const res = await postAdminClientAddOrModifyClientComunicationInfo({ | |
42 | + data: { | |
43 | + ...values, | |
44 | + ticketsAttachments: form.getFieldValue('ticketsAttachments'), | |
45 | + clientId: matchedId, | |
46 | + }, | |
47 | + }); | |
48 | + if (res.result === RESPONSE_CODE.SUCCESS) { | |
49 | + message.success('新增成功'); | |
50 | + reloadTable(); | |
51 | + return true; | |
52 | + } | |
53 | + // 不返回不会关闭弹框 | |
54 | + }; | |
55 | + | |
56 | + const editOnfinish = async (values) => { | |
57 | + // setEditClientId(data.clientId); | |
58 | + values.clientId = data.clientId; | |
59 | + | |
60 | + // const resSearchId = await postAdminClientQueryClientPage({ | |
61 | + // data: { | |
62 | + // groupFilter: 'all', | |
63 | + // }, | |
64 | + // }); | |
65 | + // const matchingItem = resSearchId.data.data.find( | |
66 | + // (item) => item.id === values.name, | |
67 | + // ); | |
68 | + const res = await postAdminClientAddOrModifyClientComunicationInfo({ | |
69 | + data: { | |
70 | + ...values, | |
71 | + // ticketsAttachments: form.getFieldValue("ticketsAttachments"), | |
72 | + ticketsAttachments: | |
73 | + form.getFieldValue('ticketsAttachments') !== undefined | |
74 | + ? form.getFieldValue('ticketsAttachments') | |
75 | + : data?.ticketsAttachments, | |
76 | + url: | |
77 | + form.getFieldValue('url') !== undefined | |
78 | + ? form.getFieldValue('url') | |
79 | + : data?.url, | |
80 | + // ticketsAttachments: data?.annexUrl, | |
81 | + }, | |
82 | + }); | |
83 | + if (res.result === RESPONSE_CODE.SUCCESS) { | |
84 | + message.success('新增成功'); | |
85 | + reloadTable(); | |
86 | + return true; | |
87 | + } | |
88 | + // 不返回不会关闭弹框 | |
89 | + }; | |
90 | + const optType = { | |
91 | + add: { | |
92 | + readOnly: false, | |
93 | + title: '新增跟进记录', | |
94 | + button: ( | |
95 | + <Button size={'middle'} type="primary"> | |
96 | + 新增 | |
97 | + </Button> | |
98 | + ), | |
99 | + onFinish: onfinish, | |
100 | + }, | |
101 | + modify: { | |
102 | + readOnly: false, | |
103 | + title: '修改跟进记录', | |
104 | + button: ( | |
105 | + <Button size={'middle'} type="primary"> | |
106 | + 编辑 | |
107 | + </Button> | |
108 | + ), | |
109 | + onFinish: editOnfinish, | |
110 | + }, | |
111 | + detail: { | |
112 | + readOnly: true, | |
113 | + title: '查看跟进记录', | |
114 | + button: ( | |
115 | + <Button size={'middle'} type="primary" color="red"> | |
116 | + 查看 | |
117 | + </Button> | |
118 | + ), | |
119 | + onFinish: () => {}, | |
120 | + }, | |
121 | + }; | |
122 | + return ( | |
123 | + <ModalForm | |
124 | + title={optType[type].title} | |
125 | + resize={{ | |
126 | + onResize() { | |
127 | + console.log('resize!'); | |
128 | + }, | |
129 | + maxWidth: window.innerWidth * 0.8, | |
130 | + minWidth: 400, | |
131 | + }} | |
132 | + form={form} | |
133 | + trigger={optType[type].button} | |
134 | + autoFocusFirstInput | |
135 | + drawerProps={{ | |
136 | + destroyOnClose: true, | |
137 | + }} | |
138 | + submitTimeout={2000} | |
139 | + onFinish={optType[type].onFinish} | |
140 | + > | |
141 | + <ProFormSelect | |
142 | + name="name" | |
143 | + readonly={optType[type].readOnly} | |
144 | + fieldProps={{ | |
145 | + labelInValue: false, | |
146 | + disabled: type === 'modify', | |
147 | + }} | |
148 | + initialValue={data ? data?.clientName + '' : null} | |
149 | + label="客户" | |
150 | + width="sm" | |
151 | + request={async () => { | |
152 | + const res = await postAdminClientQueryClientPage({ | |
153 | + data: { | |
154 | + groupFilter: 'all', | |
155 | + }, | |
156 | + }); | |
157 | + // const namesArray = res.data.data.map((item) => item.name); | |
158 | + // const formattedObject = res.data.data.reduce((acc, name) => { | |
159 | + // acc[name] = name; // 将名称作为键和值 | |
160 | + // return acc; | |
161 | + // }, {}); | |
162 | + // console.log(namesArray, '5656namesArray'); | |
163 | + // const formattedObject = res.data.data.reduce((acc, item) => { | |
164 | + // acc[item.name] = item.name; // 使用 name 作为键,id 作为值 | |
165 | + // return acc; | |
166 | + // }, {}); | |
167 | + // return enumToSelect(formattedObject); | |
168 | + const options = res.data.data.reduce((acc, item) => { | |
169 | + acc.push({ label: item.name, value: item.id }); // 使用 name 作为 label,id 作为 value | |
170 | + return acc; | |
171 | + }, []); | |
172 | + return options; | |
173 | + }} | |
174 | + rules={[ | |
175 | + { | |
176 | + required: true, | |
177 | + message: '请选择客户', | |
178 | + }, | |
179 | + ]} | |
180 | + ></ProFormSelect> | |
181 | + <ProFormText | |
182 | + name="contact" | |
183 | + label="联系人" | |
184 | + width="sm" | |
185 | + placeholder="请输入联系人" | |
186 | + initialValue={data?.content} | |
187 | + readonly={optType[type].readOnly} | |
188 | + rules={[ | |
189 | + { | |
190 | + required: true, | |
191 | + message: '请输入联系人', | |
192 | + }, | |
193 | + ]} | |
194 | + ></ProFormText> | |
195 | + <ProFormText | |
196 | + name="contactPhone" | |
197 | + label="联系电话" | |
198 | + width="sm" | |
199 | + placeholder="请输入联系电话" | |
200 | + initialValue={data?.content} | |
201 | + readonly={optType[type].readOnly} | |
202 | + rules={[ | |
203 | + { | |
204 | + required: true, | |
205 | + message: '请输入联系电话', | |
206 | + }, | |
207 | + ]} | |
208 | + ></ProFormText> | |
209 | + <ProFormDateTimePicker | |
210 | + name="datetime" | |
211 | + label="跟进日期" | |
212 | + initialValue={data ? data?.datetime + '' : null} | |
213 | + placeholder="请选择跟进时间" | |
214 | + width="sm" | |
215 | + rules={[ | |
216 | + { | |
217 | + required: true, | |
218 | + message: '请选择跟进日期', | |
219 | + }, | |
220 | + ]} | |
221 | + /> | |
222 | + <ProFormSelect | |
223 | + name="tradeStatus" | |
224 | + label="跟进状态" | |
225 | + width="sm" | |
226 | + placeholder="请输入跟进状态" | |
227 | + readonly={optType[type].readOnly} | |
228 | + fieldProps={{ | |
229 | + labelInValue: false, | |
230 | + }} | |
231 | + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null} | |
232 | + rules={[ | |
233 | + { | |
234 | + required: true, | |
235 | + message: '请输入跟进状态', | |
236 | + }, | |
237 | + ]} | |
238 | + request={async () => { | |
239 | + const res = await postServiceConstTradeStatus(); | |
240 | + return enumToSelect(res.data); | |
241 | + }} | |
242 | + /> | |
243 | + <ProFormSelect | |
244 | + name="way" | |
245 | + width="sm" | |
246 | + readonly={optType[type].readOnly} | |
247 | + fieldProps={{ | |
248 | + labelInValue: false, | |
249 | + }} | |
250 | + initialValue={data?.way ? data?.way + '' : null} | |
251 | + label="跟进方式" | |
252 | + request={async () => { | |
253 | + const res = await postServiceConstClientWay(); | |
254 | + return enumToSelect(res.data); | |
255 | + }} | |
256 | + rules={[ | |
257 | + { | |
258 | + required: true, | |
259 | + message: '请选择跟进方式', | |
260 | + }, | |
261 | + ]} | |
262 | + ></ProFormSelect> | |
263 | + <ProFormTextArea | |
264 | + name="content" | |
265 | + label="跟进详情" | |
266 | + placeholder="请输入跟进详情" | |
267 | + initialValue={data?.content} | |
268 | + readonly={optType[type].readOnly} | |
269 | + rules={[ | |
270 | + { | |
271 | + required: true, | |
272 | + message: '请输入跟进详情', | |
273 | + }, | |
274 | + ]} | |
275 | + ></ProFormTextArea> | |
276 | + <ProFormUploadDragger | |
277 | + label="附件" | |
278 | + name="attachment" | |
279 | + action="upload.do" | |
280 | + hidden={optType[type].readOnly} | |
281 | + onChange={(info) => { | |
282 | + const uploadFile = async ({ fileList: newFileList }) => { | |
283 | + if (newFileList.length > 0) { | |
284 | + const formData = new FormData(); | |
285 | + formData.append('file', newFileList[0].originFileObj as RcFile); | |
286 | + const res = await postOrderErpOrderStagesUpload({ | |
287 | + data: formData, | |
288 | + headers: { | |
289 | + 'Content-Type': | |
290 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
291 | + }, | |
292 | + }); | |
293 | + const url = res.data; | |
294 | + console.log('attachments' + JSON.stringify(url)); | |
295 | + form.setFieldValue('attachments', url); | |
296 | + } else { | |
297 | + form.setFieldValue('attachments', null); | |
298 | + } | |
299 | + }; | |
300 | + uploadFile(info); | |
301 | + }} | |
302 | + max={1} | |
303 | + /> | |
304 | + <a hidden={!optType[type].readOnly} href={data?.attachments} download> | |
305 | + 下载附件 | |
306 | + </a> | |
307 | + <ProFormTextArea | |
308 | + name="comment" | |
309 | + label="客户评价" | |
310 | + placeholder="请输入客户评价" | |
311 | + initialValue={data?.comment} | |
312 | + readonly={optType[type].readOnly} | |
313 | + ></ProFormTextArea> | |
314 | + <ProFormText | |
315 | + initialValue={data?.attachments} | |
316 | + name="attachments" | |
317 | + hidden | |
318 | + ></ProFormText> | |
319 | + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | |
320 | + <div className="styled-text"> | |
321 | + <div className="vertical-line"></div> | |
322 | + <span className="text">工单指派</span> | |
323 | + </div> | |
324 | + <ProFormSelect | |
325 | + name="ticketsType" | |
326 | + label="工单类型" | |
327 | + width="sm" | |
328 | + placeholder="请输入工单类型" | |
329 | + readonly={optType[type].readOnly} | |
330 | + fieldProps={{ | |
331 | + labelInValue: false, | |
332 | + }} | |
333 | + initialValue={data?.ticketsType ? data?.ticketsType + '' : null} | |
334 | + request={async () => { | |
335 | + return [ | |
336 | + { label: '问题', value: 'QUESTION' }, | |
337 | + { label: '需求', value: 'DEMAND' }, | |
338 | + { label: '建议', value: 'ADVICE' }, | |
339 | + ]; | |
340 | + }} | |
341 | + /> | |
342 | + <ProFormTextArea | |
343 | + name="ticketsDetail" | |
344 | + label="工单详情" | |
345 | + placeholder="请输入工单详情" | |
346 | + initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null} | |
347 | + readonly={optType[type].readOnly} | |
348 | + ></ProFormTextArea> | |
349 | + {/* <ProFormUploadDragger | |
350 | + label="工单附件" | |
351 | + name="ticketsAttachment" | |
352 | + action="upload.do" | |
353 | + hidden={optType[type].readOnly} | |
354 | + onChange={(info) => { | |
355 | + const uploadFile = async ({ fileList: newFileList }) => { | |
356 | + if (newFileList.length > 0) { | |
357 | + const formData = new FormData(); | |
358 | + formData.append('file', newFileList[0].originFileObj as RcFile); | |
359 | + const res = await postOrderErpOrderStagesUpload({ | |
360 | + data: formData, | |
361 | + headers: { | |
362 | + 'Content-Type': | |
363 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
364 | + }, | |
365 | + }); | |
366 | + const url = res.data; | |
367 | + console.log('ticketsAttachments' + JSON.stringify(url)); | |
368 | + form.setFieldValue('ticketsAttachments', url); | |
369 | + } else { | |
370 | + form.setFieldValue('ticketsAttachments', null); | |
371 | + } | |
372 | + }; | |
373 | + uploadFile(info); | |
374 | + }} | |
375 | + max={1} | |
376 | + /> */} | |
377 | + <Row> | |
378 | + <Col span={4}>附件:</Col> | |
379 | + <Col span={20}> | |
380 | + <UploadC | |
381 | + onFilesChange={async (newFileList) => { | |
382 | + if (newFileList.length > 0) { | |
383 | + const urls = []; // 创建一个数组来存储所有的 URL | |
384 | + | |
385 | + for (const file of newFileList) { | |
386 | + const formData = new FormData(); | |
387 | + formData.append('file', file.originFileObj as RcFile); | |
388 | + | |
389 | + const res = await postOrderErpOrderStagesUpload({ | |
390 | + data: formData, | |
391 | + headers: { | |
392 | + 'Content-Type': | |
393 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
394 | + }, | |
395 | + }); | |
396 | + | |
397 | + const url = res.data; // 获取响应中的 URL | |
398 | + urls.push(url); // 将每个 URL 追加到数组中 | |
399 | + } | |
400 | + | |
401 | + // 将所有 URL 使用 ',' 进行拼接 | |
402 | + const combinedUrl = urls.join(','); | |
403 | + form.setFieldValue('ticketsAttachments', combinedUrl); // 设置表单字段值为拼接后的 URL | |
404 | + } else { | |
405 | + form.setFieldValue('ticketsAttachments', null); // 如果没有文件,则清空 URL | |
406 | + } | |
407 | + }} | |
408 | + ></UploadC> | |
409 | + </Col> | |
410 | + </Row> | |
411 | + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download> | |
412 | + {/* <a href={data?.annexUrl} download> */} | |
413 | + 下载附件 | |
414 | + </a> | |
415 | + <ProFormSelect | |
416 | + name="assignPeople" | |
417 | + width="sm" | |
418 | + readonly={optType[type].readOnly} | |
419 | + fieldProps={{ | |
420 | + labelInValue: false, | |
421 | + }} | |
422 | + initialValue={data?.assignPeople ? data?.assignPeople + '' : null} | |
423 | + label="指派人员" | |
424 | + request={async () => { | |
425 | + const res = await postOrderErpUsersListByPage({ | |
426 | + data: { | |
427 | + pageSize: 10000, | |
428 | + }, | |
429 | + }); | |
430 | + const userOptions = res.data.records | |
431 | + ? res.data.records.map((user) => ({ | |
432 | + label: user.userName, // 或者使用其他需要的属性 | |
433 | + value: user.userName, // 作为value的字段 | |
434 | + })) | |
435 | + : []; | |
436 | + return userOptions; | |
437 | + }} | |
438 | + ></ProFormSelect> | |
439 | + {/* <Row> | |
440 | + <Col span={4}>上传发票:</Col> | |
441 | + <Col span={20}> | |
442 | + <UploadC | |
443 | + onFilesChange={async (newFileList) => { | |
444 | + if (newFileList.length > 0) { | |
445 | + const urls = []; // 创建一个数组来存储所有的 URL | |
446 | + | |
447 | + for (const file of newFileList) { | |
448 | + const formData = new FormData(); | |
449 | + formData.append('file', file.originFileObj as RcFile); | |
450 | + | |
451 | + const res = await postOrderErpOrderStagesUpload({ | |
452 | + data: formData, | |
453 | + headers: { | |
454 | + 'Content-Type': | |
455 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | |
456 | + }, | |
457 | + }); | |
458 | + | |
459 | + const url = res.data; // 获取响应中的 URL | |
460 | + urls.push(url); // 将每个 URL 追加到数组中 | |
461 | + } | |
462 | + | |
463 | + // 将所有 URL 使用 ',' 进行拼接 | |
464 | + const combinedUrl = urls.join(','); | |
465 | + form.setFieldValue('url', combinedUrl); // 设置表单字段值为拼接后的 URL | |
466 | + } else { | |
467 | + form.setFieldValue('url', null); // 如果没有文件,则清空 URL | |
468 | + } | |
469 | + }} | |
470 | + ></UploadC> | |
471 | + </Col> | |
472 | + </Row> */} | |
473 | + </ModalForm> | |
474 | + ); | |
475 | +}; | ... | ... |
src/pages/Client/FollowRecord/Components/CommunicationHistoryModal.tsx
... | ... | @@ -8,8 +8,6 @@ import { Button, Descriptions, Space } from 'antd'; |
8 | 8 | import { useEffect, useRef, useState } from 'react'; |
9 | 9 | |
10 | 10 | export default ({ data, reloadTable }) => { |
11 | - console.log(data, '5656datafirstshowgenjin'); | |
12 | - | |
13 | 11 | // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 |
14 | 12 | const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 |
15 | 13 | |
... | ... | @@ -17,7 +15,8 @@ export default ({ data, reloadTable }) => { |
17 | 15 | const [createByName, setCreateByName] = useState(''); // 跟进人员 |
18 | 16 | const [clientName, setClientName] = useState(''); // 客户名称 |
19 | 17 | // const [clientAddress, setClientAddress] = useState(''); // 客户地址 |
20 | - const [way, setWay] = useState(); // 类型 | |
18 | + const [way, setWay] = useState(); // 跟进方式 | |
19 | + const [tradeStatusText, setTradeStatusText] = useState(); // 状态 | |
21 | 20 | // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 |
22 | 21 | // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 |
23 | 22 | // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 |
... | ... | @@ -26,18 +25,36 @@ export default ({ data, reloadTable }) => { |
26 | 25 | const [createTime, setCreateTime] = useState(null); // 创建时间 |
27 | 26 | const [attachments, setAttachments] = useState(); //附件 |
28 | 27 | const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称 |
29 | - | |
28 | + const [ticketsType, setTicketsType] = useState(''); // 附件名称 | |
29 | + const [ticketsDetail, setTicketsDetail] = useState(''); // 附件名称 | |
30 | + const [ticketsAttachment, setTicketsAttachment] = useState(); // 附件名称 | |
31 | + // const [ticketsAttachmentName, setTicketsAttachmentName] = useState(''); // 附件名称 | |
32 | + const [comment, setComment] = useState(''); // 客户评价 | |
33 | + const [assignPeople, setAssignPeople] = useState(''); // 附件名称 | |
30 | 34 | useEffect(() => { |
31 | 35 | const request = async () => { |
32 | - console.log(data, '5656datasearch'); | |
33 | 36 | const res = await postAdminClientQueryClientComunicationInfo({ |
34 | 37 | data: { |
35 | 38 | id: data.id, |
36 | 39 | }, |
37 | 40 | }); |
38 | - console.log(res, '5656res'); | |
41 | + // const resTicket = await getOrderErpTicketsGetTicketsByClientId({ | |
42 | + // query: { | |
43 | + // id: data.id, | |
44 | + // }, | |
45 | + // }); | |
46 | + // data.type = resTicket.data.type; | |
47 | + // data.detailText = resTicket.data.detailText; | |
48 | + // data.annexUrl = resTicket.data.annexUrl; | |
49 | + // data.assignPeople = resTicket.data.assignPeople; | |
50 | + // console.log(resTicket, '5656resTicket'); | |
39 | 51 | const dataSearch = res.data.data[0]; |
52 | + console.log(dataSearch, '5656dataSearch'); | |
40 | 53 | if (dataSearch) { |
54 | + // data.type = resTicket.data.type; | |
55 | + // data.detailText = resTicket.data.detailText; | |
56 | + // data.annexUrl = resTicket.data.annexUrl; | |
57 | + // data.assignPeople = resTicket.data.assignPeople; | |
41 | 58 | if (dataSearch.attachments) { |
42 | 59 | const url = dataSearch.attachments; |
43 | 60 | const match = url.match(/aliyuncs\.com\/(.*?)\?/); |
... | ... | @@ -50,6 +67,24 @@ export default ({ data, reloadTable }) => { |
50 | 67 | setAttachmentsName(decodedStr); // 设置跟进日期 |
51 | 68 | } |
52 | 69 | } |
70 | + // if (dataSearch.ticketAttachments) { | |
71 | + // const url = dataSearch.attachments; | |
72 | + // const match = url.match(/aliyuncs\.com\/(.*?)\?/); | |
73 | + // let decodedStr = ''; | |
74 | + | |
75 | + // if (match) { | |
76 | + // // 获取匹配的字符串并进行解码 | |
77 | + // const encodedStr = match[1]; | |
78 | + // decodedStr = decodeURIComponent(encodedStr); | |
79 | + // setTicketsAttachmentName(decodedStr); // 设置跟进日期 | |
80 | + // } | |
81 | + // } | |
82 | + setComment(dataSearch.comment); | |
83 | + setTicketsType(dataSearch.ticketsTypeText); | |
84 | + setTicketsDetail(dataSearch.ticketsDetail); | |
85 | + setTicketsAttachment(dataSearch.ticketsAttachments); | |
86 | + setAssignPeople(dataSearch.assignPeople); | |
87 | + setComment(dataSearch.comment); | |
53 | 88 | setDatetime(dataSearch.datetime); // 设置跟进日期 |
54 | 89 | // setDateRange(data.dateRange || []); // 设置跟进时间范围 |
55 | 90 | setCreateByName(dataSearch.createByName); // 设置跟进人员 |
... | ... | @@ -58,13 +93,12 @@ export default ({ data, reloadTable }) => { |
58 | 93 | // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 |
59 | 94 | // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 |
60 | 95 | // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 |
61 | - // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询 | |
96 | + setTradeStatusText(data.tradeStatusLike || ''); // 设置客户状态模糊查询 | |
62 | 97 | setContent(dataSearch.content); // 设置跟进详情 |
63 | 98 | setCreateTime(dataSearch.createTime); // 设置创建时间 |
64 | 99 | setWay(dataSearch.wayText); |
65 | 100 | setAttachments(dataSearch.attachments); |
66 | 101 | } |
67 | - console.log(attachments, '5656attachments'); | |
68 | 102 | }; |
69 | 103 | request(); |
70 | 104 | }, []); |
... | ... | @@ -96,12 +130,41 @@ export default ({ data, reloadTable }) => { |
96 | 130 | }, |
97 | 131 | { |
98 | 132 | key: '6', |
99 | - label: '跟进类型', | |
100 | - children: way, // 跟进类型 | |
133 | + label: '跟进方式', | |
134 | + children: way, // 跟进方式 | |
135 | + }, | |
136 | + { | |
137 | + key: '7', | |
138 | + label: '跟进状态', | |
139 | + children: tradeStatusText, // 跟进状态 | |
140 | + }, | |
141 | + { | |
142 | + key: '8', | |
143 | + label: '工单类型', | |
144 | + children: ticketsType, // 跟进状态 | |
145 | + }, | |
146 | + { | |
147 | + key: '9', | |
148 | + label: '工单详情', | |
149 | + children: ticketsDetail, // 跟进状态 | |
150 | + }, | |
151 | + // { | |
152 | + // key: '12', | |
153 | + // label: '工单附件', | |
154 | + // children: ticketsAttachment, // 跟进状态 | |
155 | + // }, | |
156 | + { | |
157 | + key: '10', | |
158 | + label: '指派人员', | |
159 | + children: assignPeople, // 跟进状态 | |
160 | + }, | |
161 | + { | |
162 | + key: '11', | |
163 | + label: '客户评价', | |
164 | + children: comment, // 跟进状态 | |
101 | 165 | }, |
102 | 166 | ]; |
103 | 167 | const handleDelete = async () => { |
104 | - console.log(JSON.stringify(data), '5656record'); | |
105 | 168 | // 调用删除接口 |
106 | 169 | const success = await postAdminClientRemoveClientComunicationInfo({ |
107 | 170 | query: { |
... | ... | @@ -117,7 +180,7 @@ export default ({ data, reloadTable }) => { |
117 | 180 | <Space> |
118 | 181 | <ModalForm |
119 | 182 | title="跟进记录" |
120 | - trigger={<Button type="link">查看</Button>} | |
183 | + trigger={<Button type="primary">查看</Button>} | |
121 | 184 | submitter={{ |
122 | 185 | resetButtonProps: { |
123 | 186 | style: { |
... | ... | @@ -135,12 +198,14 @@ export default ({ data, reloadTable }) => { |
135 | 198 | <> |
136 | 199 | <ClientModal |
137 | 200 | key={'modify'} |
138 | - data={data} // 将表单数据传递给 ClientModal | |
201 | + // data={data} // 将表单数据传递给 ClientModal | |
202 | + data={{ | |
203 | + data, | |
204 | + }} // 传递修改后的 data | |
139 | 205 | reloadTable={() => { |
140 | 206 | actionRef?.current?.reload(); // 重新加载表格数据 |
141 | 207 | props.submit(); |
142 | 208 | reloadTable(); |
143 | - console.log('5656close'); | |
144 | 209 | }} |
145 | 210 | type={'modify'} |
146 | 211 | onFinish={() => { |
... | ... | @@ -176,11 +241,90 @@ export default ({ data, reloadTable }) => { |
176 | 241 | }} |
177 | 242 | > |
178 | 243 | <Descriptions items={items} column={1} /> |
179 | - {attachmentsName && ( | |
244 | + {/* {attachmentsName && ( | |
180 | 245 | <a href={attachments} download> |
181 | 246 | 附件:{attachmentsName} |
182 | 247 | </a> |
183 | 248 | )} |
249 | + <div></div> | |
250 | + {ticketsAttachment && ( | |
251 | + <a href={ticketsAttachment} download> | |
252 | + 工单附件:{ticketsAttachment} | |
253 | + </a> | |
254 | + )} */} | |
255 | + {attachmentsName && ( | |
256 | + <div> | |
257 | + {attachmentsName.endsWith('.png') || | |
258 | + attachmentsName.endsWith('.jpg') ? ( | |
259 | + <> | |
260 | + <img | |
261 | + src={attachments} | |
262 | + alt={attachmentsName} | |
263 | + style={{ maxWidth: '300px', height: 'auto' }} | |
264 | + /> | |
265 | + <div></div> | |
266 | + <a href={attachments} download> | |
267 | + 附件:{attachmentsName} | |
268 | + </a> | |
269 | + </> | |
270 | + ) : ( | |
271 | + <a href={attachments} download> | |
272 | + 附件:{attachmentsName} | |
273 | + </a> | |
274 | + )} | |
275 | + </div> | |
276 | + )} | |
277 | + | |
278 | + <div></div> | |
279 | + {/* {ticketsAttachment && ( | |
280 | + <a href={ticketsAttachment} download> | |
281 | + 工单附件:{ticketsAttachment} | |
282 | + </a> | |
283 | + )} */} | |
284 | + {/* {ticketsAttachment && ( | |
285 | + <div> | |
286 | + {ticketsAttachment.includes('jpg') || | |
287 | + ticketsAttachment.includes('png') ? ( | |
288 | + <> | |
289 | + <img | |
290 | + src={ticketsAttachment} | |
291 | + alt={ticketsAttachment} | |
292 | + style={{ maxWidth: '300px', height: 'auto' }} | |
293 | + /> | |
294 | + <div></div> | |
295 | + <a href={ticketsAttachment} download> | |
296 | + 工单附件:{ticketsAttachment} | |
297 | + </a> | |
298 | + </> | |
299 | + ) : ( | |
300 | + <a href={ticketsAttachment} download> | |
301 | + 工单附件:{ticketsAttachment} | |
302 | + </a> | |
303 | + )} | |
304 | + </div> | |
305 | + )} */} | |
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 | + )} | |
184 | 328 | </ModalForm> |
185 | 329 | </Space> |
186 | 330 | ); | ... | ... |
src/pages/Client/FollowRecord/Components/style.css
0 → 100644
1 | +.styled-text { | |
2 | + display: flex; | |
3 | + align-items: center; | |
4 | + margin-bottom: 20px; | |
5 | +} | |
6 | + | |
7 | +.vertical-line { | |
8 | + width: 2px; /* 线的宽度 */ | |
9 | + height: 20px; /* 线的高度 */ | |
10 | + background-color: black; /* 线的颜色 */ | |
11 | + margin-right: 10px; /* 线与文本之间的间距 */ | |
12 | +} | |
13 | + | |
14 | +.text { | |
15 | + font-size: 20px; /* 文本大小 */ | |
16 | + font-family: Arial, sans-serif; /* 字体样式 */ | |
17 | + color: black; /* 文本颜色 */ | |
18 | +} | ... | ... |
src/pages/Client/FollowRecord/index.tsx
... | ... | @@ -10,8 +10,9 @@ import { |
10 | 10 | import { enumToSelect } from '@/utils'; |
11 | 11 | import type { ActionType } from '@ant-design/pro-components'; |
12 | 12 | import { ProTable } from '@ant-design/pro-components'; |
13 | -import { Button, Space, message } from 'antd'; | |
13 | +import { Button, Popconfirm, Space, message } from 'antd'; | |
14 | 14 | import { useRef, useState } from 'react'; |
15 | +import ClientModal2 from './Components/ClientModal2'; | |
15 | 16 | |
16 | 17 | export default () => { |
17 | 18 | const actionRef = useRef<ActionType>(); |
... | ... | @@ -19,7 +20,6 @@ export default () => { |
19 | 20 | |
20 | 21 | const reload = () => { |
21 | 22 | actionRef.current.reload(); // 重新加载数据 |
22 | - console.log('5656flush'); | |
23 | 23 | |
24 | 24 | // 更新 refreshKey,强制刷新 CommunicationHistoryModal |
25 | 25 | setRefreshKey((prevKey) => prevKey + 1); |
... | ... | @@ -46,7 +46,7 @@ export default () => { |
46 | 46 | // }, |
47 | 47 | }, |
48 | 48 | { |
49 | - title: '跟进时间', | |
49 | + title: '跟进日期', | |
50 | 50 | dataIndex: 'dateRange', |
51 | 51 | valueType: 'dateRange', |
52 | 52 | hideInTable: true, |
... | ... | @@ -68,6 +68,13 @@ export default () => { |
68 | 68 | ellipsis: true, |
69 | 69 | hideInSearch: false, |
70 | 70 | }, |
71 | + // { | |
72 | + // title: '跟进状态', | |
73 | + // width: 150, | |
74 | + // ellipsis: true, | |
75 | + // dataIndex: 'tradeStatusText', | |
76 | + // hideInSearch: true, | |
77 | + // }, | |
71 | 78 | { |
72 | 79 | title: '客户名称', |
73 | 80 | dataIndex: 'clientName', |
... | ... | @@ -75,22 +82,51 @@ export default () => { |
75 | 82 | ellipsis: true, |
76 | 83 | hideInSearch: true, |
77 | 84 | }, |
85 | + // { | |
86 | + // title: '客户地址', | |
87 | + // dataIndex: 'clientAddress', | |
88 | + // width: 250, | |
89 | + // ellipsis: true, | |
90 | + // hideInSearch: true, | |
91 | + // }, | |
78 | 92 | { |
79 | - title: '客户地址', | |
80 | - dataIndex: 'clientAddress', | |
81 | - width: 250, | |
93 | + title: '联系人', | |
94 | + dataIndex: 'contact', | |
95 | + width: 150, | |
96 | + ellipsis: true, | |
97 | + hideInSearch: false, | |
98 | + }, | |
99 | + // { | |
100 | + // title: '联系人', | |
101 | + // dataIndex: 'contactLike', | |
102 | + // width: 150, | |
103 | + // ellipsis: true, | |
104 | + // hideInSearch: false, | |
105 | + // hideInTable: true, | |
106 | + // }, | |
107 | + { | |
108 | + title: '联系电话', | |
109 | + dataIndex: 'contactPhone', | |
110 | + width: 150, | |
111 | + ellipsis: true, | |
112 | + hideInSearch: true, | |
113 | + }, | |
114 | + { | |
115 | + title: '跟进状态', | |
116 | + dataIndex: 'tradeStatusLike', | |
117 | + width: 100, | |
82 | 118 | ellipsis: true, |
83 | 119 | hideInSearch: true, |
84 | 120 | }, |
85 | 121 | { |
86 | - title: '跟进类型', | |
122 | + title: '跟进方式', | |
87 | 123 | dataIndex: 'wayText', |
88 | 124 | width: 100, |
89 | 125 | ellipsis: true, |
90 | 126 | hideInSearch: true, |
91 | 127 | }, |
92 | 128 | { |
93 | - title: '跟进类型', | |
129 | + title: '跟进方式', | |
94 | 130 | dataIndex: 'way', |
95 | 131 | width: 100, |
96 | 132 | ellipsis: true, |
... | ... | @@ -101,6 +137,16 @@ export default () => { |
101 | 137 | return enumToSelect(res.data); |
102 | 138 | }, |
103 | 139 | }, |
140 | + // { | |
141 | + // title: '跟进状态', | |
142 | + // dataIndex: 'tradeStatus', | |
143 | + // valueType: 'select', | |
144 | + // hideInTable: true, | |
145 | + // request: async () => { | |
146 | + // const res = await postServiceConstTradeStatus(); | |
147 | + // return enumToSelect(res.data); | |
148 | + // }, | |
149 | + // }, | |
104 | 150 | { |
105 | 151 | title: '客户名称', |
106 | 152 | dataIndex: 'clientNameLike', |
... | ... | @@ -109,26 +155,26 @@ export default () => { |
109 | 155 | hideInSearch: false, |
110 | 156 | hideInTable: true, |
111 | 157 | }, |
158 | + // { | |
159 | + // title: '客户地址', | |
160 | + // dataIndex: 'clientAddressLike', | |
161 | + // width: 250, | |
162 | + // ellipsis: true, | |
163 | + // hideInSearch: false, | |
164 | + // hideInTable: true, | |
165 | + // }, | |
166 | + // { | |
167 | + // title: '跟进状态', | |
168 | + // dataIndex: 'tradeStatus', | |
169 | + // width: 100, | |
170 | + // ellipsis: true, | |
171 | + // hideInSearch: true, | |
172 | + // }, | |
112 | 173 | { |
113 | - title: '客户地址', | |
114 | - dataIndex: 'clientAddressLike', | |
115 | - width: 250, | |
116 | - ellipsis: true, | |
117 | - hideInSearch: false, | |
118 | - hideInTable: true, | |
119 | - }, | |
120 | - { | |
121 | - title: '客户状态', | |
174 | + title: '跟进状态', | |
122 | 175 | dataIndex: 'tradeStatus', |
123 | 176 | width: 100, |
124 | 177 | ellipsis: true, |
125 | - hideInSearch: true, | |
126 | - }, | |
127 | - { | |
128 | - title: '客户状态', | |
129 | - dataIndex: 'tradeStatusLike', | |
130 | - width: 100, | |
131 | - ellipsis: true, | |
132 | 178 | hideInSearch: false, |
133 | 179 | hideInTable: true, |
134 | 180 | request: async () => { |
... | ... | @@ -141,7 +187,7 @@ export default () => { |
141 | 187 | dataIndex: 'content', |
142 | 188 | width: 250, |
143 | 189 | ellipsis: true, |
144 | - hideInSearch: false, | |
190 | + hideInSearch: true, | |
145 | 191 | }, |
146 | 192 | { |
147 | 193 | title: '创建时间', |
... | ... | @@ -159,10 +205,26 @@ export default () => { |
159 | 205 | hideInTable: true, |
160 | 206 | }, |
161 | 207 | { |
208 | + title: '创建日期', | |
209 | + dataIndex: 'createTime', | |
210 | + valueType: 'dateRange', | |
211 | + hideInTable: true, | |
212 | + search: { | |
213 | + transform: (value) => { | |
214 | + if (value) { | |
215 | + return { | |
216 | + createTimeGe: value[0], | |
217 | + createTimeLe: value[1], | |
218 | + }; | |
219 | + } | |
220 | + }, | |
221 | + }, | |
222 | + }, | |
223 | + { | |
162 | 224 | title: '操作', |
163 | 225 | valueType: 'option', |
164 | 226 | key: 'option', |
165 | - width: 150, | |
227 | + width: 220, | |
166 | 228 | render: (text, record, index, action) => { |
167 | 229 | const handleDelete = async () => { |
168 | 230 | // console.log(JSON.stringify(record), '5656record'); |
... | ... | @@ -187,8 +249,22 @@ export default () => { |
187 | 249 | // }} |
188 | 250 | reloadTable={reload} |
189 | 251 | />, |
252 | + <ClientModal2 | |
253 | + key={'modify'} | |
254 | + // data={data} // 将表单数据传递给 ClientModal | |
255 | + data={record} // 传递修改后的 data | |
256 | + reloadTable={() => { | |
257 | + actionRef?.current?.reload(); // 重新加载表格数据 | |
258 | + // props.submit(); | |
259 | + }} | |
260 | + type={'modify'} | |
261 | + onFinish={() => { | |
262 | + // setIsModalVisible(false); | |
263 | + }} // 关闭 Modal | |
264 | + style={{ marginRight: '10px' }} | |
265 | + />, | |
190 | 266 | <> |
191 | - <Button | |
267 | + {/* <Button | |
192 | 268 | key={'delete'} |
193 | 269 | onClick={() => { |
194 | 270 | handleDelete(); |
... | ... | @@ -197,15 +273,42 @@ export default () => { |
197 | 273 | // reloadTable={() => { |
198 | 274 | // actionRef.current.reload(); |
199 | 275 | // }} |
200 | - type="link" | |
276 | + type="primary" | |
201 | 277 | size="middle" |
202 | - // 使用 danger 属性来将按钮颜色设置为红色 | |
203 | - // onFinish={() => { | |
204 | - // actionRef.current.reload(); | |
205 | - // }} | |
278 | + danger | |
279 | + // 使用 danger 属性来将按钮颜色设置为红色 | |
280 | + // onFinish={() => { | |
281 | + // actionRef.current.reload(); | |
282 | + // }} | |
206 | 283 | > |
207 | 284 | 删除 |
208 | 285 | </Button> |
286 | + <ButtonConfirm | |
287 | + key={'delete'} | |
288 | + className="p-0" | |
289 | + title={'是否确认删除'} | |
290 | + text="删除" | |
291 | + type="primary" | |
292 | + size="middle" | |
293 | + danger | |
294 | + onConfirm={async () => { | |
295 | + handleDelete(); | |
296 | + actionRef.current.reload(); | |
297 | + }} | |
298 | + /> */} | |
299 | + <Popconfirm | |
300 | + title={'是否确认删除'} | |
301 | + onConfirm={async () => { | |
302 | + handleDelete(); | |
303 | + actionRef.current.reload(); | |
304 | + }} | |
305 | + okText="确认" | |
306 | + cancelText="取消" | |
307 | + > | |
308 | + <Button key={'delete'} type="primary" size="middle" danger> | |
309 | + 删除 | |
310 | + </Button> | |
311 | + </Popconfirm> | |
209 | 312 | </>, |
210 | 313 | ]; |
211 | 314 | }, |
... | ... | @@ -236,7 +339,6 @@ export default () => { |
236 | 339 | ...params, |
237 | 340 | }, |
238 | 341 | }); |
239 | - console.log(params, '5656566params'); | |
240 | 342 | if (res.result === RESPONSE_CODE.SUCCESS) { |
241 | 343 | console.log(JSON.stringify(res.data)); |
242 | 344 | return { | ... | ... |
src/tsg.config.ts
... | ... | @@ -33,8 +33,8 @@ const projects: Project[] = [ |
33 | 33 | * openapi 文档地址,可以是远程的json文件,也可以是本地的json文件 |
34 | 34 | * 如果使用本地文件,相对路径以当前'tsg.config.ts'为基准 |
35 | 35 | * */ |
36 | - // source: 'http://localhost:8085/v2/api-docs', | |
37 | - source: 'http://39.108.227.113:8085/v2/api-docs', | |
36 | + source: 'http://localhost:8085/v2/api-docs', | |
37 | + //source: 'http://39.108.227.113:8085/v2/api-docs', | |
38 | 38 | |
39 | 39 | // source: 'https://petstore3.swagger.io/api/v3/openapi.json', |
40 | 40 | // source: './fixture/pet.json', | ... | ... |