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,15 +5,14 @@ import { | ||
5 | postDistrictSelectByLevel, | 5 | postDistrictSelectByLevel, |
6 | postDistrictSelectByNameAndLevel, | 6 | postDistrictSelectByNameAndLevel, |
7 | postDistrictSelOrderProvince, | 7 | postDistrictSelOrderProvince, |
8 | + postResearchGroupsNameSet, | ||
8 | postServiceConstClientLevels, | 9 | postServiceConstClientLevels, |
9 | postServiceConstClientSource, | 10 | postServiceConstClientSource, |
10 | - postServiceConstTradeStatus, | ||
11 | } from '@/services'; | 11 | } from '@/services'; |
12 | 12 | ||
13 | import { enumToSelect } from '@/utils'; | 13 | import { enumToSelect } from '@/utils'; |
14 | import { | 14 | import { |
15 | DrawerForm, | 15 | DrawerForm, |
16 | - ProFormDatePicker, | ||
17 | ProFormSelect, | 16 | ProFormSelect, |
18 | ProFormText, | 17 | ProFormText, |
19 | } from '@ant-design/pro-components'; | 18 | } from '@ant-design/pro-components'; |
@@ -23,17 +22,10 @@ import { useState } from 'react'; | @@ -23,17 +22,10 @@ import { useState } from 'react'; | ||
23 | 22 | ||
24 | export default ({ optType, record, onFinish }) => { | 23 | export default ({ optType, record, onFinish }) => { |
25 | const [form] = Form.useForm(); | 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 | const [province, setProvince] = useState(''); | 26 | const [province, setProvince] = useState(''); |
34 | const [city, setCity] = useState(''); | 27 | const [city, setCity] = useState(''); |
35 | const [showReferrers, setShowReferrers] = useState(false); // 控制显示的状态,初始为false | 28 | const [showReferrers, setShowReferrers] = useState(false); // 控制显示的状态,初始为false |
36 | - const [showQuoteDatetime, setShowQuoteDatetime] = useState(false); // 控制显示的状态,初始为false | ||
37 | const optTypeEnum = { | 29 | const optTypeEnum = { |
38 | add: { | 30 | add: { |
39 | text: '新增', | 31 | text: '新增', |
@@ -82,15 +74,6 @@ export default ({ optType, record, onFinish }) => { | @@ -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 | // MODIFIED: 增加处理非 JSON 格式字符串的逻辑 | 78 | // MODIFIED: 增加处理非 JSON 格式字符串的逻辑 |
96 | const parsedRecord = record | 79 | const parsedRecord = record |
@@ -314,13 +297,13 @@ export default ({ optType, record, onFinish }) => { | @@ -314,13 +297,13 @@ export default ({ optType, record, onFinish }) => { | ||
314 | ]} | 297 | ]} |
315 | /> | 298 | /> |
316 | <ProFormText | 299 | <ProFormText |
317 | - name="contacts" | ||
318 | - label="联系人" | ||
319 | - placeholder="请输入联系人" | 300 | + name="leaderName" |
301 | + label="负责人" | ||
302 | + placeholder="请输入负责人" | ||
320 | rules={[ | 303 | rules={[ |
321 | { | 304 | { |
322 | required: true, | 305 | required: true, |
323 | - message: '请输入联系人', | 306 | + message: '请输入负责人', |
324 | }, | 307 | }, |
325 | ]} | 308 | ]} |
326 | /> | 309 | /> |
@@ -336,6 +319,60 @@ export default ({ optType, record, onFinish }) => { | @@ -336,6 +319,60 @@ export default ({ optType, record, onFinish }) => { | ||
336 | ]} | 319 | ]} |
337 | /> | 320 | /> |
338 | <ProFormSelect | 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 | name="source" | 376 | name="source" |
340 | label="客户来源" | 377 | label="客户来源" |
341 | placeholder="请选择客户来源" | 378 | placeholder="请选择客户来源" |
@@ -360,7 +397,7 @@ export default ({ optType, record, onFinish }) => { | @@ -360,7 +397,7 @@ export default ({ optType, record, onFinish }) => { | ||
360 | placeholder="请输入推荐人" | 397 | placeholder="请输入推荐人" |
361 | /> | 398 | /> |
362 | )} | 399 | )} |
363 | - <ProFormSelect | 400 | + {/* <ProFormSelect |
364 | name="requirements" | 401 | name="requirements" |
365 | label="客户需求" | 402 | label="客户需求" |
366 | placeholder="请输入客户需求" | 403 | placeholder="请输入客户需求" |
@@ -380,38 +417,7 @@ export default ({ optType, record, onFinish }) => { | @@ -380,38 +417,7 @@ export default ({ optType, record, onFinish }) => { | ||
380 | // console.log(res.data, '5656require'); | 417 | // console.log(res.data, '5656require'); |
381 | // return enumToSelect(res.data); | 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 | <ProFormSelect | 421 | <ProFormSelect |
416 | name="level" | 422 | name="level" |
417 | label="客户等级" | 423 | label="客户等级" |
@@ -437,21 +443,6 @@ export default ({ optType, record, onFinish }) => { | @@ -437,21 +443,6 @@ export default ({ optType, record, onFinish }) => { | ||
437 | return enumToSelectLevel(res.data); | 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 | <ProFormText name="notes" label="备注" placeholder="请输入备注" /> | 446 | <ProFormText name="notes" label="备注" placeholder="请输入备注" /> |
456 | </DrawerForm> | 447 | </DrawerForm> |
457 | ); | 448 | ); |
src/pages/Client/Client/Components/ClientInformationModal.tsx
1 | import { RESPONSE_CODE } from '@/constants/enum'; | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | ||
2 | import { | 3 | import { |
3 | postAdminClientAddOrModifyClientComunicationInfo, | 4 | postAdminClientAddOrModifyClientComunicationInfo, |
4 | postAdminClientQueryClientPage, | 5 | postAdminClientQueryClientPage, |
5 | postOrderErpOrderStagesUpload, | 6 | postOrderErpOrderStagesUpload, |
7 | + postOrderErpUsersListByPage, | ||
6 | postServiceConstClientWay, | 8 | postServiceConstClientWay, |
9 | + postServiceConstTradeStatus, | ||
7 | } from '@/services'; | 10 | } from '@/services'; |
8 | import { enumToSelect } from '@/utils'; | 11 | import { enumToSelect } from '@/utils'; |
9 | import { | 12 | import { |
@@ -14,8 +17,9 @@ import { | @@ -14,8 +17,9 @@ import { | ||
14 | ProFormTextArea, | 17 | ProFormTextArea, |
15 | ProFormUploadDragger, | 18 | ProFormUploadDragger, |
16 | } from '@ant-design/pro-components'; | 19 | } from '@ant-design/pro-components'; |
17 | -import { Button, Form, message } from 'antd'; | 20 | +import { Button, Col, Form, Row, message } from 'antd'; |
18 | import { RcFile } from 'antd/es/upload'; | 21 | import { RcFile } from 'antd/es/upload'; |
22 | +import './style.css'; | ||
19 | export default ({ data, type, reloadTable }) => { | 23 | export default ({ data, type, reloadTable }) => { |
20 | const [form] = Form.useForm(); | 24 | const [form] = Form.useForm(); |
21 | const onfinish = async (values) => { | 25 | const onfinish = async (values) => { |
@@ -64,6 +68,12 @@ export default ({ data, type, reloadTable }) => { | @@ -64,6 +68,12 @@ export default ({ data, type, reloadTable }) => { | ||
64 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ | 68 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
65 | data: { | 69 | data: { |
66 | ...values, | 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 | if (res.result === RESPONSE_CODE.SUCCESS) { | 79 | if (res.result === RESPONSE_CODE.SUCCESS) { |
@@ -165,9 +175,37 @@ export default ({ data, type, reloadTable }) => { | @@ -165,9 +175,37 @@ export default ({ data, type, reloadTable }) => { | ||
165 | }, | 175 | }, |
166 | ]} | 176 | ]} |
167 | ></ProFormSelect> | 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 | <ProFormDateTimePicker | 206 | <ProFormDateTimePicker |
169 | name="datetime" | 207 | name="datetime" |
170 | - label="日期" | 208 | + label="跟进日期" |
171 | initialValue={data ? data?.datetime + '' : null} | 209 | initialValue={data ? data?.datetime + '' : null} |
172 | placeholder="请选择跟进时间" | 210 | placeholder="请选择跟进时间" |
173 | width="sm" | 211 | width="sm" |
@@ -179,6 +217,27 @@ export default ({ data, type, reloadTable }) => { | @@ -179,6 +217,27 @@ export default ({ data, type, reloadTable }) => { | ||
179 | ]} | 217 | ]} |
180 | /> | 218 | /> |
181 | <ProFormSelect | 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 | name="way" | 241 | name="way" |
183 | width="sm" | 242 | width="sm" |
184 | readonly={optType[type].readOnly} | 243 | readonly={optType[type].readOnly} |
@@ -186,7 +245,7 @@ export default ({ data, type, reloadTable }) => { | @@ -186,7 +245,7 @@ export default ({ data, type, reloadTable }) => { | ||
186 | labelInValue: false, | 245 | labelInValue: false, |
187 | }} | 246 | }} |
188 | initialValue={data?.way ? data?.way + '' : null} | 247 | initialValue={data?.way ? data?.way + '' : null} |
189 | - label="类型" | 248 | + label="跟进方式" |
190 | request={async () => { | 249 | request={async () => { |
191 | const res = await postServiceConstClientWay(); | 250 | const res = await postServiceConstClientWay(); |
192 | return enumToSelect(res.data); | 251 | return enumToSelect(res.data); |
@@ -194,7 +253,7 @@ export default ({ data, type, reloadTable }) => { | @@ -194,7 +253,7 @@ export default ({ data, type, reloadTable }) => { | ||
194 | rules={[ | 253 | rules={[ |
195 | { | 254 | { |
196 | required: true, | 255 | required: true, |
197 | - message: '请选择跟进类型', | 256 | + message: '请选择跟进方式', |
198 | }, | 257 | }, |
199 | ]} | 258 | ]} |
200 | ></ProFormSelect> | 259 | ></ProFormSelect> |
@@ -242,12 +301,138 @@ export default ({ data, type, reloadTable }) => { | @@ -242,12 +301,138 @@ export default ({ data, type, reloadTable }) => { | ||
242 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> | 301 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> |
243 | 下载附件 | 302 | 下载附件 |
244 | </a> | 303 | </a> |
304 | + <ProFormTextArea | ||
305 | + name="comment" | ||
306 | + label="客户评价" | ||
307 | + placeholder="请输入客户评价" | ||
308 | + initialValue={data?.comment} | ||
309 | + readonly={optType[type].readOnly} | ||
310 | + ></ProFormTextArea> | ||
245 | <ProFormText | 311 | <ProFormText |
246 | initialValue={data?.attachments} | 312 | initialValue={data?.attachments} |
247 | name="attachments" | 313 | name="attachments" |
248 | hidden | 314 | hidden |
249 | ></ProFormText> | 315 | ></ProFormText> |
250 | <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | 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 | </ModalForm> | 436 | </ModalForm> |
252 | ); | 437 | ); |
253 | }; | 438 | }; |
src/pages/Client/Client/Components/ClientModal.tsx
1 | import { RESPONSE_CODE } from '@/constants/enum'; | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | ||
2 | import { | 3 | import { |
3 | postAdminClientAddOrModifyClientComunicationInfo, | 4 | postAdminClientAddOrModifyClientComunicationInfo, |
4 | postAdminClientQueryClientPage, | 5 | postAdminClientQueryClientPage, |
5 | postOrderErpOrderStagesUpload, | 6 | postOrderErpOrderStagesUpload, |
7 | + postOrderErpUsersListByPage, | ||
6 | postServiceConstClientWay, | 8 | postServiceConstClientWay, |
9 | + postServiceConstTradeStatus, | ||
7 | } from '@/services'; | 10 | } from '@/services'; |
8 | import { enumToSelect } from '@/utils'; | 11 | import { enumToSelect } from '@/utils'; |
9 | import { | 12 | import { |
@@ -14,13 +17,12 @@ import { | @@ -14,13 +17,12 @@ import { | ||
14 | ProFormTextArea, | 17 | ProFormTextArea, |
15 | ProFormUploadDragger, | 18 | ProFormUploadDragger, |
16 | } from '@ant-design/pro-components'; | 19 | } from '@ant-design/pro-components'; |
17 | -import { Button, Form, message } from 'antd'; | 20 | +import { Button, Col, Form, Row, message } from 'antd'; |
18 | import { RcFile } from 'antd/es/upload'; | 21 | import { RcFile } from 'antd/es/upload'; |
22 | +import './style.css'; | ||
19 | export default ({ data, type, reloadTable }) => { | 23 | export default ({ data, type, reloadTable }) => { |
20 | const [form] = Form.useForm(); | 24 | const [form] = Form.useForm(); |
21 | const onfinish = async (values) => { | 25 | const onfinish = async (values) => { |
22 | - console.log(data, '5656datatest'); | ||
23 | - console.log(values, '5656...values'); | ||
24 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ | 26 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
25 | data: { | 27 | data: { |
26 | ...values, | 28 | ...values, |
@@ -111,7 +113,6 @@ export default ({ data, type, reloadTable }) => { | @@ -111,7 +113,6 @@ export default ({ data, type, reloadTable }) => { | ||
111 | groupFilter: 'all', | 113 | groupFilter: 'all', |
112 | }, | 114 | }, |
113 | }); | 115 | }); |
114 | - console.log(data?.datetime, '5656data?.datetime'); | ||
115 | const namesArray = res.data.data.map((item) => item.name); | 116 | const namesArray = res.data.data.map((item) => item.name); |
116 | return enumToSelect(namesArray); | 117 | return enumToSelect(namesArray); |
117 | }} | 118 | }} |
@@ -123,9 +124,37 @@ export default ({ data, type, reloadTable }) => { | @@ -123,9 +124,37 @@ export default ({ data, type, reloadTable }) => { | ||
123 | ]} | 124 | ]} |
124 | disabled | 125 | disabled |
125 | ></ProFormSelect> | 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 | <ProFormDateTimePicker | 155 | <ProFormDateTimePicker |
127 | name="datetime" | 156 | name="datetime" |
128 | - label="日期" | 157 | + label="跟进日期" |
129 | initialValue={data.datetime ? data?.datetime + '' : null} | 158 | initialValue={data.datetime ? data?.datetime + '' : null} |
130 | placeholder="请选择跟进时间" | 159 | placeholder="请选择跟进时间" |
131 | width="sm" | 160 | width="sm" |
@@ -137,6 +166,27 @@ export default ({ data, type, reloadTable }) => { | @@ -137,6 +166,27 @@ export default ({ data, type, reloadTable }) => { | ||
137 | ]} | 166 | ]} |
138 | /> | 167 | /> |
139 | <ProFormSelect | 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 | name="way" | 190 | name="way" |
141 | width="sm" | 191 | width="sm" |
142 | readonly={optType[type].readOnly} | 192 | readonly={optType[type].readOnly} |
@@ -200,12 +250,138 @@ export default ({ data, type, reloadTable }) => { | @@ -200,12 +250,138 @@ export default ({ data, type, reloadTable }) => { | ||
200 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> | 250 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> |
201 | 下载附件 | 251 | 下载附件 |
202 | </a> | 252 | </a> |
253 | + <ProFormTextArea | ||
254 | + name="comment" | ||
255 | + label="客户评价" | ||
256 | + placeholder="请输入客户评价" | ||
257 | + initialValue={data?.comment} | ||
258 | + readonly={optType[type].readOnly} | ||
259 | + ></ProFormTextArea> | ||
203 | <ProFormText | 260 | <ProFormText |
204 | initialValue={data?.attachments} | 261 | initialValue={data?.attachments} |
205 | name="attachments" | 262 | name="attachments" |
206 | hidden | 263 | hidden |
207 | ></ProFormText> | 264 | ></ProFormText> |
208 | <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | 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 | </ModalForm> | 385 | </ModalForm> |
210 | ); | 386 | ); |
211 | }; | 387 | }; |
src/pages/Client/Client/Components/CommunicationHistoryModal.tsx
@@ -4,6 +4,7 @@ import { | @@ -4,6 +4,7 @@ import { | ||
4 | postAdminClientQueryClientComunicationInfo, | 4 | postAdminClientQueryClientComunicationInfo, |
5 | postAdminClientRemoveClientComunicationInfo, | 5 | postAdminClientRemoveClientComunicationInfo, |
6 | postServiceConstClientWay, | 6 | postServiceConstClientWay, |
7 | + postServiceConstTradeStatus, | ||
7 | } from '@/services'; | 8 | } from '@/services'; |
8 | import { enumToSelect } from '@/utils'; | 9 | import { enumToSelect } from '@/utils'; |
9 | import { | 10 | import { |
@@ -25,7 +26,6 @@ export default ({ record }) => { | @@ -25,7 +26,6 @@ export default ({ record }) => { | ||
25 | 26 | ||
26 | const reloadInformationHistoryModal = () => { | 27 | const reloadInformationHistoryModal = () => { |
27 | actionRef.current.reload(); // 重新加载数据 | 28 | actionRef.current.reload(); // 重新加载数据 |
28 | - console.log('5656flush'); | ||
29 | 29 | ||
30 | // 更新 refreshKey,强制刷新 CommunicationHistoryModal | 30 | // 更新 refreshKey,强制刷新 CommunicationHistoryModal |
31 | setRefreshKey((prevKey) => prevKey + 1); | 31 | setRefreshKey((prevKey) => prevKey + 1); |
@@ -56,8 +56,19 @@ export default ({ record }) => { | @@ -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 | valueType: 'textarea', | 72 | valueType: 'textarea', |
62 | rules: [{ required: true, message: '请输入内容' }], | 73 | rules: [{ required: true, message: '请输入内容' }], |
63 | dataIndex: 'content', | 74 | dataIndex: 'content', |
@@ -65,7 +76,7 @@ export default ({ record }) => { | @@ -65,7 +76,7 @@ export default ({ record }) => { | ||
65 | { | 76 | { |
66 | title: '操作', | 77 | title: '操作', |
67 | valueType: 'option', | 78 | valueType: 'option', |
68 | - width: 50, | 79 | + width: 60, |
69 | render: (text, record, _, action) => [ | 80 | render: (text, record, _, action) => [ |
70 | // <a | 81 | // <a |
71 | // key="editable" | 82 | // key="editable" |
@@ -112,14 +123,13 @@ export default ({ record }) => { | @@ -112,14 +123,13 @@ export default ({ record }) => { | ||
112 | }, | 123 | }, |
113 | ]; | 124 | ]; |
114 | const [name, setName] = useState(''); // 客户名称 | 125 | const [name, setName] = useState(''); // 客户名称 |
115 | - const [contacts, setContacts] = useState(''); // 联系人 | 126 | + const [leaderName, setLeaderName] = useState(''); // 负责人 |
116 | const [sourceText, setSourceText] = useState(''); // 来源文本 | 127 | const [sourceText, setSourceText] = useState(''); // 来源文本 |
117 | const [phoneNumber, setPhoneNumber] = useState(''); // 联系电话 | 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 | const [referrers, setReferrers] = useState(''); // 推荐人 | 132 | const [referrers, setReferrers] = useState(''); // 推荐人 |
121 | - const [requirementsText, setRequirementsText] = useState(''); // 需求文本 | ||
122 | - const [tradeStatusText, setTradeStatusText] = useState(''); // 跟进状态文本 | ||
123 | const [levelText, setLevelText] = useState(''); // 客户等级文本 | 133 | const [levelText, setLevelText] = useState(''); // 客户等级文本 |
124 | const [createTime, setCreateTime] = useState(null); // 最新沟通时间 | 134 | const [createTime, setCreateTime] = useState(null); // 最新沟通时间 |
125 | const [address, setAddress] = useState(''); // 客户地址 | 135 | const [address, setAddress] = useState(''); // 客户地址 |
@@ -152,14 +162,13 @@ export default ({ record }) => { | @@ -152,14 +162,13 @@ export default ({ record }) => { | ||
152 | } | 162 | } |
153 | setRecordSave(record); | 163 | setRecordSave(record); |
154 | setName(record.name); | 164 | setName(record.name); |
155 | - setContacts(record.contacts); | 165 | + setLeaderName(record.leaderName); |
156 | setSourceText(record.sourceText); | 166 | setSourceText(record.sourceText); |
157 | setPhoneNumber(record.phoneNumber); | 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 | setReferrers(record.referrers); | 171 | setReferrers(record.referrers); |
161 | - setRequirementsText(record.requirementsText); | ||
162 | - setTradeStatusText(record.tradeStatusText); | ||
163 | setLevelText(record.levelText); | 172 | setLevelText(record.levelText); |
164 | setCreateTime(record.createTime); | 173 | setCreateTime(record.createTime); |
165 | setAddress(record.address); | 174 | setAddress(record.address); |
@@ -176,8 +185,8 @@ export default ({ record }) => { | @@ -176,8 +185,8 @@ export default ({ record }) => { | ||
176 | }, | 185 | }, |
177 | { | 186 | { |
178 | key: '2', | 187 | key: '2', |
179 | - label: '联系人', | ||
180 | - children: contacts, // 联系人 | 188 | + label: '负责人', |
189 | + children: leaderName, // 负责人 | ||
181 | }, | 190 | }, |
182 | { | 191 | { |
183 | key: '3', | 192 | key: '3', |
@@ -191,28 +200,23 @@ export default ({ record }) => { | @@ -191,28 +200,23 @@ export default ({ record }) => { | ||
191 | }, | 200 | }, |
192 | { | 201 | { |
193 | key: '5', | 202 | key: '5', |
194 | - label: '是否已报方案', | ||
195 | - children: hasSchemeText, // 报方案状态文本 | 203 | + label: '课题组', |
204 | + children: institutionContactName, // 推荐人 | ||
196 | }, | 205 | }, |
197 | { | 206 | { |
198 | key: '6', | 207 | key: '6', |
199 | - label: '报价时间', | ||
200 | - children: quoteDatetime, // 报价时间 | 208 | + label: '部门', |
209 | + children: department, // 推荐人 | ||
201 | }, | 210 | }, |
202 | { | 211 | { |
203 | key: '7', | 212 | key: '7', |
204 | - label: '推荐人', | ||
205 | - children: referrers, // 推荐人 | 213 | + label: '年级/职位', |
214 | + children: gradePosition, // 推荐人 | ||
206 | }, | 215 | }, |
207 | { | 216 | { |
208 | key: '8', | 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 | key: '10', | 222 | key: '10', |
@@ -265,7 +269,6 @@ export default ({ record }) => { | @@ -265,7 +269,6 @@ export default ({ record }) => { | ||
265 | }} | 269 | }} |
266 | type={'add2'} | 270 | type={'add2'} |
267 | /> | 271 | /> |
268 | - , | ||
269 | <EditableProTable | 272 | <EditableProTable |
270 | rowKey="tid" | 273 | rowKey="tid" |
271 | formRef={ref} | 274 | formRef={ref} |
src/pages/Client/Client/Components/InformationHistoryModal.tsx
@@ -10,8 +10,6 @@ import { Button, Descriptions, Space } from 'antd'; | @@ -10,8 +10,6 @@ import { Button, Descriptions, Space } from 'antd'; | ||
10 | import { useEffect, useRef, useState } from 'react'; | 10 | import { useEffect, useRef, useState } from 'react'; |
11 | 11 | ||
12 | export default ({ data, reloadTable }) => { | 12 | export default ({ data, reloadTable }) => { |
13 | - console.log(data, '5656datafirstshowclient'); | ||
14 | - | ||
15 | // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 | 13 | // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 |
16 | const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 | 14 | const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 |
17 | 15 | ||
@@ -23,22 +21,26 @@ export default ({ data, reloadTable }) => { | @@ -23,22 +21,26 @@ export default ({ data, reloadTable }) => { | ||
23 | // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 | 21 | // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 |
24 | // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 | 22 | // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 |
25 | // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 | 23 | // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 |
26 | - // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询 | 24 | + const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询 |
27 | const [content, setContent] = useState(''); // 跟进详情 | 25 | const [content, setContent] = useState(''); // 跟进详情 |
28 | const [createTime, setCreateTime] = useState(null); // 创建时间 | 26 | const [createTime, setCreateTime] = useState(null); // 创建时间 |
29 | const [attachments, setAttachments] = useState(); //附件 | 27 | const [attachments, setAttachments] = useState(); //附件 |
30 | const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称 | 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 | useEffect(() => { | 35 | useEffect(() => { |
33 | const request = async () => { | 36 | const request = async () => { |
34 | - console.log(data, '5656datasearch'); | ||
35 | const res = await postAdminClientQueryClientComunicationInfo({ | 37 | const res = await postAdminClientQueryClientComunicationInfo({ |
36 | data: { | 38 | data: { |
37 | id: data.id, | 39 | id: data.id, |
38 | }, | 40 | }, |
39 | }); | 41 | }); |
40 | - console.log(res, '5656res'); | ||
41 | const dataSearch = res.data.data[0]; | 42 | const dataSearch = res.data.data[0]; |
43 | + | ||
42 | if (dataSearch) { | 44 | if (dataSearch) { |
43 | if (dataSearch.attachments) { | 45 | if (dataSearch.attachments) { |
44 | const url = dataSearch.attachments; | 46 | const url = dataSearch.attachments; |
@@ -52,6 +54,11 @@ export default ({ data, reloadTable }) => { | @@ -52,6 +54,11 @@ export default ({ data, reloadTable }) => { | ||
52 | setAttachmentsName(decodedStr); // 设置跟进日期 | 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 | setDatetime(dataSearch.datetime); // 设置跟进日期 | 62 | setDatetime(dataSearch.datetime); // 设置跟进日期 |
56 | // setDateRange(data.dateRange || []); // 设置跟进时间范围 | 63 | // setDateRange(data.dateRange || []); // 设置跟进时间范围 |
57 | setCreateByName(dataSearch.createByName); // 设置跟进人员 | 64 | setCreateByName(dataSearch.createByName); // 设置跟进人员 |
@@ -60,13 +67,12 @@ export default ({ data, reloadTable }) => { | @@ -60,13 +67,12 @@ export default ({ data, reloadTable }) => { | ||
60 | // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 | 67 | // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 |
61 | // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 | 68 | // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 |
62 | // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 | 69 | // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 |
63 | - // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询 | 70 | + setTradeStatusLike(data.tradeStatusLike); // 设置客户状态模糊查询 |
64 | setContent(dataSearch.content); // 设置跟进详情 | 71 | setContent(dataSearch.content); // 设置跟进详情 |
65 | setCreateTime(dataSearch.createTime); // 设置创建时间 | 72 | setCreateTime(dataSearch.createTime); // 设置创建时间 |
66 | setWay(dataSearch.wayText); | 73 | setWay(dataSearch.wayText); |
67 | setAttachments(dataSearch.attachments); | 74 | setAttachments(dataSearch.attachments); |
68 | } | 75 | } |
69 | - console.log(attachments, '5656attachments'); | ||
70 | }; | 76 | }; |
71 | request(); | 77 | request(); |
72 | }, []); | 78 | }, []); |
@@ -101,9 +107,38 @@ export default ({ data, reloadTable }) => { | @@ -101,9 +107,38 @@ export default ({ data, reloadTable }) => { | ||
101 | label: '跟进类型', | 107 | label: '跟进类型', |
102 | children: way, // 跟进类型 | 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 | const handleDelete = async () => { | 141 | const handleDelete = async () => { |
106 | - console.log(JSON.stringify(data), '5656record'); | ||
107 | // 调用删除接口 | 142 | // 调用删除接口 |
108 | const success = await postAdminClientRemoveClientComunicationInfo({ | 143 | const success = await postAdminClientRemoveClientComunicationInfo({ |
109 | query: { | 144 | query: { |
@@ -142,7 +177,6 @@ export default ({ data, reloadTable }) => { | @@ -142,7 +177,6 @@ export default ({ data, reloadTable }) => { | ||
142 | actionRef?.current?.reload(); // 重新加载表格数据 | 177 | actionRef?.current?.reload(); // 重新加载表格数据 |
143 | props.submit(); | 178 | props.submit(); |
144 | reloadTable(); | 179 | reloadTable(); |
145 | - console.log('5656close'); | ||
146 | }} | 180 | }} |
147 | type={'modify'} | 181 | type={'modify'} |
148 | onFinish={() => { | 182 | onFinish={() => { |
@@ -178,10 +212,83 @@ export default ({ data, reloadTable }) => { | @@ -178,10 +212,83 @@ export default ({ data, reloadTable }) => { | ||
178 | }} | 212 | }} |
179 | > | 213 | > |
180 | <Descriptions items={items} column={1} /> | 214 | <Descriptions items={items} column={1} /> |
181 | - {attachmentsName && ( | 215 | + {/* {attachmentsName && ( |
182 | <a href={attachments} download> | 216 | <a href={attachments} download> |
183 | 附件:{attachmentsName} | 217 | 附件:{attachmentsName} |
184 | </a> | 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 | </ModalForm> | 293 | </ModalForm> |
187 | </Space> | 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,9 +8,8 @@ import { | ||
8 | postAdminClientGetStatisticalData, | 8 | postAdminClientGetStatisticalData, |
9 | postAdminClientQueryClientPage, | 9 | postAdminClientQueryClientPage, |
10 | postServiceConstClientLevels, | 10 | postServiceConstClientLevels, |
11 | - postServiceConstClientRequirements, | ||
12 | postServiceConstClientSource, | 11 | postServiceConstClientSource, |
13 | - postServiceConstTradeStatus, | 12 | + postServiceOrderQueryCustomerInformation, |
14 | } from '@/services'; | 13 | } from '@/services'; |
15 | import { downloadFile } from '@/services/order'; | 14 | import { downloadFile } from '@/services/order'; |
16 | import { enumToSelect } from '@/utils'; | 15 | import { enumToSelect } from '@/utils'; |
@@ -41,6 +40,12 @@ const columns = [ | @@ -41,6 +40,12 @@ const columns = [ | ||
41 | // hideInSearch: true, | 40 | // hideInSearch: true, |
42 | // }, | 41 | // }, |
43 | { | 42 | { |
43 | + title: '客户名称', | ||
44 | + dataIndex: 'nameLike', | ||
45 | + valueType: 'Text', | ||
46 | + hideInTable: true, | ||
47 | + }, | ||
48 | + { | ||
44 | title: '客户地址', | 49 | title: '客户地址', |
45 | width: 250, | 50 | width: 250, |
46 | ellipsis: true, | 51 | ellipsis: true, |
@@ -48,10 +53,10 @@ const columns = [ | @@ -48,10 +53,10 @@ const columns = [ | ||
48 | hideInSearch: false, | 53 | hideInSearch: false, |
49 | }, | 54 | }, |
50 | { | 55 | { |
51 | - title: '联系人', | 56 | + title: '负责人', |
52 | width: 150, | 57 | width: 150, |
53 | ellipsis: true, | 58 | ellipsis: true, |
54 | - dataIndex: 'contacts', | 59 | + dataIndex: 'leaderName', |
55 | hideInSearch: false, | 60 | hideInSearch: false, |
56 | }, | 61 | }, |
57 | { | 62 | { |
@@ -62,73 +67,110 @@ const columns = [ | @@ -62,73 +67,110 @@ const columns = [ | ||
62 | hideInSearch: true, | 67 | hideInSearch: true, |
63 | }, | 68 | }, |
64 | { | 69 | { |
65 | - title: '客户来源', | 70 | + title: '课题组', |
71 | + dataIndex: 'institutionContactName', | ||
66 | width: 150, | 72 | width: 150, |
67 | ellipsis: true, | 73 | ellipsis: true, |
68 | - dataIndex: 'sourceText', | ||
69 | hideInSearch: true, | 74 | hideInSearch: true, |
70 | }, | 75 | }, |
71 | { | 76 | { |
72 | - title: '客户来源', | 77 | + title: '课题组', |
78 | + dataIndex: 'institutionContactName', | ||
73 | valueType: 'select', | 79 | valueType: 'select', |
74 | hideInTable: true, | 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 | width: 150, | 116 | width: 150, |
85 | ellipsis: true, | 117 | ellipsis: true, |
118 | + dataIndex: 'gradePosition', | ||
86 | hideInSearch: true, | 119 | hideInSearch: true, |
87 | }, | 120 | }, |
88 | { | 121 | { |
89 | - title: '客户需求', | ||
90 | - width: 240, | 122 | + title: '客户来源', |
123 | + width: 150, | ||
91 | ellipsis: true, | 124 | ellipsis: true, |
92 | - dataIndex: 'requirementsText', | 125 | + dataIndex: 'sourceText', |
93 | hideInSearch: true, | 126 | hideInSearch: true, |
94 | }, | 127 | }, |
95 | { | 128 | { |
96 | - title: '客户需求', | ||
97 | - dataIndex: 'requirements', | 129 | + title: '客户来源', |
98 | valueType: 'select', | 130 | valueType: 'select', |
99 | hideInTable: true, | 131 | hideInTable: true, |
132 | + dataIndex: 'source', | ||
100 | request: async () => { | 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 | return enumToSelect(res.data); | 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 | width: 150, | 141 | width: 150, |
122 | ellipsis: true, | 142 | ellipsis: true, |
123 | - dataIndex: 'quoteDatetime', | ||
124 | - valueType: 'date', | ||
125 | hideInSearch: true, | 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 | width: 150, | 171 | width: 150, |
130 | ellipsis: true, | 172 | ellipsis: true, |
131 | - dataIndex: 'tradeStatusText', | 173 | + dataIndex: 'createByName', |
132 | hideInSearch: true, | 174 | hideInSearch: true, |
133 | }, | 175 | }, |
134 | { | 176 | { |
@@ -165,41 +207,30 @@ const columns = [ | @@ -165,41 +207,30 @@ const columns = [ | ||
165 | // valueType: 'dateTime', | 207 | // valueType: 'dateTime', |
166 | // hideInSearch: true, | 208 | // hideInSearch: true, |
167 | // }, | 209 | // }, |
168 | - { | ||
169 | - title: '客户名称', | ||
170 | - dataIndex: 'nameLike', | ||
171 | - valueType: 'Text', | ||
172 | - hideInTable: true, | ||
173 | - }, | ||
174 | // { | 210 | // { |
175 | // title: '单位名称', | 211 | // title: '单位名称', |
176 | // dataIndex: 'companyNameLike', | 212 | // dataIndex: 'companyNameLike', |
177 | // valueType: 'Text', | 213 | // valueType: 'Text', |
178 | // hideInTable: true, | 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 | title: '客户等级', | 235 | title: '客户等级', |
205 | dataIndex: 'level', | 236 | dataIndex: 'level', |
@@ -218,25 +249,30 @@ const columns = [ | @@ -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 | hideInTable: true, | 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 | valueType: 'dateRange', | 268 | valueType: 'dateRange', |
233 | hideInTable: true, | 269 | hideInTable: true, |
234 | search: { | 270 | search: { |
235 | transform: (value) => { | 271 | transform: (value) => { |
236 | if (value) { | 272 | if (value) { |
237 | return { | 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,7 +285,6 @@ const columns = [ | ||
249 | width: 200, | 285 | width: 200, |
250 | render: (text, record, index, action) => { | 286 | render: (text, record, index, action) => { |
251 | const handleDelete = async () => { | 287 | const handleDelete = async () => { |
252 | - console.log(JSON.stringify(record), '5656record1'); | ||
253 | // 调用删除接口 | 288 | // 调用删除接口 |
254 | const success = await postAdminClientDeleteAdminClient({ | 289 | const success = await postAdminClientDeleteAdminClient({ |
255 | query: { | 290 | query: { |
@@ -260,7 +295,6 @@ const columns = [ | @@ -260,7 +295,6 @@ const columns = [ | ||
260 | action.reload(); // 刷新表格 | 295 | action.reload(); // 刷新表格 |
261 | } | 296 | } |
262 | }; | 297 | }; |
263 | - console.log(JSON.stringify(record), '5656record2'); | ||
264 | return [ | 298 | return [ |
265 | <CommunicationHistoryModal | 299 | <CommunicationHistoryModal |
266 | key={'communicationHistory'} | 300 | key={'communicationHistory'} |
@@ -323,11 +357,11 @@ export default () => { | @@ -323,11 +357,11 @@ export default () => { | ||
323 | const pullStatistic = async () => { | 357 | const pullStatistic = async () => { |
324 | let statisticalData = await postAdminClientGetStatisticalData(); | 358 | let statisticalData = await postAdminClientGetStatisticalData(); |
325 | console.log('stati' + JSON.stringify(statisticalData.data)); | 359 | console.log('stati' + JSON.stringify(statisticalData.data)); |
360 | + console.log(clientStatistic); | ||
326 | setClientStatistic(statisticalData.data); | 361 | setClientStatistic(statisticalData.data); |
327 | - setWarningClientStatistic(statisticalData.data[1].value); | 362 | + setWarningClientStatistic(statisticalData?.data[1].value); |
328 | // setAllClientStatistic(statisticalData.data[0].value); | 363 | // setAllClientStatistic(statisticalData.data[0].value); |
329 | setTimeout(() => { | 364 | setTimeout(() => { |
330 | - console.log(clientStatistic, '5656groupFilterOptions1'); | ||
331 | // groupFilterOptions[0].label = groupFilterOptions[0].label + '(' + clientStatistic + ')'; | 365 | // groupFilterOptions[0].label = groupFilterOptions[0].label + '(' + clientStatistic + ')'; |
332 | }, 100); | 366 | }, 100); |
333 | actionRef.current?.reload(); // 可能需要在这里刷新 | 367 | actionRef.current?.reload(); // 可能需要在这里刷新 |
@@ -361,8 +395,6 @@ export default () => { | @@ -361,8 +395,6 @@ export default () => { | ||
361 | // }, []); | 395 | // }, []); |
362 | useEffect(() => { | 396 | useEffect(() => { |
363 | // console.log(groupFilterOptions, '5656groupFilterOptions2'); | 397 | // console.log(groupFilterOptions, '5656groupFilterOptions2'); |
364 | - console.log(clientStatistic, '5656clientStatistic'); | ||
365 | - console.log(warningClientStatistic, '5656warningClientStatistic'); | ||
366 | actionRef.current?.reload(); | 398 | actionRef.current?.reload(); |
367 | }, [groupFilter]); | 399 | }, [groupFilter]); |
368 | return ( | 400 | return ( |
@@ -411,7 +443,6 @@ export default () => { | @@ -411,7 +443,6 @@ export default () => { | ||
411 | 'POST', | 443 | 'POST', |
412 | values, | 444 | values, |
413 | () => { | 445 | () => { |
414 | - console.log(searchConfig, '5656searchConfig'); | ||
415 | messageApi.destroy(); | 446 | messageApi.destroy(); |
416 | }, | 447 | }, |
417 | ); | 448 | ); |
src/pages/Client/FollowRecord/Components/ClientModal.tsx
1 | import { RESPONSE_CODE } from '@/constants/enum'; | 1 | import { RESPONSE_CODE } from '@/constants/enum'; |
2 | +import UploadC from '@/pages/Invoice/waitProcessRecord/components/UploadSingleImg'; | ||
2 | import { | 3 | import { |
3 | postAdminClientAddOrModifyClientComunicationInfo, | 4 | postAdminClientAddOrModifyClientComunicationInfo, |
4 | postAdminClientQueryClientPage, | 5 | postAdminClientQueryClientPage, |
5 | postOrderErpOrderStagesUpload, | 6 | postOrderErpOrderStagesUpload, |
7 | + postOrderErpUsersListByPage, | ||
6 | postServiceConstClientWay, | 8 | postServiceConstClientWay, |
9 | + postServiceConstTradeStatus, | ||
7 | } from '@/services'; | 10 | } from '@/services'; |
8 | import { enumToSelect } from '@/utils'; | 11 | import { enumToSelect } from '@/utils'; |
9 | import { | 12 | import { |
@@ -14,8 +17,9 @@ import { | @@ -14,8 +17,9 @@ import { | ||
14 | ProFormTextArea, | 17 | ProFormTextArea, |
15 | ProFormUploadDragger, | 18 | ProFormUploadDragger, |
16 | } from '@ant-design/pro-components'; | 19 | } from '@ant-design/pro-components'; |
17 | -import { Button, Form, message } from 'antd'; | 20 | +import { Button, Col, Form, Row, message } from 'antd'; |
18 | import { RcFile } from 'antd/es/upload'; | 21 | import { RcFile } from 'antd/es/upload'; |
22 | +import './style.css'; | ||
19 | export default ({ data, type, reloadTable }) => { | 23 | export default ({ data, type, reloadTable }) => { |
20 | const [form] = Form.useForm(); | 24 | const [form] = Form.useForm(); |
21 | const onfinish = async (values) => { | 25 | const onfinish = async (values) => { |
@@ -37,6 +41,7 @@ export default ({ data, type, reloadTable }) => { | @@ -37,6 +41,7 @@ export default ({ data, type, reloadTable }) => { | ||
37 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ | 41 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
38 | data: { | 42 | data: { |
39 | ...values, | 43 | ...values, |
44 | + ticketsAttachments: form.getFieldValue('ticketsAttachments'), | ||
40 | clientId: matchedId, | 45 | clientId: matchedId, |
41 | }, | 46 | }, |
42 | }); | 47 | }); |
@@ -47,10 +52,10 @@ export default ({ data, type, reloadTable }) => { | @@ -47,10 +52,10 @@ export default ({ data, type, reloadTable }) => { | ||
47 | } | 52 | } |
48 | // 不返回不会关闭弹框 | 53 | // 不返回不会关闭弹框 |
49 | }; | 54 | }; |
55 | + | ||
50 | const editOnfinish = async (values) => { | 56 | const editOnfinish = async (values) => { |
51 | // setEditClientId(data.clientId); | 57 | // setEditClientId(data.clientId); |
52 | values.clientId = data.clientId; | 58 | values.clientId = data.clientId; |
53 | - console.log(values, '5656editClientId'); | ||
54 | 59 | ||
55 | // const resSearchId = await postAdminClientQueryClientPage({ | 60 | // const resSearchId = await postAdminClientQueryClientPage({ |
56 | // data: { | 61 | // data: { |
@@ -60,10 +65,15 @@ export default ({ data, type, reloadTable }) => { | @@ -60,10 +65,15 @@ export default ({ data, type, reloadTable }) => { | ||
60 | // const matchingItem = resSearchId.data.data.find( | 65 | // const matchingItem = resSearchId.data.data.find( |
61 | // (item) => item.id === values.name, | 66 | // (item) => item.id === values.name, |
62 | // ); | 67 | // ); |
63 | - | ||
64 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ | 68 | const res = await postAdminClientAddOrModifyClientComunicationInfo({ |
65 | data: { | 69 | data: { |
66 | ...values, | 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 | if (res.result === RESPONSE_CODE.SUCCESS) { | 79 | if (res.result === RESPONSE_CODE.SUCCESS) { |
@@ -140,7 +150,6 @@ export default ({ data, type, reloadTable }) => { | @@ -140,7 +150,6 @@ export default ({ data, type, reloadTable }) => { | ||
140 | groupFilter: 'all', | 150 | groupFilter: 'all', |
141 | }, | 151 | }, |
142 | }); | 152 | }); |
143 | - console.log(data, '5656data?.nameedit'); | ||
144 | // const namesArray = res.data.data.map((item) => item.name); | 153 | // const namesArray = res.data.data.map((item) => item.name); |
145 | // const formattedObject = res.data.data.reduce((acc, name) => { | 154 | // const formattedObject = res.data.data.reduce((acc, name) => { |
146 | // acc[name] = name; // 将名称作为键和值 | 155 | // acc[name] = name; // 将名称作为键和值 |
@@ -165,18 +174,67 @@ export default ({ data, type, reloadTable }) => { | @@ -165,18 +174,67 @@ export default ({ data, type, reloadTable }) => { | ||
165 | }, | 174 | }, |
166 | ]} | 175 | ]} |
167 | ></ProFormSelect> | 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 | <ProFormDateTimePicker | 205 | <ProFormDateTimePicker |
169 | name="datetime" | 206 | name="datetime" |
170 | - label="日期" | 207 | + label="跟进日期" |
171 | initialValue={data ? data?.datetime + '' : null} | 208 | initialValue={data ? data?.datetime + '' : null} |
172 | placeholder="请选择跟进时间" | 209 | placeholder="请选择跟进时间" |
173 | width="sm" | 210 | width="sm" |
174 | rules={[ | 211 | rules={[ |
175 | { | 212 | { |
176 | required: true, | 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 | <ProFormSelect | 239 | <ProFormSelect |
182 | name="way" | 240 | name="way" |
@@ -186,7 +244,7 @@ export default ({ data, type, reloadTable }) => { | @@ -186,7 +244,7 @@ export default ({ data, type, reloadTable }) => { | ||
186 | labelInValue: false, | 244 | labelInValue: false, |
187 | }} | 245 | }} |
188 | initialValue={data?.way ? data?.way + '' : null} | 246 | initialValue={data?.way ? data?.way + '' : null} |
189 | - label="类型" | 247 | + label="跟进方式" |
190 | request={async () => { | 248 | request={async () => { |
191 | const res = await postServiceConstClientWay(); | 249 | const res = await postServiceConstClientWay(); |
192 | return enumToSelect(res.data); | 250 | return enumToSelect(res.data); |
@@ -194,20 +252,20 @@ export default ({ data, type, reloadTable }) => { | @@ -194,20 +252,20 @@ export default ({ data, type, reloadTable }) => { | ||
194 | rules={[ | 252 | rules={[ |
195 | { | 253 | { |
196 | required: true, | 254 | required: true, |
197 | - message: '请选择跟进类型', | 255 | + message: '请选择跟进方式', |
198 | }, | 256 | }, |
199 | ]} | 257 | ]} |
200 | ></ProFormSelect> | 258 | ></ProFormSelect> |
201 | <ProFormTextArea | 259 | <ProFormTextArea |
202 | name="content" | 260 | name="content" |
203 | - label="详情" | ||
204 | - placeholder="请输入详情" | 261 | + label="跟进详情" |
262 | + placeholder="请输入跟进详情" | ||
205 | initialValue={data?.content} | 263 | initialValue={data?.content} |
206 | readonly={optType[type].readOnly} | 264 | readonly={optType[type].readOnly} |
207 | rules={[ | 265 | rules={[ |
208 | { | 266 | { |
209 | required: true, | 267 | required: true, |
210 | - message: '请输入详情', | 268 | + message: '请输入跟进详情', |
211 | }, | 269 | }, |
212 | ]} | 270 | ]} |
213 | ></ProFormTextArea> | 271 | ></ProFormTextArea> |
@@ -242,12 +300,138 @@ export default ({ data, type, reloadTable }) => { | @@ -242,12 +300,138 @@ export default ({ data, type, reloadTable }) => { | ||
242 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> | 300 | <a hidden={!optType[type].readOnly} href={data?.attachments} download> |
243 | 下载附件 | 301 | 下载附件 |
244 | </a> | 302 | </a> |
303 | + <ProFormTextArea | ||
304 | + name="comment" | ||
305 | + label="客户评价" | ||
306 | + placeholder="请输入客户评价" | ||
307 | + initialValue={data?.comment} | ||
308 | + readonly={optType[type].readOnly} | ||
309 | + ></ProFormTextArea> | ||
245 | <ProFormText | 310 | <ProFormText |
246 | initialValue={data?.attachments} | 311 | initialValue={data?.attachments} |
247 | name="attachments" | 312 | name="attachments" |
248 | hidden | 313 | hidden |
249 | ></ProFormText> | 314 | ></ProFormText> |
250 | <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | 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 | </ModalForm> | 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 +8,6 @@ import { Button, Descriptions, Space } from 'antd'; | ||
8 | import { useEffect, useRef, useState } from 'react'; | 8 | import { useEffect, useRef, useState } from 'react'; |
9 | 9 | ||
10 | export default ({ data, reloadTable }) => { | 10 | export default ({ data, reloadTable }) => { |
11 | - console.log(data, '5656datafirstshowgenjin'); | ||
12 | - | ||
13 | // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 | 11 | // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 |
14 | const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 | 12 | const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 |
15 | 13 | ||
@@ -17,7 +15,8 @@ export default ({ data, reloadTable }) => { | @@ -17,7 +15,8 @@ export default ({ data, reloadTable }) => { | ||
17 | const [createByName, setCreateByName] = useState(''); // 跟进人员 | 15 | const [createByName, setCreateByName] = useState(''); // 跟进人员 |
18 | const [clientName, setClientName] = useState(''); // 客户名称 | 16 | const [clientName, setClientName] = useState(''); // 客户名称 |
19 | // const [clientAddress, setClientAddress] = useState(''); // 客户地址 | 17 | // const [clientAddress, setClientAddress] = useState(''); // 客户地址 |
20 | - const [way, setWay] = useState(); // 类型 | 18 | + const [way, setWay] = useState(); // 跟进方式 |
19 | + const [tradeStatusText, setTradeStatusText] = useState(); // 状态 | ||
21 | // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 | 20 | // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 |
22 | // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 | 21 | // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 |
23 | // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 | 22 | // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 |
@@ -26,18 +25,36 @@ export default ({ data, reloadTable }) => { | @@ -26,18 +25,36 @@ export default ({ data, reloadTable }) => { | ||
26 | const [createTime, setCreateTime] = useState(null); // 创建时间 | 25 | const [createTime, setCreateTime] = useState(null); // 创建时间 |
27 | const [attachments, setAttachments] = useState(); //附件 | 26 | const [attachments, setAttachments] = useState(); //附件 |
28 | const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称 | 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 | useEffect(() => { | 34 | useEffect(() => { |
31 | const request = async () => { | 35 | const request = async () => { |
32 | - console.log(data, '5656datasearch'); | ||
33 | const res = await postAdminClientQueryClientComunicationInfo({ | 36 | const res = await postAdminClientQueryClientComunicationInfo({ |
34 | data: { | 37 | data: { |
35 | id: data.id, | 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 | const dataSearch = res.data.data[0]; | 51 | const dataSearch = res.data.data[0]; |
52 | + console.log(dataSearch, '5656dataSearch'); | ||
40 | if (dataSearch) { | 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 | if (dataSearch.attachments) { | 58 | if (dataSearch.attachments) { |
42 | const url = dataSearch.attachments; | 59 | const url = dataSearch.attachments; |
43 | const match = url.match(/aliyuncs\.com\/(.*?)\?/); | 60 | const match = url.match(/aliyuncs\.com\/(.*?)\?/); |
@@ -50,6 +67,24 @@ export default ({ data, reloadTable }) => { | @@ -50,6 +67,24 @@ export default ({ data, reloadTable }) => { | ||
50 | setAttachmentsName(decodedStr); // 设置跟进日期 | 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 | setDatetime(dataSearch.datetime); // 设置跟进日期 | 88 | setDatetime(dataSearch.datetime); // 设置跟进日期 |
54 | // setDateRange(data.dateRange || []); // 设置跟进时间范围 | 89 | // setDateRange(data.dateRange || []); // 设置跟进时间范围 |
55 | setCreateByName(dataSearch.createByName); // 设置跟进人员 | 90 | setCreateByName(dataSearch.createByName); // 设置跟进人员 |
@@ -58,13 +93,12 @@ export default ({ data, reloadTable }) => { | @@ -58,13 +93,12 @@ export default ({ data, reloadTable }) => { | ||
58 | // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 | 93 | // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 |
59 | // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 | 94 | // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 |
60 | // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 | 95 | // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 |
61 | - // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询 | 96 | + setTradeStatusText(data.tradeStatusLike || ''); // 设置客户状态模糊查询 |
62 | setContent(dataSearch.content); // 设置跟进详情 | 97 | setContent(dataSearch.content); // 设置跟进详情 |
63 | setCreateTime(dataSearch.createTime); // 设置创建时间 | 98 | setCreateTime(dataSearch.createTime); // 设置创建时间 |
64 | setWay(dataSearch.wayText); | 99 | setWay(dataSearch.wayText); |
65 | setAttachments(dataSearch.attachments); | 100 | setAttachments(dataSearch.attachments); |
66 | } | 101 | } |
67 | - console.log(attachments, '5656attachments'); | ||
68 | }; | 102 | }; |
69 | request(); | 103 | request(); |
70 | }, []); | 104 | }, []); |
@@ -96,12 +130,41 @@ export default ({ data, reloadTable }) => { | @@ -96,12 +130,41 @@ export default ({ data, reloadTable }) => { | ||
96 | }, | 130 | }, |
97 | { | 131 | { |
98 | key: '6', | 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 | const handleDelete = async () => { | 167 | const handleDelete = async () => { |
104 | - console.log(JSON.stringify(data), '5656record'); | ||
105 | // 调用删除接口 | 168 | // 调用删除接口 |
106 | const success = await postAdminClientRemoveClientComunicationInfo({ | 169 | const success = await postAdminClientRemoveClientComunicationInfo({ |
107 | query: { | 170 | query: { |
@@ -117,7 +180,7 @@ export default ({ data, reloadTable }) => { | @@ -117,7 +180,7 @@ export default ({ data, reloadTable }) => { | ||
117 | <Space> | 180 | <Space> |
118 | <ModalForm | 181 | <ModalForm |
119 | title="跟进记录" | 182 | title="跟进记录" |
120 | - trigger={<Button type="link">查看</Button>} | 183 | + trigger={<Button type="primary">查看</Button>} |
121 | submitter={{ | 184 | submitter={{ |
122 | resetButtonProps: { | 185 | resetButtonProps: { |
123 | style: { | 186 | style: { |
@@ -135,12 +198,14 @@ export default ({ data, reloadTable }) => { | @@ -135,12 +198,14 @@ export default ({ data, reloadTable }) => { | ||
135 | <> | 198 | <> |
136 | <ClientModal | 199 | <ClientModal |
137 | key={'modify'} | 200 | key={'modify'} |
138 | - data={data} // 将表单数据传递给 ClientModal | 201 | + // data={data} // 将表单数据传递给 ClientModal |
202 | + data={{ | ||
203 | + data, | ||
204 | + }} // 传递修改后的 data | ||
139 | reloadTable={() => { | 205 | reloadTable={() => { |
140 | actionRef?.current?.reload(); // 重新加载表格数据 | 206 | actionRef?.current?.reload(); // 重新加载表格数据 |
141 | props.submit(); | 207 | props.submit(); |
142 | reloadTable(); | 208 | reloadTable(); |
143 | - console.log('5656close'); | ||
144 | }} | 209 | }} |
145 | type={'modify'} | 210 | type={'modify'} |
146 | onFinish={() => { | 211 | onFinish={() => { |
@@ -176,11 +241,90 @@ export default ({ data, reloadTable }) => { | @@ -176,11 +241,90 @@ export default ({ data, reloadTable }) => { | ||
176 | }} | 241 | }} |
177 | > | 242 | > |
178 | <Descriptions items={items} column={1} /> | 243 | <Descriptions items={items} column={1} /> |
179 | - {attachmentsName && ( | 244 | + {/* {attachmentsName && ( |
180 | <a href={attachments} download> | 245 | <a href={attachments} download> |
181 | 附件:{attachmentsName} | 246 | 附件:{attachmentsName} |
182 | </a> | 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 | </ModalForm> | 328 | </ModalForm> |
185 | </Space> | 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,8 +10,9 @@ import { | ||
10 | import { enumToSelect } from '@/utils'; | 10 | import { enumToSelect } from '@/utils'; |
11 | import type { ActionType } from '@ant-design/pro-components'; | 11 | import type { ActionType } from '@ant-design/pro-components'; |
12 | import { ProTable } from '@ant-design/pro-components'; | 12 | import { ProTable } from '@ant-design/pro-components'; |
13 | -import { Button, Space, message } from 'antd'; | 13 | +import { Button, Popconfirm, Space, message } from 'antd'; |
14 | import { useRef, useState } from 'react'; | 14 | import { useRef, useState } from 'react'; |
15 | +import ClientModal2 from './Components/ClientModal2'; | ||
15 | 16 | ||
16 | export default () => { | 17 | export default () => { |
17 | const actionRef = useRef<ActionType>(); | 18 | const actionRef = useRef<ActionType>(); |
@@ -19,7 +20,6 @@ export default () => { | @@ -19,7 +20,6 @@ export default () => { | ||
19 | 20 | ||
20 | const reload = () => { | 21 | const reload = () => { |
21 | actionRef.current.reload(); // 重新加载数据 | 22 | actionRef.current.reload(); // 重新加载数据 |
22 | - console.log('5656flush'); | ||
23 | 23 | ||
24 | // 更新 refreshKey,强制刷新 CommunicationHistoryModal | 24 | // 更新 refreshKey,强制刷新 CommunicationHistoryModal |
25 | setRefreshKey((prevKey) => prevKey + 1); | 25 | setRefreshKey((prevKey) => prevKey + 1); |
@@ -46,7 +46,7 @@ export default () => { | @@ -46,7 +46,7 @@ export default () => { | ||
46 | // }, | 46 | // }, |
47 | }, | 47 | }, |
48 | { | 48 | { |
49 | - title: '跟进时间', | 49 | + title: '跟进日期', |
50 | dataIndex: 'dateRange', | 50 | dataIndex: 'dateRange', |
51 | valueType: 'dateRange', | 51 | valueType: 'dateRange', |
52 | hideInTable: true, | 52 | hideInTable: true, |
@@ -68,6 +68,13 @@ export default () => { | @@ -68,6 +68,13 @@ export default () => { | ||
68 | ellipsis: true, | 68 | ellipsis: true, |
69 | hideInSearch: false, | 69 | hideInSearch: false, |
70 | }, | 70 | }, |
71 | + // { | ||
72 | + // title: '跟进状态', | ||
73 | + // width: 150, | ||
74 | + // ellipsis: true, | ||
75 | + // dataIndex: 'tradeStatusText', | ||
76 | + // hideInSearch: true, | ||
77 | + // }, | ||
71 | { | 78 | { |
72 | title: '客户名称', | 79 | title: '客户名称', |
73 | dataIndex: 'clientName', | 80 | dataIndex: 'clientName', |
@@ -75,22 +82,51 @@ export default () => { | @@ -75,22 +82,51 @@ export default () => { | ||
75 | ellipsis: true, | 82 | ellipsis: true, |
76 | hideInSearch: true, | 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 | ellipsis: true, | 118 | ellipsis: true, |
83 | hideInSearch: true, | 119 | hideInSearch: true, |
84 | }, | 120 | }, |
85 | { | 121 | { |
86 | - title: '跟进类型', | 122 | + title: '跟进方式', |
87 | dataIndex: 'wayText', | 123 | dataIndex: 'wayText', |
88 | width: 100, | 124 | width: 100, |
89 | ellipsis: true, | 125 | ellipsis: true, |
90 | hideInSearch: true, | 126 | hideInSearch: true, |
91 | }, | 127 | }, |
92 | { | 128 | { |
93 | - title: '跟进类型', | 129 | + title: '跟进方式', |
94 | dataIndex: 'way', | 130 | dataIndex: 'way', |
95 | width: 100, | 131 | width: 100, |
96 | ellipsis: true, | 132 | ellipsis: true, |
@@ -101,6 +137,16 @@ export default () => { | @@ -101,6 +137,16 @@ export default () => { | ||
101 | return enumToSelect(res.data); | 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 | title: '客户名称', | 151 | title: '客户名称', |
106 | dataIndex: 'clientNameLike', | 152 | dataIndex: 'clientNameLike', |
@@ -109,26 +155,26 @@ export default () => { | @@ -109,26 +155,26 @@ export default () => { | ||
109 | hideInSearch: false, | 155 | hideInSearch: false, |
110 | hideInTable: true, | 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 | dataIndex: 'tradeStatus', | 175 | dataIndex: 'tradeStatus', |
123 | width: 100, | 176 | width: 100, |
124 | ellipsis: true, | 177 | ellipsis: true, |
125 | - hideInSearch: true, | ||
126 | - }, | ||
127 | - { | ||
128 | - title: '客户状态', | ||
129 | - dataIndex: 'tradeStatusLike', | ||
130 | - width: 100, | ||
131 | - ellipsis: true, | ||
132 | hideInSearch: false, | 178 | hideInSearch: false, |
133 | hideInTable: true, | 179 | hideInTable: true, |
134 | request: async () => { | 180 | request: async () => { |
@@ -141,7 +187,7 @@ export default () => { | @@ -141,7 +187,7 @@ export default () => { | ||
141 | dataIndex: 'content', | 187 | dataIndex: 'content', |
142 | width: 250, | 188 | width: 250, |
143 | ellipsis: true, | 189 | ellipsis: true, |
144 | - hideInSearch: false, | 190 | + hideInSearch: true, |
145 | }, | 191 | }, |
146 | { | 192 | { |
147 | title: '创建时间', | 193 | title: '创建时间', |
@@ -159,10 +205,26 @@ export default () => { | @@ -159,10 +205,26 @@ export default () => { | ||
159 | hideInTable: true, | 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 | title: '操作', | 224 | title: '操作', |
163 | valueType: 'option', | 225 | valueType: 'option', |
164 | key: 'option', | 226 | key: 'option', |
165 | - width: 150, | 227 | + width: 220, |
166 | render: (text, record, index, action) => { | 228 | render: (text, record, index, action) => { |
167 | const handleDelete = async () => { | 229 | const handleDelete = async () => { |
168 | // console.log(JSON.stringify(record), '5656record'); | 230 | // console.log(JSON.stringify(record), '5656record'); |
@@ -187,8 +249,22 @@ export default () => { | @@ -187,8 +249,22 @@ export default () => { | ||
187 | // }} | 249 | // }} |
188 | reloadTable={reload} | 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 | key={'delete'} | 268 | key={'delete'} |
193 | onClick={() => { | 269 | onClick={() => { |
194 | handleDelete(); | 270 | handleDelete(); |
@@ -197,15 +273,42 @@ export default () => { | @@ -197,15 +273,42 @@ export default () => { | ||
197 | // reloadTable={() => { | 273 | // reloadTable={() => { |
198 | // actionRef.current.reload(); | 274 | // actionRef.current.reload(); |
199 | // }} | 275 | // }} |
200 | - type="link" | 276 | + type="primary" |
201 | size="middle" | 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 | </Button> | 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,7 +339,6 @@ export default () => { | ||
236 | ...params, | 339 | ...params, |
237 | }, | 340 | }, |
238 | }); | 341 | }); |
239 | - console.log(params, '5656566params'); | ||
240 | if (res.result === RESPONSE_CODE.SUCCESS) { | 342 | if (res.result === RESPONSE_CODE.SUCCESS) { |
241 | console.log(JSON.stringify(res.data)); | 343 | console.log(JSON.stringify(res.data)); |
242 | return { | 344 | return { |
src/tsg.config.ts
@@ -33,8 +33,8 @@ const projects: Project[] = [ | @@ -33,8 +33,8 @@ const projects: Project[] = [ | ||
33 | * openapi 文档地址,可以是远程的json文件,也可以是本地的json文件 | 33 | * openapi 文档地址,可以是远程的json文件,也可以是本地的json文件 |
34 | * 如果使用本地文件,相对路径以当前'tsg.config.ts'为基准 | 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 | // source: 'https://petstore3.swagger.io/api/v3/openapi.json', | 39 | // source: 'https://petstore3.swagger.io/api/v3/openapi.json', |
40 | // source: './fixture/pet.json', | 40 | // source: './fixture/pet.json', |