Commit cf0ac7a5e4f9f0bf4411f3340d9f68f165093eb1

Authored by boyang
1 parent 9e4ff9d0

fix: 修改客户管理/跟进记录

.umirc.ts
... ... @@ -14,9 +14,9 @@ export default defineConfig({
14 14 },
15 15 proxy: {
16 16 '/api/': {
17   - // target: 'http://localhost:8085/',
  17 + target: 'http://localhost:8085/',
18 18 // target: 'http://192.168.1.6:8085/',
19   - target: 'http://39.108.227.113:8085/',
  19 + // target: 'http://39.108.227.113:8085/',
20 20 changeOrigin: true,
21 21 pathRewrite: { '^/api': '' },
22 22 },
... ...
src/pages/Client/Client/Components/ClientDrawer.tsx
... ... @@ -5,15 +5,14 @@ import {
5 5 postDistrictSelectByLevel,
6 6 postDistrictSelectByNameAndLevel,
7 7 postDistrictSelOrderProvince,
  8 + postResearchGroupsNameSet,
8 9 postServiceConstClientLevels,
9 10 postServiceConstClientSource,
10   - postServiceConstTradeStatus,
11 11 } from '@/services';
12 12  
13 13 import { enumToSelect } from '@/utils';
14 14 import {
15 15 DrawerForm,
16   - ProFormDatePicker,
17 16 ProFormSelect,
18 17 ProFormText,
19 18 } from '@ant-design/pro-components';
... ... @@ -33,7 +32,6 @@ export default ({ optType, record, onFinish }) => {
33 32 const [province, setProvince] = useState('');
34 33 const [city, setCity] = useState('');
35 34 const [showReferrers, setShowReferrers] = useState(false); // 控制显示的状态,初始为false
36   - const [showQuoteDatetime, setShowQuoteDatetime] = useState(false); // 控制显示的状态,初始为false
37 35 const optTypeEnum = {
38 36 add: {
39 37 text: '新增',
... ... @@ -82,15 +80,6 @@ export default ({ optType, record, onFinish }) => {
82 80 }
83 81 // 在这里可以添加其他逻辑,比如根据选择更新其他表单项的值
84 82 };
85   - const handleSchemeChange = (value) => {
86   - console.log(value);
87   - if (value === true) {
88   - setShowQuoteDatetime(true);
89   - } else {
90   - setShowQuoteDatetime(false);
91   - }
92   - // 在这里可以添加其他逻辑,比如根据选择更新其他表单项的值
93   - };
94 83  
95 84 // MODIFIED: 增加处理非 JSON 格式字符串的逻辑
96 85 const parsedRecord = record
... ... @@ -314,13 +303,13 @@ export default ({ optType, record, onFinish }) => {
314 303 ]}
315 304 />
316 305 <ProFormText
317   - name="contacts"
318   - label="联系人"
319   - placeholder="请输入联系人"
  306 + name="leaderName"
  307 + label="负责人"
  308 + placeholder="请输入负责人"
320 309 rules={[
321 310 {
322 311 required: true,
323   - message: '请输入联系人',
  312 + message: '请输入负责人',
324 313 },
325 314 ]}
326 315 />
... ... @@ -336,6 +325,60 @@ export default ({ optType, record, onFinish }) =&gt; {
336 325 ]}
337 326 />
338 327 <ProFormSelect
  328 + key={'institutionContactName'}
  329 + width="md"
  330 + showSearch
  331 + name="institutionContactName"
  332 + rules={[{ required: true, message: '请输入课题组名称!' }]}
  333 + request={async (value) => {
  334 + const keywords = value.keyWords;
  335 + const res = await postResearchGroupsNameSet({
  336 + data: {
  337 + status: 'ADD_AUDIT_PASS',
  338 + groupName: keywords,
  339 + },
  340 + });
  341 + let options = res?.data?.map((c: any) => {
  342 + return {
  343 + label: c,
  344 + value: c,
  345 + key: c,
  346 + };
  347 + });
  348 + return options;
  349 + }}
  350 + fieldProps={{
  351 + filterOption() {
  352 + return true;
  353 + },
  354 + }}
  355 + debounceTime={1000}
  356 + label="课题组名称"
  357 + placeholder="请输入名称"
  358 + />
  359 + <ProFormText
  360 + name="department"
  361 + label="部门"
  362 + placeholder="请输入部门"
  363 + rules={[
  364 + {
  365 + required: false,
  366 + message: '请输入部门',
  367 + },
  368 + ]}
  369 + />
  370 + <ProFormText
  371 + name="gradePosition"
  372 + label="年级/职位"
  373 + placeholder="请输入年级/职位"
  374 + rules={[
  375 + {
  376 + required: false,
  377 + message: '请输入年级/职位',
  378 + },
  379 + ]}
  380 + />
  381 + <ProFormSelect
339 382 name="source"
340 383 label="客户来源"
341 384 placeholder="请选择客户来源"
... ... @@ -382,37 +425,6 @@ export default ({ optType, record, onFinish }) =&gt; {
382 425 // }}
383 426 />
384 427 <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   - )}
415   - <ProFormSelect
416 428 name="level"
417 429 label="客户等级"
418 430 placeholder="请输入客户等级"
... ... @@ -437,21 +449,6 @@ export default ({ optType, record, onFinish }) =&gt; {
437 449 return enumToSelectLevel(res.data);
438 450 }}
439 451 />
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 452 <ProFormText name="notes" label="备注" placeholder="请输入备注" />
456 453 </DrawerForm>
457 454 );
... ...
src/pages/Client/Client/Components/ClientInformationModal.tsx
... ... @@ -3,7 +3,9 @@ import {
3 3 postAdminClientAddOrModifyClientComunicationInfo,
4 4 postAdminClientQueryClientPage,
5 5 postOrderErpOrderStagesUpload,
  6 + postOrderErpUsersListByPage,
6 7 postServiceConstClientWay,
  8 + postServiceConstTradeStatus,
7 9 } from '@/services';
8 10 import { enumToSelect } from '@/utils';
9 11 import {
... ... @@ -16,6 +18,7 @@ import {
16 18 } from '@ant-design/pro-components';
17 19 import { Button, Form, message } from 'antd';
18 20 import { RcFile } from 'antd/es/upload';
  21 +import './style.css';
19 22 export default ({ data, type, reloadTable }) => {
20 23 const [form] = Form.useForm();
21 24 const onfinish = async (values) => {
... ... @@ -64,6 +67,12 @@ export default ({ data, type, reloadTable }) =&gt; {
64 67 const res = await postAdminClientAddOrModifyClientComunicationInfo({
65 68 data: {
66 69 ...values,
  70 + // ticketsAttachments: form.getFieldValue("ticketsAttachments"),
  71 + ticketsAttachments:
  72 + form.getFieldValue('ticketsAttachments') !== undefined
  73 + ? form.getFieldValue('ticketsAttachments')
  74 + : data?.ticketsAttachments,
  75 + // ticketsAttachments: data?.annexUrl,
67 76 },
68 77 });
69 78 if (res.result === RESPONSE_CODE.SUCCESS) {
... ... @@ -165,9 +174,37 @@ export default ({ data, type, reloadTable }) =&gt; {
165 174 },
166 175 ]}
167 176 ></ProFormSelect>
  177 + <ProFormText
  178 + name="contact"
  179 + label="联系人"
  180 + width="sm"
  181 + placeholder="请输入联系人"
  182 + initialValue={data?.content}
  183 + readonly={optType[type].readOnly}
  184 + rules={[
  185 + {
  186 + required: true,
  187 + message: '请输入联系人',
  188 + },
  189 + ]}
  190 + ></ProFormText>
  191 + <ProFormText
  192 + name="contactPhone"
  193 + label="联系电话"
  194 + width="sm"
  195 + placeholder="请输入联系电话"
  196 + initialValue={data?.content}
  197 + readonly={optType[type].readOnly}
  198 + rules={[
  199 + {
  200 + required: true,
  201 + message: '请输入联系电话',
  202 + },
  203 + ]}
  204 + ></ProFormText>
168 205 <ProFormDateTimePicker
169 206 name="datetime"
170   - label="日期"
  207 + label="跟进日期"
171 208 initialValue={data ? data?.datetime + '' : null}
172 209 placeholder="请选择跟进时间"
173 210 width="sm"
... ... @@ -179,6 +216,27 @@ export default ({ data, type, reloadTable }) =&gt; {
179 216 ]}
180 217 />
181 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: '请输入跟进状态',
  232 + },
  233 + ]}
  234 + request={async () => {
  235 + const res = await postServiceConstTradeStatus();
  236 + return enumToSelect(res.data);
  237 + }}
  238 + />
  239 + <ProFormSelect
182 240 name="way"
183 241 width="sm"
184 242 readonly={optType[type].readOnly}
... ... @@ -186,7 +244,7 @@ export default ({ data, type, reloadTable }) =&gt; {
186 244 labelInValue: false,
187 245 }}
188 246 initialValue={data?.way ? data?.way + '' : null}
189   - label="类型"
  247 + label="跟进方式"
190 248 request={async () => {
191 249 const res = await postServiceConstClientWay();
192 250 return enumToSelect(res.data);
... ... @@ -194,7 +252,7 @@ export default ({ data, type, reloadTable }) =&gt; {
194 252 rules={[
195 253 {
196 254 required: true,
197   - message: '请选择跟进类型',
  255 + message: '请选择跟进方式',
198 256 },
199 257 ]}
200 258 ></ProFormSelect>
... ... @@ -242,12 +300,104 @@ export default ({ data, type, reloadTable }) =&gt; {
242 300 <a hidden={!optType[type].readOnly} href={data?.attachments} download>
243 301 下载附件
244 302 </a>
  303 + <ProFormTextArea
  304 + name="comment"
  305 + label="客户评价"
  306 + placeholder="请输入客户评价"
  307 + initialValue={data?.comment}
  308 + readonly={optType[type].readOnly}
  309 + ></ProFormTextArea>
245 310 <ProFormText
246 311 initialValue={data?.attachments}
247 312 name="attachments"
248 313 hidden
249 314 ></ProFormText>
250 315 <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  316 + <div className="styled-text">
  317 + <div className="vertical-line"></div>
  318 + <span className="text">工单指派</span>
  319 + </div>
  320 + <ProFormSelect
  321 + name="ticketsType"
  322 + label="工单类型"
  323 + width="sm"
  324 + placeholder="请输入工单类型"
  325 + readonly={optType[type].readOnly}
  326 + fieldProps={{
  327 + labelInValue: false,
  328 + }}
  329 + initialValue={data?.ticketsType ? data?.ticketsType + '' : null}
  330 + request={async () => {
  331 + return [
  332 + { label: '问题', value: 'QUESTION' },
  333 + { label: '需求', value: 'DEMAND' },
  334 + { label: '建议', value: 'ADVICE' },
  335 + ];
  336 + }}
  337 + />
  338 + <ProFormTextArea
  339 + name="ticketsDetail"
  340 + label="工单详情"
  341 + placeholder="请输入工单详情"
  342 + initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null}
  343 + readonly={optType[type].readOnly}
  344 + ></ProFormTextArea>
  345 + <ProFormUploadDragger
  346 + label="工单附件"
  347 + name="ticketsAttachment"
  348 + action="upload.do"
  349 + hidden={optType[type].readOnly}
  350 + onChange={(info) => {
  351 + const uploadFile = async ({ fileList: newFileList }) => {
  352 + if (newFileList.length > 0) {
  353 + const formData = new FormData();
  354 + formData.append('file', newFileList[0].originFileObj as RcFile);
  355 + const res = await postOrderErpOrderStagesUpload({
  356 + data: formData,
  357 + headers: {
  358 + 'Content-Type':
  359 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  360 + },
  361 + });
  362 + const url = res.data;
  363 + console.log('ticketsAttachments' + JSON.stringify(url));
  364 + form.setFieldValue('ticketsAttachments', url);
  365 + } else {
  366 + form.setFieldValue('ticketsAttachments', null);
  367 + }
  368 + };
  369 + uploadFile(info);
  370 + }}
  371 + max={1}
  372 + />
  373 + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download>
  374 + 下载附件
  375 + </a>
  376 + <ProFormSelect
  377 + name="assignPeople"
  378 + width="sm"
  379 + readonly={optType[type].readOnly}
  380 + fieldProps={{
  381 + labelInValue: false,
  382 + }}
  383 + initialValue={data?.assignPeople ? data?.assignPeople + '' : null}
  384 + label="指派人员"
  385 + request={async () => {
  386 + const res = await postOrderErpUsersListByPage({
  387 + data: {
  388 + pageSize: 10000,
  389 + },
  390 + });
  391 +
  392 + const userOptions = res.data.records
  393 + ? res.data.records.map((user) => ({
  394 + label: user.userName, // 或者使用其他需要的属性
  395 + value: user.userName, // 作为value的字段
  396 + }))
  397 + : [];
  398 + return userOptions;
  399 + }}
  400 + ></ProFormSelect>
251 401 </ModalForm>
252 402 );
253 403 };
... ...
src/pages/Client/Client/Components/ClientModal.tsx
... ... @@ -3,7 +3,9 @@ import {
3 3 postAdminClientAddOrModifyClientComunicationInfo,
4 4 postAdminClientQueryClientPage,
5 5 postOrderErpOrderStagesUpload,
  6 + postOrderErpUsersListByPage,
6 7 postServiceConstClientWay,
  8 + postServiceConstTradeStatus,
7 9 } from '@/services';
8 10 import { enumToSelect } from '@/utils';
9 11 import {
... ... @@ -16,11 +18,10 @@ import {
16 18 } from '@ant-design/pro-components';
17 19 import { Button, Form, message } from 'antd';
18 20 import { RcFile } from 'antd/es/upload';
  21 +import './style.css';
19 22 export default ({ data, type, reloadTable }) => {
20 23 const [form] = Form.useForm();
21 24 const onfinish = async (values) => {
22   - console.log(data, '5656datatest');
23   - console.log(values, '5656...values');
24 25 const res = await postAdminClientAddOrModifyClientComunicationInfo({
25 26 data: {
26 27 ...values,
... ... @@ -111,7 +112,6 @@ export default ({ data, type, reloadTable }) =&gt; {
111 112 groupFilter: 'all',
112 113 },
113 114 });
114   - console.log(data?.datetime, '5656data?.datetime');
115 115 const namesArray = res.data.data.map((item) => item.name);
116 116 return enumToSelect(namesArray);
117 117 }}
... ... @@ -123,9 +123,37 @@ export default ({ data, type, reloadTable }) =&gt; {
123 123 ]}
124 124 disabled
125 125 ></ProFormSelect>
  126 + <ProFormText
  127 + name="contact"
  128 + label="联系人"
  129 + width="sm"
  130 + placeholder="请输入联系人"
  131 + initialValue={data?.content}
  132 + readonly={optType[type].readOnly}
  133 + rules={[
  134 + {
  135 + required: true,
  136 + message: '请输入联系人',
  137 + },
  138 + ]}
  139 + ></ProFormText>
  140 + <ProFormText
  141 + name="contactPhone"
  142 + label="联系电话"
  143 + width="sm"
  144 + placeholder="请输入联系电话"
  145 + initialValue={data?.content}
  146 + readonly={optType[type].readOnly}
  147 + rules={[
  148 + {
  149 + required: true,
  150 + message: '请输入联系电话',
  151 + },
  152 + ]}
  153 + ></ProFormText>
126 154 <ProFormDateTimePicker
127 155 name="datetime"
128   - label="日期"
  156 + label="跟进日期"
129 157 initialValue={data.datetime ? data?.datetime + '' : null}
130 158 placeholder="请选择跟进时间"
131 159 width="sm"
... ... @@ -137,6 +165,27 @@ export default ({ data, type, reloadTable }) =&gt; {
137 165 ]}
138 166 />
139 167 <ProFormSelect
  168 + name="tradeStatus"
  169 + label="跟进状态"
  170 + width="sm"
  171 + placeholder="请输入跟进状态"
  172 + readonly={optType[type].readOnly}
  173 + fieldProps={{
  174 + labelInValue: false,
  175 + }}
  176 + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null}
  177 + rules={[
  178 + {
  179 + required: true,
  180 + message: '请输入跟进状态',
  181 + },
  182 + ]}
  183 + request={async () => {
  184 + const res = await postServiceConstTradeStatus();
  185 + return enumToSelect(res.data);
  186 + }}
  187 + />
  188 + <ProFormSelect
140 189 name="way"
141 190 width="sm"
142 191 readonly={optType[type].readOnly}
... ... @@ -200,12 +249,104 @@ export default ({ data, type, reloadTable }) =&gt; {
200 249 <a hidden={!optType[type].readOnly} href={data?.attachments} download>
201 250 下载附件
202 251 </a>
  252 + <ProFormTextArea
  253 + name="comment"
  254 + label="客户评价"
  255 + placeholder="请输入客户评价"
  256 + initialValue={data?.comment}
  257 + readonly={optType[type].readOnly}
  258 + ></ProFormTextArea>
203 259 <ProFormText
204 260 initialValue={data?.attachments}
205 261 name="attachments"
206 262 hidden
207 263 ></ProFormText>
208 264 <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  265 + <div className="styled-text">
  266 + <div className="vertical-line"></div>
  267 + <span className="text">工单指派</span>
  268 + </div>
  269 + <ProFormSelect
  270 + name="ticketsType"
  271 + label="工单类型"
  272 + width="sm"
  273 + placeholder="请输入工单类型"
  274 + readonly={optType[type].readOnly}
  275 + fieldProps={{
  276 + labelInValue: false,
  277 + }}
  278 + initialValue={data?.type ? data?.type + '' : null}
  279 + request={async () => {
  280 + return [
  281 + { label: '问题', value: 'QUESTION' },
  282 + { label: '需求', value: 'DEMAND' },
  283 + { label: '建议', value: 'ADVICE' },
  284 + ];
  285 + }}
  286 + />
  287 + <ProFormTextArea
  288 + name="ticketsDetail"
  289 + label="工单详情"
  290 + placeholder="请输入工单详情"
  291 + initialValue={data?.detailText ? data?.detailText + '' : null}
  292 + readonly={optType[type].readOnly}
  293 + ></ProFormTextArea>
  294 + <ProFormUploadDragger
  295 + label="工单附件"
  296 + name="ticketsAttachment"
  297 + action="upload.do"
  298 + hidden={optType[type].readOnly}
  299 + onChange={(info) => {
  300 + const uploadFile = async ({ fileList: newFileList }) => {
  301 + if (newFileList.length > 0) {
  302 + const formData = new FormData();
  303 + formData.append('file', newFileList[0].originFileObj as RcFile);
  304 + const res = await postOrderErpOrderStagesUpload({
  305 + data: formData,
  306 + headers: {
  307 + 'Content-Type':
  308 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  309 + },
  310 + });
  311 + const url = res.data;
  312 + console.log('ticketsAttachments' + JSON.stringify(url));
  313 + form.setFieldValue('ticketsAttachments', url);
  314 + } else {
  315 + form.setFieldValue('ticketsAttachments', null);
  316 + }
  317 + };
  318 + uploadFile(info);
  319 + }}
  320 + max={1}
  321 + />
  322 + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download>
  323 + 下载附件
  324 + </a>
  325 + <ProFormSelect
  326 + name="assignPeople"
  327 + width="sm"
  328 + readonly={optType[type].readOnly}
  329 + fieldProps={{
  330 + labelInValue: false,
  331 + }}
  332 + initialValue={data?.assignPeople ? data?.assignPeople + '' : null}
  333 + label="指派人员"
  334 + request={async () => {
  335 + const res = await postOrderErpUsersListByPage({
  336 + data: {
  337 + pageSize: 10000,
  338 + },
  339 + });
  340 +
  341 + const userOptions = res.data.records
  342 + ? res.data.records.map((user) => ({
  343 + label: user.userName, // 或者使用其他需要的属性
  344 + value: user.userName, // 作为value的字段
  345 + }))
  346 + : [];
  347 + return userOptions;
  348 + }}
  349 + ></ProFormSelect>
209 350 </ModalForm>
210 351 );
211 352 };
... ...
src/pages/Client/Client/Components/CommunicationHistoryModal.tsx
... ... @@ -4,6 +4,7 @@ import {
4 4 postAdminClientQueryClientComunicationInfo,
5 5 postAdminClientRemoveClientComunicationInfo,
6 6 postServiceConstClientWay,
  7 + postServiceConstTradeStatus,
7 8 } from '@/services';
8 9 import { enumToSelect } from '@/utils';
9 10 import {
... ... @@ -25,7 +26,6 @@ export default ({ record }) =&gt; {
25 26  
26 27 const reloadInformationHistoryModal = () => {
27 28 actionRef.current.reload(); // 重新加载数据
28   - console.log('5656flush');
29 29  
30 30 // 更新 refreshKey,强制刷新 CommunicationHistoryModal
31 31 setRefreshKey((prevKey) => prevKey + 1);
... ... @@ -56,8 +56,19 @@ export default ({ record }) =&gt; {
56 56 },
57 57 },
58 58 {
59   - title: '内容',
60   - width: 100,
  59 + title: '跟进状态',
  60 + width: 50,
  61 + dataIndex: 'tradeStatus',
  62 + rules: [{ required: true, message: '请选择方式' }],
  63 + render: (text, record) => record.tradeStatusLike, // 显示 wayText
  64 + request: async () => {
  65 + const res = await postServiceConstTradeStatus();
  66 + return enumToSelect(res.data);
  67 + },
  68 + },
  69 + {
  70 + title: '跟进详情',
  71 + width: 80,
61 72 valueType: 'textarea',
62 73 rules: [{ required: true, message: '请输入内容' }],
63 74 dataIndex: 'content',
... ... @@ -65,7 +76,7 @@ export default ({ record }) =&gt; {
65 76 {
66 77 title: '操作',
67 78 valueType: 'option',
68   - width: 50,
  79 + width: 60,
69 80 render: (text, record, _, action) => [
70 81 // <a
71 82 // key="editable"
... ... @@ -112,14 +123,15 @@ export default ({ record }) =&gt; {
112 123 },
113 124 ];
114 125 const [name, setName] = useState(''); // 客户名称
115   - const [contacts, setContacts] = useState(''); // 联系
  126 + const [leaderName, setLeaderName] = useState(''); // 负责
116 127 const [sourceText, setSourceText] = useState(''); // 来源文本
117 128 const [phoneNumber, setPhoneNumber] = useState(''); // 联系电话
118   - const [hasSchemeText, setHasSchemeText] = useState(''); // 报方案状态文本
119   - const [quoteDatetime, setQuoteDatetime] = useState(null); // 报价时间
  129 + const [institutionContactName, setInstitutionContactName] = useState(''); // 联系电话
  130 + const [department, setDepartment] = useState(''); // 联系电话
  131 + const [gradePosition, setGradePosition] = useState(''); // 联系电话
120 132 const [referrers, setReferrers] = useState(''); // 推荐人
121 133 const [requirementsText, setRequirementsText] = useState(''); // 需求文本
122   - const [tradeStatusText, setTradeStatusText] = useState(''); // 跟进状态文本
  134 + const [setTradeStatusText] = useState(''); // 跟进状态文本
123 135 const [levelText, setLevelText] = useState(''); // 客户等级文本
124 136 const [createTime, setCreateTime] = useState(null); // 最新沟通时间
125 137 const [address, setAddress] = useState(''); // 客户地址
... ... @@ -152,11 +164,12 @@ export default ({ record }) =&gt; {
152 164 }
153 165 setRecordSave(record);
154 166 setName(record.name);
155   - setContacts(record.contacts);
  167 + setLeaderName(record.leaderName);
156 168 setSourceText(record.sourceText);
157 169 setPhoneNumber(record.phoneNumber);
158   - setHasSchemeText(record.hasSchemeText);
159   - setQuoteDatetime(record.quoteDatetime);
  170 + setInstitutionContactName(record.institutionContactName);
  171 + setDepartment(record.department);
  172 + setGradePosition(record.gradePosition);
160 173 setReferrers(record.referrers);
161 174 setRequirementsText(record.requirementsText);
162 175 setTradeStatusText(record.tradeStatusText);
... ... @@ -176,8 +189,8 @@ export default ({ record }) =&gt; {
176 189 },
177 190 {
178 191 key: '2',
179   - label: '联系人',
180   - children: contacts, // 联系人
  192 + label: '负责人',
  193 + children: leaderName, // 负责人
181 194 },
182 195 {
183 196 key: '3',
... ... @@ -191,28 +204,28 @@ export default ({ record }) =&gt; {
191 204 },
192 205 {
193 206 key: '5',
194   - label: '是否已报方案',
195   - children: hasSchemeText, // 报方案状态文本
  207 + label: '课题组',
  208 + children: institutionContactName, // 推荐人
196 209 },
197 210 {
198 211 key: '6',
199   - label: '报价时间',
200   - children: quoteDatetime, // 报价时间
  212 + label: '部门',
  213 + children: department, // 推荐人
201 214 },
202 215 {
203 216 key: '7',
204   - label: '推荐人',
205   - children: referrers, // 推荐人
  217 + label: '年级/职位',
  218 + children: gradePosition, // 推荐人
206 219 },
207 220 {
208 221 key: '8',
209   - label: '需求',
210   - children: requirementsText, // 需求文本
  222 + label: '推荐人',
  223 + children: referrers, // 推荐人
211 224 },
212 225 {
213 226 key: '9',
214   - label: '跟进状态',
215   - children: tradeStatusText, // 跟进状态文本
  227 + label: '需求',
  228 + children: requirementsText, // 需求文本
216 229 },
217 230 {
218 231 key: '10',
... ...
src/pages/Client/Client/Components/InformationHistoryModal.tsx
... ... @@ -2,6 +2,7 @@
2 2 import ClientInformationModal from '@/pages/Client/Client/Components/ClientInformationModal';
3 3  
4 4 import {
  5 + getOrderErpTicketsGetTicketsByClientId,
5 6 postAdminClientQueryClientComunicationInfo,
6 7 postAdminClientRemoveClientComunicationInfo,
7 8 } from '@/services/request';
... ... @@ -10,8 +11,6 @@ import { Button, Descriptions, Space } from &#39;antd&#39;;
10 11 import { useEffect, useRef, useState } from 'react';
11 12  
12 13 export default ({ data, reloadTable }) => {
13   - console.log(data, '5656datafirstshowclient');
14   -
15 14 // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示
16 15 const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法
17 16  
... ... @@ -23,23 +22,36 @@ export default ({ data, reloadTable }) =&gt; {
23 22 // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询
24 23 // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询
25 24 // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态
26   - // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询
  25 + const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询
27 26 const [content, setContent] = useState(''); // 跟进详情
28 27 const [createTime, setCreateTime] = useState(null); // 创建时间
29 28 const [attachments, setAttachments] = useState(); //附件
30 29 const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称
  30 + const [ticketsType, setTicketsType] = useState(''); // 附件名称
  31 + const [ticketsDetail, setTicketsDetail] = useState(''); // 附件名称
  32 + const [ticketsAttachment, setTicketsAttachment] = useState(''); // 附件名称
  33 + const [setTicketsAttachmentName] = useState(''); // 附件名称
  34 + const [assignPeople, setAssignPeople] = useState(''); // 附件名称
31 35  
32 36 useEffect(() => {
33 37 const request = async () => {
34   - console.log(data, '5656datasearch');
35 38 const res = await postAdminClientQueryClientComunicationInfo({
36 39 data: {
37 40 id: data.id,
38 41 },
39 42 });
40   - console.log(res, '5656res');
  43 + const resTicket = await getOrderErpTicketsGetTicketsByClientId({
  44 + query: {
  45 + id: data.id,
  46 + },
  47 + });
41 48 const dataSearch = res.data.data[0];
  49 +
42 50 if (dataSearch) {
  51 + data.type = resTicket.data.type;
  52 + data.detailText = resTicket.data.detailText;
  53 + data.annexUrl = resTicket.data.annexUrl;
  54 + data.assignPeople = resTicket.data.assignPeople;
43 55 if (dataSearch.attachments) {
44 56 const url = dataSearch.attachments;
45 57 const match = url.match(/aliyuncs\.com\/(.*?)\?/);
... ... @@ -52,6 +64,23 @@ export default ({ data, reloadTable }) =&gt; {
52 64 setAttachmentsName(decodedStr); // 设置跟进日期
53 65 }
54 66 }
  67 +
  68 + if (dataSearch.ticketsAttachments) {
  69 + const url = dataSearch.ticketsAttachments;
  70 + const match = url.match(/aliyuncs\.com\/(.*?)\?/);
  71 + let decodedStr = '';
  72 +
  73 + if (match) {
  74 + // 获取匹配的字符串并进行解码
  75 + const encodedStr = match[1];
  76 + decodedStr = decodeURIComponent(encodedStr);
  77 + setTicketsAttachmentName(decodedStr);
  78 + }
  79 + }
  80 + setTicketsType(resTicket.data.type);
  81 + setTicketsDetail(resTicket.data.detailText);
  82 + setTicketsAttachment(resTicket.data.annexUrl);
  83 + setAssignPeople(resTicket.data.assignPeople);
55 84 setDatetime(dataSearch.datetime); // 设置跟进日期
56 85 // setDateRange(data.dateRange || []); // 设置跟进时间范围
57 86 setCreateByName(dataSearch.createByName); // 设置跟进人员
... ... @@ -60,13 +89,12 @@ export default ({ data, reloadTable }) =&gt; {
60 89 // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询
61 90 // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询
62 91 // setTradeStatus(data.tradeStatus || ''); // 设置客户状态
63   - // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询
  92 + setTradeStatusLike(data.tradeStatusLike); // 设置客户状态模糊查询
64 93 setContent(dataSearch.content); // 设置跟进详情
65 94 setCreateTime(dataSearch.createTime); // 设置创建时间
66 95 setWay(dataSearch.wayText);
67 96 setAttachments(dataSearch.attachments);
68 97 }
69   - console.log(attachments, '5656attachments');
70 98 };
71 99 request();
72 100 }, []);
... ... @@ -101,9 +129,33 @@ export default ({ data, reloadTable }) =&gt; {
101 129 label: '跟进类型',
102 130 children: way, // 跟进类型
103 131 },
  132 + {
  133 + key: '7',
  134 + label: '跟进状态',
  135 + children: tradeStatusLike, // 跟进类型
  136 + },
  137 + {
  138 + key: '8',
  139 + label: '工单类型',
  140 + children: ticketsType, // 跟进状态
  141 + },
  142 + {
  143 + key: '9',
  144 + label: '工单详情',
  145 + children: ticketsDetail, // 跟进状态
  146 + },
  147 + // {
  148 + // key: '10',
  149 + // label: '工单附件',
  150 + // children: ticketsAttachment, // 跟进状态
  151 + // },
  152 + {
  153 + key: '10',
  154 + label: '指派人员',
  155 + children: assignPeople, // 跟进状态
  156 + },
104 157 ];
105 158 const handleDelete = async () => {
106   - console.log(JSON.stringify(data), '5656record');
107 159 // 调用删除接口
108 160 const success = await postAdminClientRemoveClientComunicationInfo({
109 161 query: {
... ... @@ -142,7 +194,6 @@ export default ({ data, reloadTable }) =&gt; {
142 194 actionRef?.current?.reload(); // 重新加载表格数据
143 195 props.submit();
144 196 reloadTable();
145   - console.log('5656close');
146 197 }}
147 198 type={'modify'}
148 199 onFinish={() => {
... ... @@ -178,10 +229,61 @@ export default ({ data, reloadTable }) =&gt; {
178 229 }}
179 230 >
180 231 <Descriptions items={items} column={1} />
181   - {attachmentsName && (
  232 + {/* {attachmentsName && (
182 233 <a href={attachments} download>
183 234 附件:{attachmentsName}
184 235 </a>
  236 + )} */}
  237 + {attachmentsName && (
  238 + <div>
  239 + {attachmentsName.endsWith('.png') ||
  240 + attachmentsName.endsWith('.jpg') ? (
  241 + <>
  242 + <img
  243 + src={attachments}
  244 + alt={attachmentsName}
  245 + style={{ maxWidth: '100%', height: 'auto' }}
  246 + />
  247 + <div></div>
  248 + <a href={attachments} download>
  249 + 附件:{attachmentsName}
  250 + </a>
  251 + </>
  252 + ) : (
  253 + <a href={attachments} download>
  254 + 附件:{attachmentsName}
  255 + </a>
  256 + )}
  257 + </div>
  258 + )}
  259 +
  260 + <div></div>
  261 + {/* {ticketsAttachment && (
  262 + <a href={ticketsAttachment} download>
  263 + 工单附件:{ticketsAttachment}
  264 + </a>
  265 + )} */}
  266 + {ticketsAttachment && (
  267 + <div>
  268 + {ticketsAttachment.includes('jpg') ||
  269 + ticketsAttachment.includes('png') ? (
  270 + <>
  271 + <img
  272 + src={ticketsAttachment}
  273 + alt={ticketsAttachment}
  274 + style={{ maxWidth: '100%', height: 'auto' }}
  275 + />
  276 + <div></div>
  277 + <a href={ticketsAttachment} download>
  278 + 工单附件:{ticketsAttachment}
  279 + </a>
  280 + </>
  281 + ) : (
  282 + <a href={ticketsAttachment} download>
  283 + 工单附件:{ticketsAttachment}
  284 + </a>
  285 + )}
  286 + </div>
185 287 )}
186 288 </ModalForm>
187 289 </Space>
... ...
src/pages/Client/Client/Components/style.css 0 → 100644
  1 +.styled-text {
  2 + display: flex;
  3 + align-items: center;
  4 + margin-bottom: 20px;
  5 +}
  6 +
  7 +.vertical-line {
  8 + width: 2px; /* 线的宽度 */
  9 + height: 20px; /* 线的高度 */
  10 + background-color: black; /* 线的颜色 */
  11 + margin-right: 10px; /* 线与文本之间的间距 */
  12 +}
  13 +
  14 +.text {
  15 + font-size: 20px; /* 文本大小 */
  16 + font-family: Arial, sans-serif; /* 字体样式 */
  17 + color: black; /* 文本颜色 */
  18 +}
... ...
src/pages/Client/Client/index.tsx
... ... @@ -8,9 +8,8 @@ import {
8 8 postAdminClientGetStatisticalData,
9 9 postAdminClientQueryClientPage,
10 10 postServiceConstClientLevels,
11   - postServiceConstClientRequirements,
12 11 postServiceConstClientSource,
13   - postServiceConstTradeStatus,
  12 + postServiceOrderQueryCustomerInformation,
14 13 } from '@/services';
15 14 import { downloadFile } from '@/services/order';
16 15 import { enumToSelect } from '@/utils';
... ... @@ -41,6 +40,12 @@ const columns = [
41 40 // hideInSearch: true,
42 41 // },
43 42 {
  43 + title: '客户名称',
  44 + dataIndex: 'nameLike',
  45 + valueType: 'Text',
  46 + hideInTable: true,
  47 + },
  48 + {
44 49 title: '客户地址',
45 50 width: 250,
46 51 ellipsis: true,
... ... @@ -48,10 +53,10 @@ const columns = [
48 53 hideInSearch: false,
49 54 },
50 55 {
51   - title: '联系人',
  56 + title: '负责人',
52 57 width: 150,
53 58 ellipsis: true,
54   - dataIndex: 'contacts',
  59 + dataIndex: 'leaderName',
55 60 hideInSearch: false,
56 61 },
57 62 {
... ... @@ -62,75 +67,105 @@ const columns = [
62 67 hideInSearch: true,
63 68 },
64 69 {
65   - title: '客户来源',
  70 + title: '课题组',
  71 + dataIndex: 'institutionContactName',
66 72 width: 150,
67 73 ellipsis: true,
68   - dataIndex: 'sourceText',
69 74 hideInSearch: true,
70 75 },
71 76 {
72   - title: '客户来源',
  77 + title: '课题组',
  78 + dataIndex: 'institutionContactName',
73 79 valueType: 'select',
74 80 hideInTable: true,
75   - dataIndex: 'source',
76   - request: async () => {
77   - const res = await postServiceConstClientSource();
78   - return enumToSelect(res.data);
  81 + fieldProps: {
  82 + showSearch: true,
  83 + // mode: 'tags', // 允许自定义输入
  84 + },
  85 + request: async (value, { params }) => {
  86 + const keywords = value.keyWords;
  87 + const { data } = await postServiceOrderQueryCustomerInformation({
  88 + data: {
  89 + name: 'institutionContactName',
  90 + institutionContactName: keywords,
  91 + },
  92 + params: params,
  93 + });
  94 + let options = data
  95 + .filter((c: any) => {
  96 + return c.orderName === 'institutionCustomerUser';
  97 + })
  98 + .map((item: any) => {
  99 + return {
  100 + label: item.orderValue,
  101 + value: item.orderValue,
  102 + };
  103 + });
  104 + return options;
79 105 },
80 106 },
81 107 {
82   - title: '推荐人',
83   - dataIndex: 'referrers',
  108 + title: '部门',
84 109 width: 150,
85 110 ellipsis: true,
  111 + dataIndex: 'department',
86 112 hideInSearch: true,
87 113 },
88 114 {
89   - title: '客户需求',
90   - width: 240,
  115 + title: '年级/职位',
  116 + width: 150,
91 117 ellipsis: true,
92   - dataIndex: 'requirementsText',
  118 + dataIndex: 'gradePosition',
93 119 hideInSearch: true,
94 120 },
95 121 {
96   - title: '客户需求',
97   - dataIndex: 'requirements',
98   - valueType: 'select',
99   - hideInTable: true,
100   - 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   - // }
108   - return enumToSelect(res.data);
109   - },
110   - },
111   - {
112   - title: '是否已报方案',
  122 + title: '客户来源',
113 123 width: 150,
114 124 ellipsis: true,
115   - dataIndex: 'hasSchemeText',
  125 + dataIndex: 'sourceText',
116 126 hideInSearch: true,
117 127 },
118 128 {
119   - title: '报价时间',
120   - key: 'since',
121   - width: 150,
122   - ellipsis: true,
123   - dataIndex: 'quoteDatetime',
124   - valueType: 'date',
125   - hideInSearch: true,
  129 + title: '客户来源',
  130 + valueType: 'select',
  131 + hideInTable: true,
  132 + dataIndex: 'source',
  133 + request: async () => {
  134 + const res = await postServiceConstClientSource();
  135 + return enumToSelect(res.data);
  136 + },
126 137 },
127 138 {
128   - title: '跟进状态',
  139 + title: '推荐人',
  140 + dataIndex: 'referrers',
129 141 width: 150,
130 142 ellipsis: true,
131   - dataIndex: 'tradeStatusText',
132 143 hideInSearch: true,
133 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 + // },
134 169 {
135 170 title: '客户等级',
136 171 width: 150,
... ... @@ -165,41 +200,30 @@ const columns = [
165 200 // valueType: 'dateTime',
166 201 // hideInSearch: true,
167 202 // },
168   - {
169   - title: '客户名称',
170   - dataIndex: 'nameLike',
171   - valueType: 'Text',
172   - hideInTable: true,
173   - },
174 203 // {
175 204 // title: '单位名称',
176 205 // dataIndex: 'companyNameLike',
177 206 // valueType: 'Text',
178 207 // hideInTable: true,
179 208 // },
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   - },
  209 + // {
  210 + // title: '联系电话',
  211 + // dataIndex: 'phoneNumberLike',
  212 + // valueType: 'Text',
  213 + // hideInTable: true,
  214 + // },
  215 + // {
  216 + // title: '部门',
  217 + // dataIndex: 'department',
  218 + // valueType: 'Text',
  219 + // hideInTable: false,
  220 + // },
  221 + // {
  222 + // title: '年级/职位',
  223 + // dataIndex: 'gradePosition',
  224 + // valueType: 'Text',
  225 + // hideInTable: false,
  226 + // },
203 227 {
204 228 title: '客户等级',
205 229 dataIndex: 'level',
... ... @@ -218,25 +242,30 @@ const columns = [
218 242 },
219 243 },
220 244 {
221   - title: '跟进状态',
222   - dataIndex: 'tradeStatus',
223   - valueType: 'select',
  245 + title: '创建时间',
  246 + valueType: 'dateRange',
224 247 hideInTable: true,
225   - request: async () => {
226   - const res = await postServiceConstTradeStatus();
227   - return enumToSelect(res.data);
  248 + search: {
  249 + transform: (value) => {
  250 + if (value) {
  251 + return {
  252 + createTimeGe: value[0],
  253 + createTimeLe: value[1],
  254 + };
  255 + }
  256 + },
228 257 },
229 258 },
230 259 {
231   - title: '创建时间',
  260 + title: '最新跟进时间',
232 261 valueType: 'dateRange',
233 262 hideInTable: true,
234 263 search: {
235 264 transform: (value) => {
236 265 if (value) {
237 266 return {
238   - createTimeGe: value[0],
239   - createTimeLe: value[1],
  267 + updateTimeGe: value[0],
  268 + updateTimeLe: value[1],
240 269 };
241 270 }
242 271 },
... ... @@ -249,7 +278,6 @@ const columns = [
249 278 width: 200,
250 279 render: (text, record, index, action) => {
251 280 const handleDelete = async () => {
252   - console.log(JSON.stringify(record), '5656record1');
253 281 // 调用删除接口
254 282 const success = await postAdminClientDeleteAdminClient({
255 283 query: {
... ... @@ -260,7 +288,6 @@ const columns = [
260 288 action.reload(); // 刷新表格
261 289 }
262 290 };
263   - console.log(JSON.stringify(record), '5656record2');
264 291 return [
265 292 <CommunicationHistoryModal
266 293 key={'communicationHistory'}
... ... @@ -313,7 +340,7 @@ export default () =&gt; {
313 340 // const [groupFilterOptions, setGroupFilterDataOptions] = useState([]);
314 341 const actionRef = useRef<ActionType>();
315 342 //获得预警/全部数量
316   - const [clientStatistic, setClientStatistic] = useState([]);
  343 + const [setClientStatistic] = useState([]);
317 344 // const [allClientStatistic, setAllClientStatistic] = useState([]);
318 345 const [warningClientStatistic, setWarningClientStatistic] = useState([]);
319 346 // const reloadTable = () => {
... ... @@ -324,10 +351,9 @@ export default () =&gt; {
324 351 let statisticalData = await postAdminClientGetStatisticalData();
325 352 console.log('stati' + JSON.stringify(statisticalData.data));
326 353 setClientStatistic(statisticalData.data);
327   - setWarningClientStatistic(statisticalData.data[1].value);
  354 + setWarningClientStatistic(statisticalData?.data[1].value);
328 355 // setAllClientStatistic(statisticalData.data[0].value);
329 356 setTimeout(() => {
330   - console.log(clientStatistic, '5656groupFilterOptions1');
331 357 // groupFilterOptions[0].label = groupFilterOptions[0].label + '(' + clientStatistic + ')';
332 358 }, 100);
333 359 actionRef.current?.reload(); // 可能需要在这里刷新
... ... @@ -361,8 +387,6 @@ export default () =&gt; {
361 387 // }, []);
362 388 useEffect(() => {
363 389 // console.log(groupFilterOptions, '5656groupFilterOptions2');
364   - console.log(clientStatistic, '5656clientStatistic');
365   - console.log(warningClientStatistic, '5656warningClientStatistic');
366 390 actionRef.current?.reload();
367 391 }, [groupFilter]);
368 392 return (
... ... @@ -411,7 +435,6 @@ export default () =&gt; {
411 435 'POST',
412 436 values,
413 437 () => {
414   - console.log(searchConfig, '5656searchConfig');
415 438 messageApi.destroy();
416 439 },
417 440 );
... ...
src/pages/Client/FollowRecord/Components/ClientModal.tsx
... ... @@ -3,7 +3,9 @@ import {
3 3 postAdminClientAddOrModifyClientComunicationInfo,
4 4 postAdminClientQueryClientPage,
5 5 postOrderErpOrderStagesUpload,
  6 + postOrderErpUsersListByPage,
6 7 postServiceConstClientWay,
  8 + postServiceConstTradeStatus,
7 9 } from '@/services';
8 10 import { enumToSelect } from '@/utils';
9 11 import {
... ... @@ -16,6 +18,7 @@ import {
16 18 } from '@ant-design/pro-components';
17 19 import { Button, Form, message } from 'antd';
18 20 import { RcFile } from 'antd/es/upload';
  21 +import './style.css';
19 22 export default ({ data, type, reloadTable }) => {
20 23 const [form] = Form.useForm();
21 24 const onfinish = async (values) => {
... ... @@ -37,6 +40,7 @@ export default ({ data, type, reloadTable }) =&gt; {
37 40 const res = await postAdminClientAddOrModifyClientComunicationInfo({
38 41 data: {
39 42 ...values,
  43 + ticketsAttachments: form.getFieldValue('ticketsAttachments'),
40 44 clientId: matchedId,
41 45 },
42 46 });
... ... @@ -47,10 +51,10 @@ export default ({ data, type, reloadTable }) =&gt; {
47 51 }
48 52 // 不返回不会关闭弹框
49 53 };
  54 +
50 55 const editOnfinish = async (values) => {
51 56 // setEditClientId(data.clientId);
52 57 values.clientId = data.clientId;
53   - console.log(values, '5656editClientId');
54 58  
55 59 // const resSearchId = await postAdminClientQueryClientPage({
56 60 // data: {
... ... @@ -60,10 +64,15 @@ export default ({ data, type, reloadTable }) =&gt; {
60 64 // const matchingItem = resSearchId.data.data.find(
61 65 // (item) => item.id === values.name,
62 66 // );
63   -
64 67 const res = await postAdminClientAddOrModifyClientComunicationInfo({
65 68 data: {
66 69 ...values,
  70 + // ticketsAttachments: form.getFieldValue("ticketsAttachments"),
  71 + ticketsAttachments:
  72 + form.getFieldValue('ticketsAttachments') !== undefined
  73 + ? form.getFieldValue('ticketsAttachments')
  74 + : data?.ticketsAttachments,
  75 + // ticketsAttachments: data?.annexUrl,
67 76 },
68 77 });
69 78 if (res.result === RESPONSE_CODE.SUCCESS) {
... ... @@ -140,7 +149,6 @@ export default ({ data, type, reloadTable }) =&gt; {
140 149 groupFilter: 'all',
141 150 },
142 151 });
143   - console.log(data, '5656data?.nameedit');
144 152 // const namesArray = res.data.data.map((item) => item.name);
145 153 // const formattedObject = res.data.data.reduce((acc, name) => {
146 154 // acc[name] = name; // 将名称作为键和值
... ... @@ -165,20 +173,69 @@ export default ({ data, type, reloadTable }) =&gt; {
165 173 },
166 174 ]}
167 175 ></ProFormSelect>
  176 + <ProFormText
  177 + name="contact"
  178 + label="联系人"
  179 + width="sm"
  180 + placeholder="请输入联系人"
  181 + initialValue={data?.content}
  182 + readonly={optType[type].readOnly}
  183 + rules={[
  184 + {
  185 + required: true,
  186 + message: '请输入联系人',
  187 + },
  188 + ]}
  189 + ></ProFormText>
  190 + <ProFormText
  191 + name="contactPhone"
  192 + label="联系电话"
  193 + width="sm"
  194 + placeholder="请输入联系电话"
  195 + initialValue={data?.content}
  196 + readonly={optType[type].readOnly}
  197 + rules={[
  198 + {
  199 + required: true,
  200 + message: '请输入联系电话',
  201 + },
  202 + ]}
  203 + ></ProFormText>
168 204 <ProFormDateTimePicker
169 205 name="datetime"
170   - label="日期"
  206 + label="跟进日期"
171 207 initialValue={data ? data?.datetime + '' : null}
172 208 placeholder="请选择跟进时间"
173 209 width="sm"
174 210 rules={[
175 211 {
176 212 required: true,
177   - message: '请选择日期',
  213 + message: '请选择跟进日期',
178 214 },
179 215 ]}
180 216 />
181 217 <ProFormSelect
  218 + name="tradeStatus"
  219 + label="跟进状态"
  220 + width="sm"
  221 + placeholder="请输入跟进状态"
  222 + readonly={optType[type].readOnly}
  223 + fieldProps={{
  224 + labelInValue: false,
  225 + }}
  226 + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null}
  227 + rules={[
  228 + {
  229 + required: true,
  230 + message: '请输入跟进状态',
  231 + },
  232 + ]}
  233 + request={async () => {
  234 + const res = await postServiceConstTradeStatus();
  235 + return enumToSelect(res.data);
  236 + }}
  237 + />
  238 + <ProFormSelect
182 239 name="way"
183 240 width="sm"
184 241 readonly={optType[type].readOnly}
... ... @@ -186,7 +243,7 @@ export default ({ data, type, reloadTable }) =&gt; {
186 243 labelInValue: false,
187 244 }}
188 245 initialValue={data?.way ? data?.way + '' : null}
189   - label="类型"
  246 + label="跟进方式"
190 247 request={async () => {
191 248 const res = await postServiceConstClientWay();
192 249 return enumToSelect(res.data);
... ... @@ -194,20 +251,20 @@ export default ({ data, type, reloadTable }) =&gt; {
194 251 rules={[
195 252 {
196 253 required: true,
197   - message: '请选择跟进类型',
  254 + message: '请选择跟进方式',
198 255 },
199 256 ]}
200 257 ></ProFormSelect>
201 258 <ProFormTextArea
202 259 name="content"
203   - label="详情"
204   - placeholder="请输入详情"
  260 + label="跟进详情"
  261 + placeholder="请输入跟进详情"
205 262 initialValue={data?.content}
206 263 readonly={optType[type].readOnly}
207 264 rules={[
208 265 {
209 266 required: true,
210   - message: '请输入详情',
  267 + message: '请输入跟进详情',
211 268 },
212 269 ]}
213 270 ></ProFormTextArea>
... ... @@ -242,12 +299,104 @@ export default ({ data, type, reloadTable }) =&gt; {
242 299 <a hidden={!optType[type].readOnly} href={data?.attachments} download>
243 300 下载附件
244 301 </a>
  302 + <ProFormTextArea
  303 + name="comment"
  304 + label="客户评价"
  305 + placeholder="请输入客户评价"
  306 + initialValue={data?.comment}
  307 + readonly={optType[type].readOnly}
  308 + ></ProFormTextArea>
245 309 <ProFormText
246 310 initialValue={data?.attachments}
247 311 name="attachments"
248 312 hidden
249 313 ></ProFormText>
250 314 <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  315 + <div className="styled-text">
  316 + <div className="vertical-line"></div>
  317 + <span className="text">工单指派</span>
  318 + </div>
  319 + <ProFormSelect
  320 + name="ticketsType"
  321 + label="工单类型"
  322 + width="sm"
  323 + placeholder="请输入工单类型"
  324 + readonly={optType[type].readOnly}
  325 + fieldProps={{
  326 + labelInValue: false,
  327 + }}
  328 + initialValue={data?.ticketsType ? data?.ticketsType + '' : null}
  329 + request={async () => {
  330 + return [
  331 + { label: '问题', value: 'QUESTION' },
  332 + { label: '需求', value: 'DEMAND' },
  333 + { label: '建议', value: 'ADVICE' },
  334 + ];
  335 + }}
  336 + />
  337 + <ProFormTextArea
  338 + name="ticketsDetail"
  339 + label="工单详情"
  340 + placeholder="请输入工单详情"
  341 + initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null}
  342 + readonly={optType[type].readOnly}
  343 + ></ProFormTextArea>
  344 + <ProFormUploadDragger
  345 + label="工单附件"
  346 + name="ticketsAttachment"
  347 + action="upload.do"
  348 + hidden={optType[type].readOnly}
  349 + onChange={(info) => {
  350 + const uploadFile = async ({ fileList: newFileList }) => {
  351 + if (newFileList.length > 0) {
  352 + const formData = new FormData();
  353 + formData.append('file', newFileList[0].originFileObj as RcFile);
  354 + const res = await postOrderErpOrderStagesUpload({
  355 + data: formData,
  356 + headers: {
  357 + 'Content-Type':
  358 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  359 + },
  360 + });
  361 + const url = res.data;
  362 + console.log('ticketsAttachments' + JSON.stringify(url));
  363 + form.setFieldValue('ticketsAttachments', url);
  364 + } else {
  365 + form.setFieldValue('ticketsAttachments', null);
  366 + }
  367 + };
  368 + uploadFile(info);
  369 + }}
  370 + max={1}
  371 + />
  372 + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download>
  373 + {/* <a href={data?.annexUrl} download> */}
  374 + 下载附件
  375 + </a>
  376 + <ProFormSelect
  377 + name="assignPeople"
  378 + width="sm"
  379 + readonly={optType[type].readOnly}
  380 + fieldProps={{
  381 + labelInValue: false,
  382 + }}
  383 + initialValue={data?.assignPeople ? data?.assignPeople + '' : null}
  384 + label="指派人员"
  385 + request={async () => {
  386 + const res = await postOrderErpUsersListByPage({
  387 + data: {
  388 + pageSize: 10000,
  389 + },
  390 + });
  391 + const userOptions = res.data.records
  392 + ? res.data.records.map((user) => ({
  393 + label: user.userName, // 或者使用其他需要的属性
  394 + value: user.userName, // 作为value的字段
  395 + }))
  396 + : [];
  397 + return userOptions;
  398 + }}
  399 + ></ProFormSelect>
251 400 </ModalForm>
252 401 );
253 402 };
... ...
src/pages/Client/FollowRecord/Components/ClientModal2.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postAdminClientAddOrModifyClientComunicationInfo,
  4 + postAdminClientQueryClientPage,
  5 + postOrderErpOrderStagesUpload,
  6 + postOrderErpUsersListByPage,
  7 + postServiceConstClientWay,
  8 + postServiceConstTradeStatus,
  9 +} from '@/services';
  10 +import { enumToSelect } from '@/utils';
  11 +import {
  12 + ModalForm,
  13 + ProFormDateTimePicker,
  14 + ProFormSelect,
  15 + ProFormText,
  16 + ProFormTextArea,
  17 + ProFormUploadDragger,
  18 +} from '@ant-design/pro-components';
  19 +import { Button, Form, message } from 'antd';
  20 +import { RcFile } from 'antd/es/upload';
  21 +import './style.css';
  22 +export default ({ data, type, reloadTable }) => {
  23 + const [form] = Form.useForm();
  24 + const onfinish = async (values) => {
  25 + const resSearchId = await postAdminClientQueryClientPage({
  26 + data: {
  27 + groupFilter: 'all',
  28 + },
  29 + });
  30 + const matchingItem = resSearchId.data.data.find(
  31 + (item) => item.id === values.name,
  32 + );
  33 + let matchedId;
  34 + if (matchingItem) {
  35 + matchedId = matchingItem.id; // 匹配成功,取出 id
  36 + values.name = matchingItem.name;
  37 + } else {
  38 + matchedId = null; // 如果没有匹配项,可以设置为 null 或其他值
  39 + }
  40 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  41 + data: {
  42 + ...values,
  43 + ticketsAttachments: form.getFieldValue('ticketsAttachments'),
  44 + clientId: matchedId,
  45 + },
  46 + });
  47 + if (res.result === RESPONSE_CODE.SUCCESS) {
  48 + message.success('新增成功');
  49 + reloadTable();
  50 + return true;
  51 + }
  52 + // 不返回不会关闭弹框
  53 + };
  54 +
  55 + const editOnfinish = async (values) => {
  56 + // setEditClientId(data.clientId);
  57 + values.clientId = data.clientId;
  58 +
  59 + // const resSearchId = await postAdminClientQueryClientPage({
  60 + // data: {
  61 + // groupFilter: 'all',
  62 + // },
  63 + // });
  64 + // const matchingItem = resSearchId.data.data.find(
  65 + // (item) => item.id === values.name,
  66 + // );
  67 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  68 + data: {
  69 + ...values,
  70 + // ticketsAttachments: form.getFieldValue("ticketsAttachments"),
  71 + ticketsAttachments:
  72 + form.getFieldValue('ticketsAttachments') !== undefined
  73 + ? form.getFieldValue('ticketsAttachments')
  74 + : data?.ticketsAttachments,
  75 + // ticketsAttachments: data?.annexUrl,
  76 + },
  77 + });
  78 + if (res.result === RESPONSE_CODE.SUCCESS) {
  79 + message.success('新增成功');
  80 + reloadTable();
  81 + return true;
  82 + }
  83 + // 不返回不会关闭弹框
  84 + };
  85 + const optType = {
  86 + add: {
  87 + readOnly: false,
  88 + title: '新增跟进记录',
  89 + button: (
  90 + <Button size={'middle'} type="primary">
  91 + 新增
  92 + </Button>
  93 + ),
  94 + onFinish: onfinish,
  95 + },
  96 + modify: {
  97 + readOnly: false,
  98 + title: '修改跟进记录',
  99 + button: (
  100 + <Button size={'middle'} type="primary">
  101 + 编辑
  102 + </Button>
  103 + ),
  104 + onFinish: editOnfinish,
  105 + },
  106 + detail: {
  107 + readOnly: true,
  108 + title: '查看跟进记录',
  109 + button: (
  110 + <Button size={'middle'} type="primary" color="red">
  111 + 查看
  112 + </Button>
  113 + ),
  114 + onFinish: () => {},
  115 + },
  116 + };
  117 + return (
  118 + <ModalForm
  119 + title={optType[type].title}
  120 + resize={{
  121 + onResize() {
  122 + console.log('resize!');
  123 + },
  124 + maxWidth: window.innerWidth * 0.8,
  125 + minWidth: 400,
  126 + }}
  127 + form={form}
  128 + trigger={optType[type].button}
  129 + autoFocusFirstInput
  130 + drawerProps={{
  131 + destroyOnClose: true,
  132 + }}
  133 + submitTimeout={2000}
  134 + onFinish={optType[type].onFinish}
  135 + >
  136 + <ProFormSelect
  137 + name="name"
  138 + readonly={optType[type].readOnly}
  139 + fieldProps={{
  140 + labelInValue: false,
  141 + disabled: type === 'modify',
  142 + }}
  143 + initialValue={data ? data?.clientName + '' : null}
  144 + label="客户"
  145 + width="sm"
  146 + request={async () => {
  147 + const res = await postAdminClientQueryClientPage({
  148 + data: {
  149 + groupFilter: 'all',
  150 + },
  151 + });
  152 + // const namesArray = res.data.data.map((item) => item.name);
  153 + // const formattedObject = res.data.data.reduce((acc, name) => {
  154 + // acc[name] = name; // 将名称作为键和值
  155 + // return acc;
  156 + // }, {});
  157 + // console.log(namesArray, '5656namesArray');
  158 + // const formattedObject = res.data.data.reduce((acc, item) => {
  159 + // acc[item.name] = item.name; // 使用 name 作为键,id 作为值
  160 + // return acc;
  161 + // }, {});
  162 + // return enumToSelect(formattedObject);
  163 + const options = res.data.data.reduce((acc, item) => {
  164 + acc.push({ label: item.name, value: item.id }); // 使用 name 作为 label,id 作为 value
  165 + return acc;
  166 + }, []);
  167 + return options;
  168 + }}
  169 + rules={[
  170 + {
  171 + required: true,
  172 + message: '请选择客户',
  173 + },
  174 + ]}
  175 + ></ProFormSelect>
  176 + <ProFormText
  177 + name="contact"
  178 + label="联系人"
  179 + width="sm"
  180 + placeholder="请输入联系人"
  181 + initialValue={data?.content}
  182 + readonly={optType[type].readOnly}
  183 + rules={[
  184 + {
  185 + required: true,
  186 + message: '请输入联系人',
  187 + },
  188 + ]}
  189 + ></ProFormText>
  190 + <ProFormText
  191 + name="contactPhone"
  192 + label="联系电话"
  193 + width="sm"
  194 + placeholder="请输入联系电话"
  195 + initialValue={data?.content}
  196 + readonly={optType[type].readOnly}
  197 + rules={[
  198 + {
  199 + required: true,
  200 + message: '请输入联系电话',
  201 + },
  202 + ]}
  203 + ></ProFormText>
  204 + <ProFormDateTimePicker
  205 + name="datetime"
  206 + label="跟进日期"
  207 + initialValue={data ? data?.datetime + '' : null}
  208 + placeholder="请选择跟进时间"
  209 + width="sm"
  210 + rules={[
  211 + {
  212 + required: true,
  213 + message: '请选择跟进日期',
  214 + },
  215 + ]}
  216 + />
  217 + <ProFormSelect
  218 + name="tradeStatus"
  219 + label="跟进状态"
  220 + width="sm"
  221 + placeholder="请输入跟进状态"
  222 + readonly={optType[type].readOnly}
  223 + fieldProps={{
  224 + labelInValue: false,
  225 + }}
  226 + initialValue={data?.tradeStatus ? data?.tradeStatus + '' : null}
  227 + rules={[
  228 + {
  229 + required: true,
  230 + message: '请输入跟进状态',
  231 + },
  232 + ]}
  233 + request={async () => {
  234 + const res = await postServiceConstTradeStatus();
  235 + return enumToSelect(res.data);
  236 + }}
  237 + />
  238 + <ProFormSelect
  239 + name="way"
  240 + width="sm"
  241 + readonly={optType[type].readOnly}
  242 + fieldProps={{
  243 + labelInValue: false,
  244 + }}
  245 + initialValue={data?.way ? data?.way + '' : null}
  246 + label="跟进方式"
  247 + request={async () => {
  248 + const res = await postServiceConstClientWay();
  249 + return enumToSelect(res.data);
  250 + }}
  251 + rules={[
  252 + {
  253 + required: true,
  254 + message: '请选择跟进方式',
  255 + },
  256 + ]}
  257 + ></ProFormSelect>
  258 + <ProFormTextArea
  259 + name="content"
  260 + label="跟进详情"
  261 + placeholder="请输入跟进详情"
  262 + initialValue={data?.content}
  263 + readonly={optType[type].readOnly}
  264 + rules={[
  265 + {
  266 + required: true,
  267 + message: '请输入跟进详情',
  268 + },
  269 + ]}
  270 + ></ProFormTextArea>
  271 + <ProFormUploadDragger
  272 + label="附件"
  273 + name="attachment"
  274 + action="upload.do"
  275 + hidden={optType[type].readOnly}
  276 + onChange={(info) => {
  277 + const uploadFile = async ({ fileList: newFileList }) => {
  278 + if (newFileList.length > 0) {
  279 + const formData = new FormData();
  280 + formData.append('file', newFileList[0].originFileObj as RcFile);
  281 + const res = await postOrderErpOrderStagesUpload({
  282 + data: formData,
  283 + headers: {
  284 + 'Content-Type':
  285 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  286 + },
  287 + });
  288 + const url = res.data;
  289 + console.log('attachments' + JSON.stringify(url));
  290 + form.setFieldValue('attachments', url);
  291 + } else {
  292 + form.setFieldValue('attachments', null);
  293 + }
  294 + };
  295 + uploadFile(info);
  296 + }}
  297 + max={1}
  298 + />
  299 + <a hidden={!optType[type].readOnly} href={data?.attachments} download>
  300 + 下载附件
  301 + </a>
  302 + <ProFormTextArea
  303 + name="comment"
  304 + label="客户评价"
  305 + placeholder="请输入客户评价"
  306 + initialValue={data?.comment}
  307 + readonly={optType[type].readOnly}
  308 + ></ProFormTextArea>
  309 + <ProFormText
  310 + initialValue={data?.attachments}
  311 + name="attachments"
  312 + hidden
  313 + ></ProFormText>
  314 + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  315 + <div className="styled-text">
  316 + <div className="vertical-line"></div>
  317 + <span className="text">工单指派</span>
  318 + </div>
  319 + <ProFormSelect
  320 + name="ticketsType"
  321 + label="工单类型"
  322 + width="sm"
  323 + placeholder="请输入工单类型"
  324 + readonly={optType[type].readOnly}
  325 + fieldProps={{
  326 + labelInValue: false,
  327 + }}
  328 + initialValue={data?.ticketsType ? data?.ticketsType + '' : null}
  329 + request={async () => {
  330 + return [
  331 + { label: '问题', value: 'QUESTION' },
  332 + { label: '需求', value: 'DEMAND' },
  333 + { label: '建议', value: 'ADVICE' },
  334 + ];
  335 + }}
  336 + />
  337 + <ProFormTextArea
  338 + name="ticketsDetail"
  339 + label="工单详情"
  340 + placeholder="请输入工单详情"
  341 + initialValue={data?.ticketsDetail ? data?.ticketsDetail + '' : null}
  342 + readonly={optType[type].readOnly}
  343 + ></ProFormTextArea>
  344 + <ProFormUploadDragger
  345 + label="工单附件"
  346 + name="ticketsAttachment"
  347 + action="upload.do"
  348 + hidden={optType[type].readOnly}
  349 + onChange={(info) => {
  350 + const uploadFile = async ({ fileList: newFileList }) => {
  351 + if (newFileList.length > 0) {
  352 + const formData = new FormData();
  353 + formData.append('file', newFileList[0].originFileObj as RcFile);
  354 + const res = await postOrderErpOrderStagesUpload({
  355 + data: formData,
  356 + headers: {
  357 + 'Content-Type':
  358 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  359 + },
  360 + });
  361 + const url = res.data;
  362 + console.log('ticketsAttachments' + JSON.stringify(url));
  363 + form.setFieldValue('ticketsAttachments', url);
  364 + } else {
  365 + form.setFieldValue('ticketsAttachments', null);
  366 + }
  367 + };
  368 + uploadFile(info);
  369 + }}
  370 + max={1}
  371 + />
  372 + <a hidden={!optType[type].readOnly} href={data?.orderAttachment} download>
  373 + {/* <a href={data?.annexUrl} download> */}
  374 + 下载附件
  375 + </a>
  376 + <ProFormSelect
  377 + name="assignPeople"
  378 + width="sm"
  379 + readonly={optType[type].readOnly}
  380 + fieldProps={{
  381 + labelInValue: false,
  382 + }}
  383 + initialValue={data?.assignPeople ? data?.assignPeople + '' : null}
  384 + label="指派人员"
  385 + request={async () => {
  386 + const res = await postOrderErpUsersListByPage({
  387 + data: {
  388 + pageSize: 10000,
  389 + },
  390 + });
  391 + const userOptions = res.data.records
  392 + ? res.data.records.map((user) => ({
  393 + label: user.userName, // 或者使用其他需要的属性
  394 + value: user.userName, // 作为value的字段
  395 + }))
  396 + : [];
  397 + return userOptions;
  398 + }}
  399 + ></ProFormSelect>
  400 + </ModalForm>
  401 + );
  402 +};
... ...
src/pages/Client/FollowRecord/Components/CommunicationHistoryModal.tsx
1 1 import ClientModal from '@/pages/Client/FollowRecord/Components/ClientModal';
2 2 import {
  3 + getOrderErpTicketsGetTicketsByClientId,
3 4 postAdminClientQueryClientComunicationInfo,
4 5 postAdminClientRemoveClientComunicationInfo,
5 6 } from '@/services/request';
... ... @@ -8,8 +9,6 @@ import { Button, Descriptions, Space } from &#39;antd&#39;;
8 9 import { useEffect, useRef, useState } from 'react';
9 10  
10 11 export default ({ data, reloadTable }) => {
11   - console.log(data, '5656datafirstshowgenjin');
12   -
13 12 // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示
14 13 const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法
15 14  
... ... @@ -17,7 +16,8 @@ export default ({ data, reloadTable }) =&gt; {
17 16 const [createByName, setCreateByName] = useState(''); // 跟进人员
18 17 const [clientName, setClientName] = useState(''); // 客户名称
19 18 // const [clientAddress, setClientAddress] = useState(''); // 客户地址
20   - const [way, setWay] = useState(); // 类型
  19 + const [way, setWay] = useState(); // 跟进方式
  20 + const [tradeStatusText, setTradeStatusText] = useState(); // 状态
21 21 // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询
22 22 // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询
23 23 // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态
... ... @@ -26,18 +26,34 @@ export default ({ data, reloadTable }) =&gt; {
26 26 const [createTime, setCreateTime] = useState(null); // 创建时间
27 27 const [attachments, setAttachments] = useState(); //附件
28 28 const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称
29   -
  29 + const [ticketsType, setTicketsType] = useState(''); // 附件名称
  30 + const [ticketsDetail, setTicketsDetail] = useState(''); // 附件名称
  31 + const [ticketsAttachment, setTicketsAttachment] = useState(''); // 附件名称
  32 + // const [ticketsAttachmentName, setTicketsAttachmentName] = useState(''); // 附件名称
  33 + const [assignPeople, setAssignPeople] = useState(''); // 附件名称
30 34 useEffect(() => {
31 35 const request = async () => {
32   - console.log(data, '5656datasearch');
33 36 const res = await postAdminClientQueryClientComunicationInfo({
34 37 data: {
35 38 id: data.id,
36 39 },
37 40 });
38   - console.log(res, '5656res');
  41 + const resTicket = await getOrderErpTicketsGetTicketsByClientId({
  42 + query: {
  43 + id: data.id,
  44 + },
  45 + });
  46 + // data.type = resTicket.data.type;
  47 + // data.detailText = resTicket.data.detailText;
  48 + // data.annexUrl = resTicket.data.annexUrl;
  49 + // data.assignPeople = resTicket.data.assignPeople;
  50 + // console.log(resTicket, '5656resTicket');
39 51 const dataSearch = res.data.data[0];
40 52 if (dataSearch) {
  53 + data.type = resTicket.data.type;
  54 + data.detailText = resTicket.data.detailText;
  55 + data.annexUrl = resTicket.data.annexUrl;
  56 + data.assignPeople = resTicket.data.assignPeople;
41 57 if (dataSearch.attachments) {
42 58 const url = dataSearch.attachments;
43 59 const match = url.match(/aliyuncs\.com\/(.*?)\?/);
... ... @@ -50,6 +66,22 @@ export default ({ data, reloadTable }) =&gt; {
50 66 setAttachmentsName(decodedStr); // 设置跟进日期
51 67 }
52 68 }
  69 + // if (dataSearch.ticketAttachments) {
  70 + // const url = dataSearch.attachments;
  71 + // const match = url.match(/aliyuncs\.com\/(.*?)\?/);
  72 + // let decodedStr = '';
  73 +
  74 + // if (match) {
  75 + // // 获取匹配的字符串并进行解码
  76 + // const encodedStr = match[1];
  77 + // decodedStr = decodeURIComponent(encodedStr);
  78 + // setTicketsAttachmentName(decodedStr); // 设置跟进日期
  79 + // }
  80 + // }
  81 + setTicketsType(resTicket.data.type);
  82 + setTicketsDetail(resTicket.data.detailText);
  83 + setTicketsAttachment(resTicket.data.annexUrl);
  84 + setAssignPeople(resTicket.data.assignPeople);
53 85 setDatetime(dataSearch.datetime); // 设置跟进日期
54 86 // setDateRange(data.dateRange || []); // 设置跟进时间范围
55 87 setCreateByName(dataSearch.createByName); // 设置跟进人员
... ... @@ -58,13 +90,12 @@ export default ({ data, reloadTable }) =&gt; {
58 90 // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询
59 91 // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询
60 92 // setTradeStatus(data.tradeStatus || ''); // 设置客户状态
61   - // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询
  93 + setTradeStatusText(data.tradeStatusLike || ''); // 设置客户状态模糊查询
62 94 setContent(dataSearch.content); // 设置跟进详情
63 95 setCreateTime(dataSearch.createTime); // 设置创建时间
64 96 setWay(dataSearch.wayText);
65 97 setAttachments(dataSearch.attachments);
66 98 }
67   - console.log(attachments, '5656attachments');
68 99 };
69 100 request();
70 101 }, []);
... ... @@ -96,12 +127,36 @@ export default ({ data, reloadTable }) =&gt; {
96 127 },
97 128 {
98 129 key: '6',
99   - label: '跟进类型',
100   - children: way, // 跟进类型
  130 + label: '跟进方式',
  131 + children: way, // 跟进方式
  132 + },
  133 + {
  134 + key: '7',
  135 + label: '跟进状态',
  136 + children: tradeStatusText, // 跟进状态
  137 + },
  138 + {
  139 + key: '8',
  140 + label: '工单类型',
  141 + children: ticketsType, // 跟进状态
  142 + },
  143 + {
  144 + key: '9',
  145 + label: '工单详情',
  146 + children: ticketsDetail, // 跟进状态
  147 + },
  148 + // {
  149 + // key: '10',
  150 + // label: '工单附件',
  151 + // children: ticketsAttachment, // 跟进状态
  152 + // },
  153 + {
  154 + key: '10',
  155 + label: '指派人员',
  156 + children: assignPeople, // 跟进状态
101 157 },
102 158 ];
103 159 const handleDelete = async () => {
104   - console.log(JSON.stringify(data), '5656record');
105 160 // 调用删除接口
106 161 const success = await postAdminClientRemoveClientComunicationInfo({
107 162 query: {
... ... @@ -117,7 +172,7 @@ export default ({ data, reloadTable }) =&gt; {
117 172 <Space>
118 173 <ModalForm
119 174 title="跟进记录"
120   - trigger={<Button type="link">查看</Button>}
  175 + trigger={<Button type="primary">查看</Button>}
121 176 submitter={{
122 177 resetButtonProps: {
123 178 style: {
... ... @@ -135,12 +190,18 @@ export default ({ data, reloadTable }) =&gt; {
135 190 <>
136 191 <ClientModal
137 192 key={'modify'}
138   - data={data} // 将表单数据传递给 ClientModal
  193 + // data={data} // 将表单数据传递给 ClientModal
  194 + data={{
  195 + ...data,
  196 + type: data.type,
  197 + detailText: data.detailText,
  198 + annexUrl: data.annexUrl,
  199 + assignPeople: data.assignPeople,
  200 + }} // 传递修改后的 data
139 201 reloadTable={() => {
140 202 actionRef?.current?.reload(); // 重新加载表格数据
141 203 props.submit();
142 204 reloadTable();
143   - console.log('5656close');
144 205 }}
145 206 type={'modify'}
146 207 onFinish={() => {
... ... @@ -181,6 +242,12 @@ export default ({ data, reloadTable }) =&gt; {
181 242 附件:{attachmentsName}
182 243 </a>
183 244 )}
  245 + <div></div>
  246 + {ticketsAttachment && (
  247 + <a href={ticketsAttachment} download>
  248 + 工单附件:{ticketsAttachment}
  249 + </a>
  250 + )}
184 251 </ModalForm>
185 252 </Space>
186 253 );
... ...
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
... ... @@ -12,6 +12,7 @@ import type { ActionType } from &#39;@ant-design/pro-components&#39;;
12 12 import { ProTable } from '@ant-design/pro-components';
13 13 import { Button, Space, message } from 'antd';
14 14 import { useRef, useState } from 'react';
  15 +import ClientModal2 from './Components/ClientModal2';
15 16  
16 17 export default () => {
17 18 const actionRef = useRef<ActionType>();
... ... @@ -19,7 +20,6 @@ export default () =&gt; {
19 20  
20 21 const reload = () => {
21 22 actionRef.current.reload(); // 重新加载数据
22   - console.log('5656flush');
23 23  
24 24 // 更新 refreshKey,强制刷新 CommunicationHistoryModal
25 25 setRefreshKey((prevKey) => prevKey + 1);
... ... @@ -46,7 +46,7 @@ export default () =&gt; {
46 46 // },
47 47 },
48 48 {
49   - title: '跟进时间',
  49 + title: '跟进日期',
50 50 dataIndex: 'dateRange',
51 51 valueType: 'dateRange',
52 52 hideInTable: true,
... ... @@ -68,6 +68,13 @@ export default () =&gt; {
68 68 ellipsis: true,
69 69 hideInSearch: false,
70 70 },
  71 + // {
  72 + // title: '跟进状态',
  73 + // width: 150,
  74 + // ellipsis: true,
  75 + // dataIndex: 'tradeStatusText',
  76 + // hideInSearch: true,
  77 + // },
71 78 {
72 79 title: '客户名称',
73 80 dataIndex: 'clientName',
... ... @@ -75,22 +82,51 @@ export default () =&gt; {
75 82 ellipsis: true,
76 83 hideInSearch: true,
77 84 },
  85 + // {
  86 + // title: '客户地址',
  87 + // dataIndex: 'clientAddress',
  88 + // width: 250,
  89 + // ellipsis: true,
  90 + // hideInSearch: true,
  91 + // },
78 92 {
79   - title: '客户地址',
80   - dataIndex: 'clientAddress',
81   - width: 250,
  93 + title: '联系人',
  94 + dataIndex: 'contact',
  95 + width: 150,
  96 + ellipsis: true,
  97 + hideInSearch: false,
  98 + },
  99 + // {
  100 + // title: '联系人',
  101 + // dataIndex: 'contactLike',
  102 + // width: 150,
  103 + // ellipsis: true,
  104 + // hideInSearch: false,
  105 + // hideInTable: true,
  106 + // },
  107 + {
  108 + title: '联系电话',
  109 + dataIndex: 'contactPhone',
  110 + width: 150,
  111 + ellipsis: true,
  112 + hideInSearch: true,
  113 + },
  114 + {
  115 + title: '跟进状态',
  116 + dataIndex: 'tradeStatusLike',
  117 + width: 100,
82 118 ellipsis: true,
83 119 hideInSearch: true,
84 120 },
85 121 {
86   - title: '跟进类型',
  122 + title: '跟进方式',
87 123 dataIndex: 'wayText',
88 124 width: 100,
89 125 ellipsis: true,
90 126 hideInSearch: true,
91 127 },
92 128 {
93   - title: '跟进类型',
  129 + title: '跟进方式',
94 130 dataIndex: 'way',
95 131 width: 100,
96 132 ellipsis: true,
... ... @@ -101,6 +137,16 @@ export default () =&gt; {
101 137 return enumToSelect(res.data);
102 138 },
103 139 },
  140 + // {
  141 + // title: '跟进状态',
  142 + // dataIndex: 'tradeStatus',
  143 + // valueType: 'select',
  144 + // hideInTable: true,
  145 + // request: async () => {
  146 + // const res = await postServiceConstTradeStatus();
  147 + // return enumToSelect(res.data);
  148 + // },
  149 + // },
104 150 {
105 151 title: '客户名称',
106 152 dataIndex: 'clientNameLike',
... ... @@ -109,26 +155,26 @@ export default () =&gt; {
109 155 hideInSearch: false,
110 156 hideInTable: true,
111 157 },
  158 + // {
  159 + // title: '客户地址',
  160 + // dataIndex: 'clientAddressLike',
  161 + // width: 250,
  162 + // ellipsis: true,
  163 + // hideInSearch: false,
  164 + // hideInTable: true,
  165 + // },
  166 + // {
  167 + // title: '跟进状态',
  168 + // dataIndex: 'tradeStatus',
  169 + // width: 100,
  170 + // ellipsis: true,
  171 + // hideInSearch: true,
  172 + // },
112 173 {
113   - title: '客户地址',
114   - dataIndex: 'clientAddressLike',
115   - width: 250,
116   - ellipsis: true,
117   - hideInSearch: false,
118   - hideInTable: true,
119   - },
120   - {
121   - title: '客户状态',
  174 + title: '跟进状态',
122 175 dataIndex: 'tradeStatus',
123 176 width: 100,
124 177 ellipsis: true,
125   - hideInSearch: true,
126   - },
127   - {
128   - title: '客户状态',
129   - dataIndex: 'tradeStatusLike',
130   - width: 100,
131   - ellipsis: true,
132 178 hideInSearch: false,
133 179 hideInTable: true,
134 180 request: async () => {
... ... @@ -141,7 +187,7 @@ export default () =&gt; {
141 187 dataIndex: 'content',
142 188 width: 250,
143 189 ellipsis: true,
144   - hideInSearch: false,
  190 + hideInSearch: true,
145 191 },
146 192 {
147 193 title: '创建时间',
... ... @@ -159,10 +205,26 @@ export default () =&gt; {
159 205 hideInTable: true,
160 206 },
161 207 {
  208 + title: '创建日期',
  209 + dataIndex: 'createTime',
  210 + valueType: 'dateRange',
  211 + hideInTable: true,
  212 + search: {
  213 + transform: (value) => {
  214 + if (value) {
  215 + return {
  216 + createTimeGe: value[0],
  217 + createTimeLe: value[1],
  218 + };
  219 + }
  220 + },
  221 + },
  222 + },
  223 + {
162 224 title: '操作',
163 225 valueType: 'option',
164 226 key: 'option',
165   - width: 150,
  227 + width: 220,
166 228 render: (text, record, index, action) => {
167 229 const handleDelete = async () => {
168 230 // console.log(JSON.stringify(record), '5656record');
... ... @@ -187,6 +249,20 @@ export default () =&gt; {
187 249 // }}
188 250 reloadTable={reload}
189 251 />,
  252 + <ClientModal2
  253 + key={'modify'}
  254 + // data={data} // 将表单数据传递给 ClientModal
  255 + data={record} // 传递修改后的 data
  256 + reloadTable={() => {
  257 + actionRef?.current?.reload(); // 重新加载表格数据
  258 + // props.submit();
  259 + }}
  260 + type={'modify'}
  261 + onFinish={() => {
  262 + // setIsModalVisible(false);
  263 + }} // 关闭 Modal
  264 + style={{ marginRight: '10px' }}
  265 + />,
190 266 <>
191 267 <Button
192 268 key={'delete'}
... ... @@ -197,8 +273,9 @@ export default () =&gt; {
197 273 // reloadTable={() => {
198 274 // actionRef.current.reload();
199 275 // }}
200   - type="link"
  276 + type="primary"
201 277 size="middle"
  278 + danger
202 279 // 使用 danger 属性来将按钮颜色设置为红色
203 280 // onFinish={() => {
204 281 // actionRef.current.reload();
... ... @@ -236,7 +313,6 @@ export default () =&gt; {
236 313 ...params,
237 314 },
238 315 });
239   - console.log(params, '5656566params');
240 316 if (res.result === RESPONSE_CODE.SUCCESS) {
241 317 console.log(JSON.stringify(res.data));
242 318 return {
... ...
src/pages/Order/Order/index.tsx
... ... @@ -4786,7 +4786,7 @@ const OrderPage = () =&gt; {
4786 4786 marginBottom: '20px',
4787 4787 }}
4788 4788 >
4789   - {waitConfirmPayment}
  4789 + {invoiceRefundWarningNum}
4790 4790 </div>
4791 4791 待确认收货订单
4792 4792 </div>
... ... @@ -4930,7 +4930,7 @@ const OrderPage = () =&gt; {
4930 4930 marginBottom: '20px',
4931 4931 }}
4932 4932 >
4933   - {invoiceRefundWarningNum}
  4933 + {waitConfirmPayment}
4934 4934 </div>
4935 4935 待回款订单
4936 4936 </div>
... ...
src/services/definition.ts
... ... @@ -103,16 +103,16 @@ export interface AdminClientDto {
103 103 */
104 104 city?: string;
105 105 companyId?: string;
106   - /**
107   - * @description
108   - * 联系人
109   - */
110   - contacts?: string;
111 106 createByName?: string;
112 107 /** @format date-time */
113 108 createTime?: string;
114 109 /**
115 110 * @description
  111 + * 部门
  112 + */
  113 + department?: string;
  114 + /**
  115 + * @description
116 116 * 详细地址
117 117 */
118 118 detailAddress?: string;
... ... @@ -123,16 +123,25 @@ export interface AdminClientDto {
123 123 district?: string;
124 124 /**
125 125 * @description
126   - * 是否已报方案
  126 + * 年级/职位
127 127 */
128   - hasScheme?: boolean;
129   - hasSchemeText?: string;
  128 + gradePosition?: string;
130 129 /** @format int64 */
131 130 id?: number;
  131 + /**
  132 + * @description
  133 + * 课题组
  134 + */
  135 + institutionContactName?: string;
132 136 /** @format date-time */
133 137 latestCommunicationTime?: string;
134 138 /**
135 139 * @description
  140 + * 负责人
  141 + */
  142 + leaderName?: string;
  143 + /**
  144 + * @description
136 145 * 客户等级
137 146 */
138 147 level?: string;
... ... @@ -165,12 +174,6 @@ export interface AdminClientDto {
165 174 province?: string;
166 175 /**
167 176 * @description
168   - * 报价时间
169   - * @format date-time
170   - */
171   - quoteDatetime?: string;
172   - /**
173   - * @description
174 177 * 推荐人
175 178 */
176 179 referrers?: string;
... ... @@ -194,16 +197,6 @@ export interface AdminClientDto {
194 197 * 来源
195 198 */
196 199 sourceText?: string;
197   - /**
198   - * @description
199   - * 跟进状态
200   - */
201   - tradeStatus?: string;
202   - /**
203   - * @description
204   - * 跟进状态
205   - */
206   - tradeStatusText?: string;
207 200 updateByName?: string;
208 201 /** @format date-time */
209 202 updateTime?: string;
... ... @@ -593,6 +586,11 @@ export interface ApiCreateOrderRequest {
593 586 paymentMethod?: string;
594 587 /**
595 588 * @description
  589 + * 销售代表
  590 + */
  591 + salesCode?: string;
  592 + /**
  593 + * @description
596 594 * 运费
597 595 */
598 596 shippingFee?: number;
... ... @@ -2893,7 +2891,6 @@ export interface QueryClientDto {
2893 2891 companyAddressLike?: string;
2894 2892 companyIds?: Array<number>;
2895 2893 companyNameLike?: string;
2896   - contacts?: string;
2897 2894 createByName?: string;
2898 2895 createByUserIdIn?: Array<number>;
2899 2896 /** @format date-time */
... ... @@ -2902,11 +2899,14 @@ export interface QueryClientDto {
2902 2899 createTimeLe?: string;
2903 2900 /** @format int32 */
2904 2901 current?: number;
  2902 + department?: string;
2905 2903 detailAddress?: string;
2906 2904 /** @format int32 */
2907 2905 end?: number;
  2906 + gradePosition?: string;
2908 2907 groupFilter?: string;
2909   - hasScheme?: boolean;
  2908 + institutionContactName?: Array<string>;
  2909 + leaderName?: string;
2910 2910 level?: string;
2911 2911 namelike?: string;
2912 2912 /** @format int32 */
... ... @@ -2918,7 +2918,10 @@ export interface QueryClientDto {
2918 2918 start?: number;
2919 2919 /** @format int32 */
2920 2920 total?: number;
2921   - tradeStatus?: string;
  2921 + /** @format date-time */
  2922 + updateTimeGe?: string;
  2923 + /** @format date-time */
  2924 + updateTimeLe?: string;
2922 2925 }
2923 2926  
2924 2927 export interface QueryCommunicationInfoDto {
... ... @@ -2927,9 +2930,17 @@ export interface QueryCommunicationInfoDto {
2927 2930 clientId?: number;
2928 2931 clientIdIn?: Array<number>;
2929 2932 clientNameLike?: string;
  2933 + comment?: string;
  2934 + contact?: string;
  2935 + contactLike?: string;
  2936 + contactPhone?: string;
2930 2937 content?: string;
2931 2938 createByName?: string;
2932 2939 createByNameIn?: Array<string>;
  2940 + /** @format date-time */
  2941 + createTimeGe?: string;
  2942 + /** @format date-time */
  2943 + createTimeLe?: string;
2933 2944 /** @format int32 */
2934 2945 current?: number;
2935 2946 /** @format date-time */
... ... @@ -2948,6 +2959,7 @@ export interface QueryCommunicationInfoDto {
2948 2959 start?: number;
2949 2960 /** @format int32 */
2950 2961 total?: number;
  2962 + tradeStatus?: string;
2951 2963 tradeStatusLike?: string;
2952 2964 updateByName?: string;
2953 2965 way?: string;
... ... @@ -3928,6 +3940,51 @@ export interface SystemCustomFieldReq {
3928 3940 entityNumber?: string;
3929 3941 }
3930 3942  
  3943 +export interface TicketsSearchVo {
  3944 + annexName?: string;
  3945 + annexUrl?: string;
  3946 + assignPeople?: string;
  3947 + createByName?: string;
  3948 + /** @format date-time */
  3949 + createTimeBegin?: string;
  3950 + /** @format date-time */
  3951 + createTimeEnd?: string;
  3952 + /** @format int32 */
  3953 + current?: number;
  3954 + detailText?: string;
  3955 + /** @format int32 */
  3956 + end?: number;
  3957 + /** @format int64 */
  3958 + id?: number;
  3959 + origin?: string;
  3960 + /** @format int32 */
  3961 + pageSize?: number;
  3962 + /** @format date-time */
  3963 + resolveTimeBegin?: string;
  3964 + /** @format date-time */
  3965 + resolveTimeEnd?: string;
  3966 + /** @format int32 */
  3967 + start?: number;
  3968 + status?: string;
  3969 + /** @format int32 */
  3970 + total?: number;
  3971 + type?: string;
  3972 +}
  3973 +
  3974 +export interface TicketsVo {
  3975 + annexName?: string;
  3976 + annexUrl?: string;
  3977 + assignPeople?: string;
  3978 + /** @format int64 */
  3979 + cid?: number;
  3980 + detailText?: string;
  3981 + /** @format int64 */
  3982 + id?: number;
  3983 + origin?: string;
  3984 + status?: string;
  3985 + type?: string;
  3986 +}
  3987 +
3931 3988 export interface ToProcureAuditDto {
3932 3989 procure?: string;
3933 3990 subOrderIds?: Array<number>;
... ... @@ -4259,6 +4316,7 @@ export interface ApiOrderConfirmReceiveRequest {
4259 4316 }
4260 4317  
4261 4318 export interface ClientCommunicationInfo {
  4319 + assignPeople?: string;
4262 4320 attachments?: string;
4263 4321 /**
4264 4322 * @description
... ... @@ -4274,6 +4332,21 @@ export interface ClientCommunicationInfo {
4274 4332 clientName?: string;
4275 4333 /**
4276 4334 * @description
  4335 + * 客户评价
  4336 + */
  4337 + comment?: string;
  4338 + /**
  4339 + * @description
  4340 + * 联系人
  4341 + */
  4342 + contact?: string;
  4343 + /**
  4344 + * @description
  4345 + * 联系电话
  4346 + */
  4347 + contactPhone?: string;
  4348 + /**
  4349 + * @description
4277 4350 * 内容
4278 4351 */
4279 4352 content?: string;
... ... @@ -4291,22 +4364,30 @@ export interface ClientCommunicationInfo {
4291 4364 /** @format int64 */
4292 4365 id?: number;
4293 4366 logicDelete?: boolean;
  4367 + ticketsAttachments?: string;
  4368 + ticketsDetail?: string;
  4369 + ticketsType?: string;
4294 4370 /**
4295 4371 * @description
4296 4372 * 客户状态
4297 4373 */
4298 4374 tradeStatus?: string;
  4375 + /**
  4376 + * @description
  4377 + * 客户状态
  4378 + */
  4379 + tradeStatusLike?: string;
4299 4380 updateByName?: string;
4300 4381 /** @format date-time */
4301 4382 updateTime?: string;
4302 4383 /**
4303 4384 * @description
4304   - * 方式
  4385 + * 跟进类型
4305 4386 */
4306 4387 way?: string;
4307 4388 /**
4308 4389 * @description
4309   - * 方式
  4390 + * 跟进类型
4310 4391 */
4311 4392 wayText?: string;
4312 4393 }
... ...
src/services/request.ts
... ... @@ -133,6 +133,8 @@ import type {
133 133 StoreOrderInvoiceRequest,
134 134 SysLogQueryVO,
135 135 SystemCustomFieldReq,
  136 + TicketsSearchVo,
  137 + TicketsVo,
136 138 ToProcureAuditDto,
137 139 TokenApiDto,
138 140 UnitMaterialUnitListReq,
... ... @@ -807,7 +809,7 @@ export type PostAdminClientModifyClientInfoResponseSuccess =
807 809 PostAdminClientModifyClientInfoResponse[200];
808 810 /**
809 811 * @description
810   - * 修改跟进信息
  812 + * 修改客户信息
811 813 * @tags 客户管理
812 814 * @produces *
813 815 * @consumes application/json
... ... @@ -9908,6 +9910,722 @@ export const postOrderErpRolesListByPage = /* #__PURE__ */ (() =&gt; {
9908 9910 return request;
9909 9911 })();
9910 9912  
  9913 +/** @description request parameter type for postOrderErpTicketsCreate */
  9914 +export interface PostOrderErpTicketsCreateOption {
  9915 + /**
  9916 + * @description
  9917 + * ticketsVo
  9918 + */
  9919 + body: {
  9920 + /**
  9921 + @description
  9922 + ticketsVo */
  9923 + ticketsVo: TicketsVo;
  9924 + };
  9925 +}
  9926 +
  9927 +/** @description response type for postOrderErpTicketsCreate */
  9928 +export interface PostOrderErpTicketsCreateResponse {
  9929 + /**
  9930 + * @description
  9931 + * OK
  9932 + */
  9933 + 200: ServerResult;
  9934 + /**
  9935 + * @description
  9936 + * Created
  9937 + */
  9938 + 201: any;
  9939 + /**
  9940 + * @description
  9941 + * Unauthorized
  9942 + */
  9943 + 401: any;
  9944 + /**
  9945 + * @description
  9946 + * Forbidden
  9947 + */
  9948 + 403: any;
  9949 + /**
  9950 + * @description
  9951 + * Not Found
  9952 + */
  9953 + 404: any;
  9954 +}
  9955 +
  9956 +export type PostOrderErpTicketsCreateResponseSuccess =
  9957 + PostOrderErpTicketsCreateResponse[200];
  9958 +/**
  9959 + * @description
  9960 + * 创建新工单
  9961 + * @tags 工单管理
  9962 + * @produces *
  9963 + * @consumes application/json
  9964 + */
  9965 +export const postOrderErpTicketsCreate = /* #__PURE__ */ (() => {
  9966 + const method = 'post';
  9967 + const url = '/order/erp/tickets/create';
  9968 + function request(
  9969 + option: PostOrderErpTicketsCreateOption,
  9970 + ): Promise<PostOrderErpTicketsCreateResponseSuccess> {
  9971 + return requester(request.url, {
  9972 + method: request.method,
  9973 + ...option,
  9974 + }) as unknown as Promise<PostOrderErpTicketsCreateResponseSuccess>;
  9975 + }
  9976 +
  9977 + /** http method */
  9978 + request.method = method;
  9979 + /** request url */
  9980 + request.url = url;
  9981 + return request;
  9982 +})();
  9983 +
  9984 +/** @description request parameter type for postOrderErpTicketsDelete */
  9985 +export interface PostOrderErpTicketsDeleteOption {
  9986 + /**
  9987 + * @description
  9988 + * ids
  9989 + */
  9990 + query: {
  9991 + /**
  9992 + @description
  9993 + ids */
  9994 + ids: Array<number>;
  9995 + };
  9996 +}
  9997 +
  9998 +/** @description response type for postOrderErpTicketsDelete */
  9999 +export interface PostOrderErpTicketsDeleteResponse {
  10000 + /**
  10001 + * @description
  10002 + * OK
  10003 + */
  10004 + 200: ServerResult;
  10005 + /**
  10006 + * @description
  10007 + * Created
  10008 + */
  10009 + 201: any;
  10010 + /**
  10011 + * @description
  10012 + * Unauthorized
  10013 + */
  10014 + 401: any;
  10015 + /**
  10016 + * @description
  10017 + * Forbidden
  10018 + */
  10019 + 403: any;
  10020 + /**
  10021 + * @description
  10022 + * Not Found
  10023 + */
  10024 + 404: any;
  10025 +}
  10026 +
  10027 +export type PostOrderErpTicketsDeleteResponseSuccess =
  10028 + PostOrderErpTicketsDeleteResponse[200];
  10029 +/**
  10030 + * @description
  10031 + * 删除工单
  10032 + * @tags 工单管理
  10033 + * @produces *
  10034 + * @consumes application/json
  10035 + */
  10036 +export const postOrderErpTicketsDelete = /* #__PURE__ */ (() => {
  10037 + const method = 'post';
  10038 + const url = '/order/erp/tickets/delete';
  10039 + function request(
  10040 + option: PostOrderErpTicketsDeleteOption,
  10041 + ): Promise<PostOrderErpTicketsDeleteResponseSuccess> {
  10042 + return requester(request.url, {
  10043 + method: request.method,
  10044 + ...option,
  10045 + }) as unknown as Promise<PostOrderErpTicketsDeleteResponseSuccess>;
  10046 + }
  10047 +
  10048 + /** http method */
  10049 + request.method = method;
  10050 + /** request url */
  10051 + request.url = url;
  10052 + return request;
  10053 +})();
  10054 +
  10055 +/** @description request parameter type for getOrderErpTicketsDetail */
  10056 +export interface GetOrderErpTicketsDetailOption {
  10057 + /**
  10058 + * @description
  10059 + * id
  10060 + * @format int64
  10061 + */
  10062 + query: {
  10063 + /**
  10064 + @description
  10065 + id
  10066 + @format int64 */
  10067 + id: number;
  10068 + };
  10069 +}
  10070 +
  10071 +/** @description response type for getOrderErpTicketsDetail */
  10072 +export interface GetOrderErpTicketsDetailResponse {
  10073 + /**
  10074 + * @description
  10075 + * OK
  10076 + */
  10077 + 200: ServerResult;
  10078 + /**
  10079 + * @description
  10080 + * Unauthorized
  10081 + */
  10082 + 401: any;
  10083 + /**
  10084 + * @description
  10085 + * Forbidden
  10086 + */
  10087 + 403: any;
  10088 + /**
  10089 + * @description
  10090 + * Not Found
  10091 + */
  10092 + 404: any;
  10093 +}
  10094 +
  10095 +export type GetOrderErpTicketsDetailResponseSuccess =
  10096 + GetOrderErpTicketsDetailResponse[200];
  10097 +/**
  10098 + * @description
  10099 + * 工单详情
  10100 + * @tags 工单管理
  10101 + * @produces *
  10102 + */
  10103 +export const getOrderErpTicketsDetail = /* #__PURE__ */ (() => {
  10104 + const method = 'get';
  10105 + const url = '/order/erp/tickets/detail';
  10106 + function request(
  10107 + option: GetOrderErpTicketsDetailOption,
  10108 + ): Promise<GetOrderErpTicketsDetailResponseSuccess> {
  10109 + return requester(request.url, {
  10110 + method: request.method,
  10111 + ...option,
  10112 + }) as unknown as Promise<GetOrderErpTicketsDetailResponseSuccess>;
  10113 + }
  10114 +
  10115 + /** http method */
  10116 + request.method = method;
  10117 + /** request url */
  10118 + request.url = url;
  10119 + return request;
  10120 +})();
  10121 +
  10122 +/** @description response type for getOrderErpTicketsExport */
  10123 +export interface GetOrderErpTicketsExportResponse {
  10124 + /**
  10125 + * @description
  10126 + * OK
  10127 + */
  10128 + 200: ServerResult;
  10129 + /**
  10130 + * @description
  10131 + * Unauthorized
  10132 + */
  10133 + 401: any;
  10134 + /**
  10135 + * @description
  10136 + * Forbidden
  10137 + */
  10138 + 403: any;
  10139 + /**
  10140 + * @description
  10141 + * Not Found
  10142 + */
  10143 + 404: any;
  10144 +}
  10145 +
  10146 +export type GetOrderErpTicketsExportResponseSuccess =
  10147 + GetOrderErpTicketsExportResponse[200];
  10148 +/**
  10149 + * @description
  10150 + * 导出工单
  10151 + * @tags 工单管理
  10152 + * @produces *
  10153 + */
  10154 +export const getOrderErpTicketsExport = /* #__PURE__ */ (() => {
  10155 + const method = 'get';
  10156 + const url = '/order/erp/tickets/export';
  10157 + function request(): Promise<GetOrderErpTicketsExportResponseSuccess> {
  10158 + return requester(request.url, {
  10159 + method: request.method,
  10160 + }) as unknown as Promise<GetOrderErpTicketsExportResponseSuccess>;
  10161 + }
  10162 +
  10163 + /** http method */
  10164 + request.method = method;
  10165 + /** request url */
  10166 + request.url = url;
  10167 + return request;
  10168 +})();
  10169 +
  10170 +/** @description response type for postOrderErpTicketsGetStatus */
  10171 +export interface PostOrderErpTicketsGetStatusResponse {
  10172 + /**
  10173 + * @description
  10174 + * OK
  10175 + */
  10176 + 200: ServerResult;
  10177 + /**
  10178 + * @description
  10179 + * Created
  10180 + */
  10181 + 201: any;
  10182 + /**
  10183 + * @description
  10184 + * Unauthorized
  10185 + */
  10186 + 401: any;
  10187 + /**
  10188 + * @description
  10189 + * Forbidden
  10190 + */
  10191 + 403: any;
  10192 + /**
  10193 + * @description
  10194 + * Not Found
  10195 + */
  10196 + 404: any;
  10197 +}
  10198 +
  10199 +export type PostOrderErpTicketsGetStatusResponseSuccess =
  10200 + PostOrderErpTicketsGetStatusResponse[200];
  10201 +/**
  10202 + * @description
  10203 + * 获得工单的所有状态
  10204 + * @tags 工单管理
  10205 + * @produces *
  10206 + * @consumes application/json
  10207 + */
  10208 +export const postOrderErpTicketsGetStatus = /* #__PURE__ */ (() => {
  10209 + const method = 'post';
  10210 + const url = '/order/erp/tickets/getStatus';
  10211 + function request(): Promise<PostOrderErpTicketsGetStatusResponseSuccess> {
  10212 + return requester(request.url, {
  10213 + method: request.method,
  10214 + }) as unknown as Promise<PostOrderErpTicketsGetStatusResponseSuccess>;
  10215 + }
  10216 +
  10217 + /** http method */
  10218 + request.method = method;
  10219 + /** request url */
  10220 + request.url = url;
  10221 + return request;
  10222 +})();
  10223 +
  10224 +/** @description request parameter type for getOrderErpTicketsGetTicketsByClientId */
  10225 +export interface GetOrderErpTicketsGetTicketsByClientIdOption {
  10226 + /**
  10227 + * @description
  10228 + * id
  10229 + * @format int64
  10230 + */
  10231 + query: {
  10232 + /**
  10233 + @description
  10234 + id
  10235 + @format int64 */
  10236 + id: number;
  10237 + };
  10238 +}
  10239 +
  10240 +/** @description response type for getOrderErpTicketsGetTicketsByClientId */
  10241 +export interface GetOrderErpTicketsGetTicketsByClientIdResponse {
  10242 + /**
  10243 + * @description
  10244 + * OK
  10245 + */
  10246 + 200: ServerResult;
  10247 + /**
  10248 + * @description
  10249 + * Unauthorized
  10250 + */
  10251 + 401: any;
  10252 + /**
  10253 + * @description
  10254 + * Forbidden
  10255 + */
  10256 + 403: any;
  10257 + /**
  10258 + * @description
  10259 + * Not Found
  10260 + */
  10261 + 404: any;
  10262 +}
  10263 +
  10264 +export type GetOrderErpTicketsGetTicketsByClientIdResponseSuccess =
  10265 + GetOrderErpTicketsGetTicketsByClientIdResponse[200];
  10266 +/**
  10267 + * @description
  10268 + * 根据跟进记录id获得工单信息
  10269 + * @tags 工单管理
  10270 + * @produces *
  10271 + */
  10272 +export const getOrderErpTicketsGetTicketsByClientId = /* #__PURE__ */ (() => {
  10273 + const method = 'get';
  10274 + const url = '/order/erp/tickets/getTicketsByClientId';
  10275 + function request(
  10276 + option: GetOrderErpTicketsGetTicketsByClientIdOption,
  10277 + ): Promise<GetOrderErpTicketsGetTicketsByClientIdResponseSuccess> {
  10278 + return requester(request.url, {
  10279 + method: request.method,
  10280 + ...option,
  10281 + }) as unknown as Promise<GetOrderErpTicketsGetTicketsByClientIdResponseSuccess>;
  10282 + }
  10283 +
  10284 + /** http method */
  10285 + request.method = method;
  10286 + /** request url */
  10287 + request.url = url;
  10288 + return request;
  10289 +})();
  10290 +
  10291 +/** @description response type for postOrderErpTicketsGetType */
  10292 +export interface PostOrderErpTicketsGetTypeResponse {
  10293 + /**
  10294 + * @description
  10295 + * OK
  10296 + */
  10297 + 200: ServerResult;
  10298 + /**
  10299 + * @description
  10300 + * Created
  10301 + */
  10302 + 201: any;
  10303 + /**
  10304 + * @description
  10305 + * Unauthorized
  10306 + */
  10307 + 401: any;
  10308 + /**
  10309 + * @description
  10310 + * Forbidden
  10311 + */
  10312 + 403: any;
  10313 + /**
  10314 + * @description
  10315 + * Not Found
  10316 + */
  10317 + 404: any;
  10318 +}
  10319 +
  10320 +export type PostOrderErpTicketsGetTypeResponseSuccess =
  10321 + PostOrderErpTicketsGetTypeResponse[200];
  10322 +/**
  10323 + * @description
  10324 + * 获得工单的所有类型
  10325 + * @tags 工单管理
  10326 + * @produces *
  10327 + * @consumes application/json
  10328 + */
  10329 +export const postOrderErpTicketsGetType = /* #__PURE__ */ (() => {
  10330 + const method = 'post';
  10331 + const url = '/order/erp/tickets/getType';
  10332 + function request(): Promise<PostOrderErpTicketsGetTypeResponseSuccess> {
  10333 + return requester(request.url, {
  10334 + method: request.method,
  10335 + }) as unknown as Promise<PostOrderErpTicketsGetTypeResponseSuccess>;
  10336 + }
  10337 +
  10338 + /** http method */
  10339 + request.method = method;
  10340 + /** request url */
  10341 + request.url = url;
  10342 + return request;
  10343 +})();
  10344 +
  10345 +/** @description request parameter type for postOrderErpTicketsImport */
  10346 +export interface PostOrderErpTicketsImportOption {
  10347 + /**
  10348 + * @description
  10349 + * file
  10350 + */
  10351 + formData: {
  10352 + /**
  10353 + @description
  10354 + file */
  10355 + file: File;
  10356 + };
  10357 +}
  10358 +
  10359 +/** @description response type for postOrderErpTicketsImport */
  10360 +export interface PostOrderErpTicketsImportResponse {
  10361 + /**
  10362 + * @description
  10363 + * OK
  10364 + */
  10365 + 200: ServerResult;
  10366 + /**
  10367 + * @description
  10368 + * Created
  10369 + */
  10370 + 201: any;
  10371 + /**
  10372 + * @description
  10373 + * Unauthorized
  10374 + */
  10375 + 401: any;
  10376 + /**
  10377 + * @description
  10378 + * Forbidden
  10379 + */
  10380 + 403: any;
  10381 + /**
  10382 + * @description
  10383 + * Not Found
  10384 + */
  10385 + 404: any;
  10386 +}
  10387 +
  10388 +export type PostOrderErpTicketsImportResponseSuccess =
  10389 + PostOrderErpTicketsImportResponse[200];
  10390 +/**
  10391 + * @description
  10392 + * 导入工单
  10393 + * @tags 工单管理
  10394 + * @produces *
  10395 + * @consumes multipart/form-data
  10396 + */
  10397 +export const postOrderErpTicketsImport = /* #__PURE__ */ (() => {
  10398 + const method = 'post';
  10399 + const url = '/order/erp/tickets/import';
  10400 + function request(
  10401 + option: PostOrderErpTicketsImportOption,
  10402 + ): Promise<PostOrderErpTicketsImportResponseSuccess> {
  10403 + return requester(request.url, {
  10404 + method: request.method,
  10405 + ...option,
  10406 + }) as unknown as Promise<PostOrderErpTicketsImportResponseSuccess>;
  10407 + }
  10408 +
  10409 + /** http method */
  10410 + request.method = method;
  10411 + /** request url */
  10412 + request.url = url;
  10413 + return request;
  10414 +})();
  10415 +
  10416 +/** @description request parameter type for postOrderErpTicketsSearch */
  10417 +export interface PostOrderErpTicketsSearchOption {
  10418 + /**
  10419 + * @description
  10420 + * ticketsVo
  10421 + */
  10422 + body: {
  10423 + /**
  10424 + @description
  10425 + ticketsVo */
  10426 + ticketsVo: TicketsSearchVo;
  10427 + };
  10428 +}
  10429 +
  10430 +/** @description response type for postOrderErpTicketsSearch */
  10431 +export interface PostOrderErpTicketsSearchResponse {
  10432 + /**
  10433 + * @description
  10434 + * OK
  10435 + */
  10436 + 200: ServerResult;
  10437 + /**
  10438 + * @description
  10439 + * Created
  10440 + */
  10441 + 201: any;
  10442 + /**
  10443 + * @description
  10444 + * Unauthorized
  10445 + */
  10446 + 401: any;
  10447 + /**
  10448 + * @description
  10449 + * Forbidden
  10450 + */
  10451 + 403: any;
  10452 + /**
  10453 + * @description
  10454 + * Not Found
  10455 + */
  10456 + 404: any;
  10457 +}
  10458 +
  10459 +export type PostOrderErpTicketsSearchResponseSuccess =
  10460 + PostOrderErpTicketsSearchResponse[200];
  10461 +/**
  10462 + * @description
  10463 + * 查询工单列表
  10464 + * @tags 工单管理
  10465 + * @produces *
  10466 + * @consumes application/json
  10467 + */
  10468 +export const postOrderErpTicketsSearch = /* #__PURE__ */ (() => {
  10469 + const method = 'post';
  10470 + const url = '/order/erp/tickets/search';
  10471 + function request(
  10472 + option: PostOrderErpTicketsSearchOption,
  10473 + ): Promise<PostOrderErpTicketsSearchResponseSuccess> {
  10474 + return requester(request.url, {
  10475 + method: request.method,
  10476 + ...option,
  10477 + }) as unknown as Promise<PostOrderErpTicketsSearchResponseSuccess>;
  10478 + }
  10479 +
  10480 + /** http method */
  10481 + request.method = method;
  10482 + /** request url */
  10483 + request.url = url;
  10484 + return request;
  10485 +})();
  10486 +
  10487 +/** @description request parameter type for postOrderErpTicketsUpdate */
  10488 +export interface PostOrderErpTicketsUpdateOption {
  10489 + /**
  10490 + * @description
  10491 + * ticketsVo
  10492 + */
  10493 + body: {
  10494 + /**
  10495 + @description
  10496 + ticketsVo */
  10497 + ticketsVo: TicketsVo;
  10498 + };
  10499 +}
  10500 +
  10501 +/** @description response type for postOrderErpTicketsUpdate */
  10502 +export interface PostOrderErpTicketsUpdateResponse {
  10503 + /**
  10504 + * @description
  10505 + * OK
  10506 + */
  10507 + 200: ServerResult;
  10508 + /**
  10509 + * @description
  10510 + * Created
  10511 + */
  10512 + 201: any;
  10513 + /**
  10514 + * @description
  10515 + * Unauthorized
  10516 + */
  10517 + 401: any;
  10518 + /**
  10519 + * @description
  10520 + * Forbidden
  10521 + */
  10522 + 403: any;
  10523 + /**
  10524 + * @description
  10525 + * Not Found
  10526 + */
  10527 + 404: any;
  10528 +}
  10529 +
  10530 +export type PostOrderErpTicketsUpdateResponseSuccess =
  10531 + PostOrderErpTicketsUpdateResponse[200];
  10532 +/**
  10533 + * @description
  10534 + * 修改工单
  10535 + * @tags 工单管理
  10536 + * @produces *
  10537 + * @consumes application/json
  10538 + */
  10539 +export const postOrderErpTicketsUpdate = /* #__PURE__ */ (() => {
  10540 + const method = 'post';
  10541 + const url = '/order/erp/tickets/update';
  10542 + function request(
  10543 + option: PostOrderErpTicketsUpdateOption,
  10544 + ): Promise<PostOrderErpTicketsUpdateResponseSuccess> {
  10545 + return requester(request.url, {
  10546 + method: request.method,
  10547 + ...option,
  10548 + }) as unknown as Promise<PostOrderErpTicketsUpdateResponseSuccess>;
  10549 + }
  10550 +
  10551 + /** http method */
  10552 + request.method = method;
  10553 + /** request url */
  10554 + request.url = url;
  10555 + return request;
  10556 +})();
  10557 +
  10558 +/** @description request parameter type for postOrderErpTicketsUpload */
  10559 +export interface PostOrderErpTicketsUploadOption {
  10560 + /**
  10561 + * @description
  10562 + * file
  10563 + */
  10564 + formData: {
  10565 + /**
  10566 + @description
  10567 + file */
  10568 + file: File;
  10569 + };
  10570 +}
  10571 +
  10572 +/** @description response type for postOrderErpTicketsUpload */
  10573 +export interface PostOrderErpTicketsUploadResponse {
  10574 + /**
  10575 + * @description
  10576 + * OK
  10577 + */
  10578 + 200: ServerResult;
  10579 + /**
  10580 + * @description
  10581 + * Created
  10582 + */
  10583 + 201: any;
  10584 + /**
  10585 + * @description
  10586 + * Unauthorized
  10587 + */
  10588 + 401: any;
  10589 + /**
  10590 + * @description
  10591 + * Forbidden
  10592 + */
  10593 + 403: any;
  10594 + /**
  10595 + * @description
  10596 + * Not Found
  10597 + */
  10598 + 404: any;
  10599 +}
  10600 +
  10601 +export type PostOrderErpTicketsUploadResponseSuccess =
  10602 + PostOrderErpTicketsUploadResponse[200];
  10603 +/**
  10604 + * @description
  10605 + * 文件上传
  10606 + * @tags 工单管理
  10607 + * @produces *
  10608 + * @consumes multipart/form-data
  10609 + */
  10610 +export const postOrderErpTicketsUpload = /* #__PURE__ */ (() => {
  10611 + const method = 'post';
  10612 + const url = '/order/erp/tickets/upload';
  10613 + function request(
  10614 + option: PostOrderErpTicketsUploadOption,
  10615 + ): Promise<PostOrderErpTicketsUploadResponseSuccess> {
  10616 + return requester(request.url, {
  10617 + method: request.method,
  10618 + ...option,
  10619 + }) as unknown as Promise<PostOrderErpTicketsUploadResponseSuccess>;
  10620 + }
  10621 +
  10622 + /** http method */
  10623 + request.method = method;
  10624 + /** request url */
  10625 + request.url = url;
  10626 + return request;
  10627 +})();
  10628 +
9911 10629 /** @description request parameter type for postOrderErpUsersAdd */
9912 10630 export interface PostOrderErpUsersAddOption {
9913 10631 /**
... ...
src/tsg.config.ts
... ... @@ -33,8 +33,8 @@ const projects: Project[] = [
33 33 * openapi 文档地址,可以是远程的json文件,也可以是本地的json文件
34 34 * 如果使用本地文件,相对路径以当前'tsg.config.ts'为基准
35 35 * */
36   - // source: 'http://localhost:8085/v2/api-docs',
37   - source: 'http://39.108.227.113:8085/v2/api-docs',
  36 + source: 'http://localhost:8085/v2/api-docs',
  37 + //source: 'http://39.108.227.113:8085/v2/api-docs',
38 38  
39 39 // source: 'https://petstore3.swagger.io/api/v3/openapi.json',
40 40 // source: './fixture/pet.json',
... ...