Commit 2144d84dda897f640f653bf91def4304e75ae2f5
1 parent
2159dc50
feat: 客户列表与跟进记录
Showing
15 changed files
with
1989 additions
and
283 deletions
.umirc.ts
@@ -124,10 +124,21 @@ export default defineConfig({ | @@ -124,10 +124,21 @@ export default defineConfig({ | ||
124 | }, | 124 | }, |
125 | { | 125 | { |
126 | name: '客户管理', | 126 | name: '客户管理', |
127 | - path: '/client', | ||
128 | - component: './Client', | 127 | + path: '/Client', |
129 | icon: 'BookOutlined', | 128 | icon: 'BookOutlined', |
130 | access: 'canReadAdminAndSales', | 129 | access: 'canReadAdminAndSales', |
130 | + routes: [ | ||
131 | + { | ||
132 | + name: '客户列表', | ||
133 | + path: 'clint', | ||
134 | + component: './Client/Client', | ||
135 | + }, | ||
136 | + { | ||
137 | + name: '跟进记录', | ||
138 | + path: 'FollowRecord', | ||
139 | + component: './Client/FollowRecord', | ||
140 | + }, | ||
141 | + ], | ||
131 | }, | 142 | }, |
132 | { | 143 | { |
133 | name: '打印', | 144 | name: '打印', |
src/pages/Client/Components/ClientDrawer.tsx renamed to src/pages/Client/Client/Components/ClientDrawer.tsx
@@ -6,8 +6,11 @@ import { | @@ -6,8 +6,11 @@ import { | ||
6 | postDistrictSelectByNameAndLevel, | 6 | postDistrictSelectByNameAndLevel, |
7 | postDistrictSelOrderProvince, | 7 | postDistrictSelOrderProvince, |
8 | postServiceConstClientLevels, | 8 | postServiceConstClientLevels, |
9 | + postServiceConstClientRequirements, | ||
10 | + postServiceConstClientSource, | ||
9 | postServiceConstTradeStatus, | 11 | postServiceConstTradeStatus, |
10 | } from '@/services'; | 12 | } from '@/services'; |
13 | + | ||
11 | import { enumToSelect } from '@/utils'; | 14 | import { enumToSelect } from '@/utils'; |
12 | import { | 15 | import { |
13 | DrawerForm, | 16 | DrawerForm, |
@@ -42,7 +45,7 @@ export default ({ optType, record, onFinish }) => { | @@ -42,7 +45,7 @@ export default ({ optType, record, onFinish }) => { | ||
42 | }, | 45 | }, |
43 | edit: { | 46 | edit: { |
44 | text: '编辑', | 47 | text: '编辑', |
45 | - button: <a type="primary">编辑</a>, | 48 | + button: <a type="link">编辑</a>, |
46 | readonly: false, | 49 | readonly: false, |
47 | onFinish: async (values) => { | 50 | onFinish: async (values) => { |
48 | const res = await postAdminClientModifyClientInfo({ | 51 | const res = await postAdminClientModifyClientInfo({ |
@@ -58,7 +61,7 @@ export default ({ optType, record, onFinish }) => { | @@ -58,7 +61,7 @@ export default ({ optType, record, onFinish }) => { | ||
58 | }, | 61 | }, |
59 | detail: { | 62 | detail: { |
60 | text: '详情', | 63 | text: '详情', |
61 | - button: <a type="primary">详情</a>, | 64 | + // button: <a type="primary">详情</a>, |
62 | readonly: true, | 65 | readonly: true, |
63 | }, | 66 | }, |
64 | }; | 67 | }; |
@@ -98,7 +101,7 @@ export default ({ optType, record, onFinish }) => { | @@ -98,7 +101,7 @@ export default ({ optType, record, onFinish }) => { | ||
98 | }, | 101 | }, |
99 | ]} | 102 | ]} |
100 | /> | 103 | /> |
101 | - <ProFormText | 104 | + {/* <ProFormText |
102 | name="companyName" | 105 | name="companyName" |
103 | label="单位名称" | 106 | label="单位名称" |
104 | placeholder="请输入单位名称" | 107 | placeholder="请输入单位名称" |
@@ -108,7 +111,7 @@ export default ({ optType, record, onFinish }) => { | @@ -108,7 +111,7 @@ export default ({ optType, record, onFinish }) => { | ||
108 | message: '请输入单位名称', | 111 | message: '请输入单位名称', |
109 | }, | 112 | }, |
110 | ]} | 113 | ]} |
111 | - /> | 114 | + /> */} |
112 | <div | 115 | <div |
113 | style={{ | 116 | style={{ |
114 | display: 'flex', | 117 | display: 'flex', |
@@ -260,7 +263,7 @@ export default ({ optType, record, onFinish }) => { | @@ -260,7 +263,7 @@ export default ({ optType, record, onFinish }) => { | ||
260 | /> | 263 | /> |
261 | </div> | 264 | </div> |
262 | <ProFormText | 265 | <ProFormText |
263 | - name="companyAddress" | 266 | + name="detailAddress" |
264 | label="详细地址" | 267 | label="详细地址" |
265 | placeholder="请输入单位地址" | 268 | placeholder="请输入单位地址" |
266 | rules={[ | 269 | rules={[ |
@@ -271,6 +274,17 @@ export default ({ optType, record, onFinish }) => { | @@ -271,6 +274,17 @@ export default ({ optType, record, onFinish }) => { | ||
271 | ]} | 274 | ]} |
272 | /> | 275 | /> |
273 | <ProFormText | 276 | <ProFormText |
277 | + name="contacts" | ||
278 | + label="联系人" | ||
279 | + placeholder="请输入联系人" | ||
280 | + rules={[ | ||
281 | + { | ||
282 | + required: true, | ||
283 | + message: '请输入联系人', | ||
284 | + }, | ||
285 | + ]} | ||
286 | + /> | ||
287 | + <ProFormText | ||
274 | name="phoneNumber" | 288 | name="phoneNumber" |
275 | label="联系电话" | 289 | label="联系电话" |
276 | placeholder="请输入联系电话" | 290 | placeholder="请输入联系电话" |
@@ -281,12 +295,22 @@ export default ({ optType, record, onFinish }) => { | @@ -281,12 +295,22 @@ export default ({ optType, record, onFinish }) => { | ||
281 | }, | 295 | }, |
282 | ]} | 296 | ]} |
283 | /> | 297 | /> |
284 | - <ProFormText | 298 | + <ProFormSelect |
285 | name="source" | 299 | name="source" |
286 | label="客户来源" | 300 | label="客户来源" |
287 | - placeholder="请输入客户来源" | 301 | + placeholder="请选择客户来源" |
302 | + request={async () => { | ||
303 | + const res = await postServiceConstClientSource(); | ||
304 | + return enumToSelect(res.data); | ||
305 | + }} | ||
306 | + rules={[ | ||
307 | + { | ||
308 | + required: true, | ||
309 | + message: '请选择客户来源', | ||
310 | + }, | ||
311 | + ]} | ||
288 | /> | 312 | /> |
289 | - <ProFormText | 313 | + <ProFormSelect |
290 | name="requirements" | 314 | name="requirements" |
291 | label="客户需求" | 315 | label="客户需求" |
292 | placeholder="请输入客户需求" | 316 | placeholder="请输入客户需求" |
@@ -296,6 +320,10 @@ export default ({ optType, record, onFinish }) => { | @@ -296,6 +320,10 @@ export default ({ optType, record, onFinish }) => { | ||
296 | message: '请输入客户需求', | 320 | message: '请输入客户需求', |
297 | }, | 321 | }, |
298 | ]} | 322 | ]} |
323 | + request={async () => { | ||
324 | + const res = await postServiceConstClientRequirements(); | ||
325 | + return enumToSelect(res.data); | ||
326 | + }} | ||
299 | /> | 327 | /> |
300 | <ProFormText name="referrers" label="推荐人" placeholder="请输入推荐人" /> | 328 | <ProFormText name="referrers" label="推荐人" placeholder="请输入推荐人" /> |
301 | <ProFormSelect | 329 | <ProFormSelect |
src/pages/Client/Components/ClientImportModal.tsx renamed to src/pages/Client/Client/Components/ClientImportModal.tsx
src/pages/Client/Client/Components/ClientModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { | ||
3 | + postAdminClientAddOrModifyClientComunicationInfo, | ||
4 | + postAdminClientQueryClientPage, | ||
5 | + postOrderErpOrderStagesUpload, | ||
6 | + postServiceConstClientWay, | ||
7 | +} from '@/services'; | ||
8 | +import { enumToSelect } from '@/utils'; | ||
9 | +import { | ||
10 | + ModalForm, | ||
11 | + ProFormDateTimePicker, | ||
12 | + ProFormSelect, | ||
13 | + ProFormText, | ||
14 | + ProFormTextArea, | ||
15 | + ProFormUploadDragger, | ||
16 | +} from '@ant-design/pro-components'; | ||
17 | +import { Button, Form, message } from 'antd'; | ||
18 | +import { RcFile } from 'antd/es/upload'; | ||
19 | +export default ({ data, type, reloadTable }) => { | ||
20 | + const [form] = Form.useForm(); | ||
21 | + const onfinish = async (values) => { | ||
22 | + console.log(data, '5656datatest'); | ||
23 | + console.log(values, '5656...values'); | ||
24 | + const res = await postAdminClientAddOrModifyClientComunicationInfo({ | ||
25 | + data: { | ||
26 | + ...values, | ||
27 | + clientId: data.id, | ||
28 | + }, | ||
29 | + }); | ||
30 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
31 | + message.success('新增成功'); | ||
32 | + reloadTable(); | ||
33 | + return true; | ||
34 | + } | ||
35 | + // 不返回不会关闭弹框 | ||
36 | + }; | ||
37 | + const optType = { | ||
38 | + add: { | ||
39 | + readOnly: false, | ||
40 | + title: '新增跟进记录', | ||
41 | + button: ( | ||
42 | + <Button size={'small'} type="link"> | ||
43 | + 新增跟进 | ||
44 | + </Button> | ||
45 | + ), | ||
46 | + onFinish: onfinish, | ||
47 | + }, | ||
48 | + modify: { | ||
49 | + readOnly: false, | ||
50 | + title: '修改跟进记录', | ||
51 | + button: ( | ||
52 | + <Button size={'small'} type="link"> | ||
53 | + 编辑 | ||
54 | + </Button> | ||
55 | + ), | ||
56 | + onFinish: onfinish, | ||
57 | + }, | ||
58 | + detail: { | ||
59 | + readOnly: true, | ||
60 | + title: '查看跟进记录', | ||
61 | + button: ( | ||
62 | + <Button size={'small'} type="link"> | ||
63 | + 查看 | ||
64 | + </Button> | ||
65 | + ), | ||
66 | + onFinish: () => {}, | ||
67 | + }, | ||
68 | + }; | ||
69 | + return ( | ||
70 | + <ModalForm | ||
71 | + title={optType[type].title} | ||
72 | + resize={{ | ||
73 | + onResize() { | ||
74 | + console.log('resize!'); | ||
75 | + }, | ||
76 | + maxWidth: window.innerWidth * 0.8, | ||
77 | + minWidth: 400, | ||
78 | + }} | ||
79 | + form={form} | ||
80 | + trigger={optType[type].button} | ||
81 | + autoFocusFirstInput | ||
82 | + drawerProps={{ | ||
83 | + destroyOnClose: true, | ||
84 | + }} | ||
85 | + submitTimeout={2000} | ||
86 | + onFinish={optType[type].onFinish} | ||
87 | + > | ||
88 | + <ProFormSelect | ||
89 | + name="sendStoreCode" | ||
90 | + readonly={optType[type].readOnly} | ||
91 | + fieldProps={{ | ||
92 | + labelInValue: false, | ||
93 | + }} | ||
94 | + initialValue={data ? data?.name + '' : null} | ||
95 | + label="客户" | ||
96 | + width="sm" | ||
97 | + request={async () => { | ||
98 | + const res = await postAdminClientQueryClientPage({ | ||
99 | + data: { | ||
100 | + groupFilter: 'all', | ||
101 | + }, | ||
102 | + }); | ||
103 | + console.log(data?.datetime, '5656data?.datetime'); | ||
104 | + const namesArray = res.data.data.map((item) => item.name); | ||
105 | + return enumToSelect(namesArray); | ||
106 | + }} | ||
107 | + rules={[ | ||
108 | + { | ||
109 | + required: true, | ||
110 | + message: '请选择客户', | ||
111 | + }, | ||
112 | + ]} | ||
113 | + disabled | ||
114 | + ></ProFormSelect> | ||
115 | + <ProFormDateTimePicker | ||
116 | + name="datetime" | ||
117 | + label="日期" | ||
118 | + initialValue={data.datetime ? data?.datetime + '' : null} | ||
119 | + placeholder="请选择跟进时间" | ||
120 | + width="sm" | ||
121 | + rules={[ | ||
122 | + { | ||
123 | + required: true, | ||
124 | + message: '请选择日期', | ||
125 | + }, | ||
126 | + ]} | ||
127 | + /> | ||
128 | + <ProFormSelect | ||
129 | + name="way" | ||
130 | + width="sm" | ||
131 | + readonly={optType[type].readOnly} | ||
132 | + fieldProps={{ | ||
133 | + labelInValue: false, | ||
134 | + }} | ||
135 | + initialValue={data?.way ? data?.way + '' : null} | ||
136 | + label="类型" | ||
137 | + request={async () => { | ||
138 | + const res = await postServiceConstClientWay(); | ||
139 | + return enumToSelect(res.data); | ||
140 | + }} | ||
141 | + rules={[ | ||
142 | + { | ||
143 | + required: true, | ||
144 | + message: '请选择跟进类型', | ||
145 | + }, | ||
146 | + ]} | ||
147 | + ></ProFormSelect> | ||
148 | + <ProFormTextArea | ||
149 | + name="content" | ||
150 | + label="详情" | ||
151 | + placeholder="请输入详情" | ||
152 | + initialValue={data?.content} | ||
153 | + readonly={optType[type].readOnly} | ||
154 | + rules={[ | ||
155 | + { | ||
156 | + required: true, | ||
157 | + message: '请输入详情', | ||
158 | + }, | ||
159 | + ]} | ||
160 | + ></ProFormTextArea> | ||
161 | + <ProFormUploadDragger | ||
162 | + label="附件" | ||
163 | + name="attachment" | ||
164 | + action="upload.do" | ||
165 | + hidden={optType[type].readOnly} | ||
166 | + onChange={(info) => { | ||
167 | + const uploadFile = async ({ fileList: newFileList }) => { | ||
168 | + if (newFileList.length > 0) { | ||
169 | + const formData = new FormData(); | ||
170 | + formData.append('file', newFileList[0].originFileObj as RcFile); | ||
171 | + const res = await postOrderErpOrderStagesUpload({ | ||
172 | + data: formData, | ||
173 | + headers: { | ||
174 | + 'Content-Type': | ||
175 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | ||
176 | + }, | ||
177 | + }); | ||
178 | + const url = res.data; | ||
179 | + console.log('attachments' + JSON.stringify(url)); | ||
180 | + form.setFieldValue('attachments', url); | ||
181 | + } else { | ||
182 | + form.setFieldValue('attachments', null); | ||
183 | + } | ||
184 | + }; | ||
185 | + uploadFile(info); | ||
186 | + }} | ||
187 | + max={1} | ||
188 | + /> | ||
189 | + <a hidden={!optType[type].readOnly} href={data?.attachments} download> | ||
190 | + 下载附件 | ||
191 | + </a> | ||
192 | + <ProFormText | ||
193 | + initialValue={data?.attachments} | ||
194 | + name="attachments" | ||
195 | + hidden | ||
196 | + ></ProFormText> | ||
197 | + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | ||
198 | + </ModalForm> | ||
199 | + ); | ||
200 | +}; |
src/pages/Client/Client/Components/ClientModalBak.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { | ||
3 | + postOrderErpOrderStagesUpload, | ||
4 | + postProcureReturnBillAddOrModify, | ||
5 | + postServiceConstStores, | ||
6 | +} from '@/services'; | ||
7 | +import { enumToSelect } from '@/utils'; | ||
8 | +import { | ||
9 | + ModalForm, | ||
10 | + ProFormSelect, | ||
11 | + ProFormText, | ||
12 | + ProFormTextArea, | ||
13 | + ProFormUploadDragger, | ||
14 | +} from '@ant-design/pro-components'; | ||
15 | +import { Button, Form, message } from 'antd'; | ||
16 | +import { RcFile } from 'antd/es/upload'; | ||
17 | +export default ({ data, type, reloadTable }) => { | ||
18 | + const [form] = Form.useForm(); | ||
19 | + const onfinish = async (values) => { | ||
20 | + const res = await postProcureReturnBillAddOrModify({ | ||
21 | + data: values, | ||
22 | + }); | ||
23 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
24 | + message.success('新增成功'); | ||
25 | + reloadTable(); | ||
26 | + return true; | ||
27 | + } | ||
28 | + // 不返回不会关闭弹框 | ||
29 | + }; | ||
30 | + const optType = { | ||
31 | + add: { | ||
32 | + readOnly: false, | ||
33 | + title: '新增采购退货单', | ||
34 | + button: ( | ||
35 | + <Button size={'small'} type="link"> | ||
36 | + 新增记录 | ||
37 | + </Button> | ||
38 | + ), | ||
39 | + onFinish: onfinish, | ||
40 | + }, | ||
41 | + modify: { | ||
42 | + readOnly: false, | ||
43 | + title: '修改采购退货单', | ||
44 | + button: ( | ||
45 | + <Button size={'small'} type="link"> | ||
46 | + 编辑 | ||
47 | + </Button> | ||
48 | + ), | ||
49 | + onFinish: onfinish, | ||
50 | + }, | ||
51 | + detail: { | ||
52 | + readOnly: true, | ||
53 | + title: '查看采购退货单', | ||
54 | + button: ( | ||
55 | + <Button size={'small'} type="link"> | ||
56 | + 查看 | ||
57 | + </Button> | ||
58 | + ), | ||
59 | + onFinish: () => {}, | ||
60 | + }, | ||
61 | + }; | ||
62 | + return ( | ||
63 | + <ModalForm | ||
64 | + title={optType[type].title} | ||
65 | + resize={{ | ||
66 | + onResize() { | ||
67 | + console.log('resize!'); | ||
68 | + }, | ||
69 | + maxWidth: window.innerWidth * 0.8, | ||
70 | + minWidth: 400, | ||
71 | + }} | ||
72 | + form={form} | ||
73 | + trigger={optType[type].button} | ||
74 | + autoFocusFirstInput | ||
75 | + drawerProps={{ | ||
76 | + destroyOnClose: true, | ||
77 | + }} | ||
78 | + submitTimeout={2000} | ||
79 | + onFinish={optType[type].onFinish} | ||
80 | + > | ||
81 | + <ProFormText | ||
82 | + name="consignee" | ||
83 | + label="收货人" | ||
84 | + placeholder="请输入收货人" | ||
85 | + readonly={optType[type].readOnly} | ||
86 | + initialValue={data?.consignee} | ||
87 | + rules={[ | ||
88 | + { | ||
89 | + required: true, | ||
90 | + message: '请输入收货人', | ||
91 | + }, | ||
92 | + ]} | ||
93 | + /> | ||
94 | + <ProFormText | ||
95 | + name="phoneNumber" | ||
96 | + label="联系电话" | ||
97 | + placeholder="请输入联系电话" | ||
98 | + initialValue={data?.phoneNumber} | ||
99 | + readonly={optType[type].readOnly} | ||
100 | + rules={[ | ||
101 | + { | ||
102 | + required: true, | ||
103 | + message: '请输入联系电话', | ||
104 | + }, | ||
105 | + ]} | ||
106 | + /> | ||
107 | + <ProFormText | ||
108 | + name="address" | ||
109 | + label="收货地址" | ||
110 | + placeholder="请输入收货地址" | ||
111 | + initialValue={data?.address} | ||
112 | + readonly={optType[type].readOnly} | ||
113 | + rules={[ | ||
114 | + { | ||
115 | + required: true, | ||
116 | + message: '请输入联系电话', | ||
117 | + }, | ||
118 | + ]} | ||
119 | + /> | ||
120 | + <ProFormTextArea | ||
121 | + name="productDetail" | ||
122 | + label="产品明细" | ||
123 | + placeholder="请输入产品明细" | ||
124 | + initialValue={data?.productDetail} | ||
125 | + readonly={optType[type].readOnly} | ||
126 | + rules={[ | ||
127 | + { | ||
128 | + required: true, | ||
129 | + message: '请输入联系电话', | ||
130 | + }, | ||
131 | + ]} | ||
132 | + ></ProFormTextArea> | ||
133 | + <ProFormSelect | ||
134 | + name="sendStoreCode" | ||
135 | + readonly={optType[type].readOnly} | ||
136 | + fieldProps={{ | ||
137 | + labelInValue: false, | ||
138 | + }} | ||
139 | + initialValue={data ? data?.sendStoreCode + '' : null} | ||
140 | + label="发货仓库" | ||
141 | + request={async () => { | ||
142 | + const res = await postServiceConstStores(); | ||
143 | + return enumToSelect(res.data); | ||
144 | + }} | ||
145 | + rules={[ | ||
146 | + { | ||
147 | + required: true, | ||
148 | + message: '请输入联系电话', | ||
149 | + }, | ||
150 | + ]} | ||
151 | + ></ProFormSelect> | ||
152 | + <ProFormTextArea | ||
153 | + name="notes" | ||
154 | + label="备注" | ||
155 | + initialValue={data?.notes} | ||
156 | + readonly={optType[type].readOnly} | ||
157 | + placeholder="请输入备注" | ||
158 | + ></ProFormTextArea> | ||
159 | + <ProFormUploadDragger | ||
160 | + label="附件" | ||
161 | + name="attachmentsFile" | ||
162 | + action="upload.do" | ||
163 | + hidden={optType[type].readOnly} | ||
164 | + onChange={(info) => { | ||
165 | + const uploadFile = async ({ fileList: newFileList }) => { | ||
166 | + if (newFileList.length > 0) { | ||
167 | + const formData = new FormData(); | ||
168 | + formData.append('file', newFileList[0].originFileObj as RcFile); | ||
169 | + const res = await postOrderErpOrderStagesUpload({ | ||
170 | + data: formData, | ||
171 | + headers: { | ||
172 | + 'Content-Type': | ||
173 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | ||
174 | + }, | ||
175 | + }); | ||
176 | + const url = res.data; | ||
177 | + console.log('attachments' + JSON.stringify(url)); | ||
178 | + form.setFieldValue('attachments', url); | ||
179 | + } else { | ||
180 | + form.setFieldValue('attachments', null); | ||
181 | + } | ||
182 | + }; | ||
183 | + uploadFile(info); | ||
184 | + }} | ||
185 | + max={1} | ||
186 | + /> | ||
187 | + <a hidden={!optType[type].readOnly} href={data?.attachments} download> | ||
188 | + 下载附件 | ||
189 | + </a> | ||
190 | + <ProFormText | ||
191 | + initialValue={data?.attachments} | ||
192 | + name="attachments" | ||
193 | + hidden | ||
194 | + ></ProFormText> | ||
195 | + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | ||
196 | + </ModalForm> | ||
197 | + ); | ||
198 | +}; |
src/pages/Client/Client/Components/CommunicationHistoryModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { | ||
3 | + postAdminClientAddOrModifyClientComunicationInfo, | ||
4 | + postAdminClientQueryClientComunicationInfo, | ||
5 | + postAdminClientRemoveClientComunicationInfo, | ||
6 | + postServiceConstClientWay, | ||
7 | +} from '@/services'; | ||
8 | +import { enumToSelect } from '@/utils'; | ||
9 | +import { | ||
10 | + ActionType, | ||
11 | + EditableProTable, | ||
12 | + ModalForm, | ||
13 | + ProFormInstance, | ||
14 | +} from '@ant-design/pro-components'; | ||
15 | +import { Descriptions, Popconfirm, message } from 'antd'; | ||
16 | +import { useEffect, useRef, useState } from 'react'; | ||
17 | +export default ({ record }) => { | ||
18 | + const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]); | ||
19 | + const [dataSource, setDataSource] = useState(); | ||
20 | + const ref = useRef<ProFormInstance>(); | ||
21 | + const actionRef = useRef<ActionType>(); | ||
22 | + const columns = [ | ||
23 | + { | ||
24 | + title: '跟进时间', | ||
25 | + dataIndex: 'datetime', | ||
26 | + width: 50, | ||
27 | + valueType: 'dateTime', | ||
28 | + rules: [{ required: true, message: '请选择时间' }], | ||
29 | + }, | ||
30 | + { | ||
31 | + title: '跟进人', | ||
32 | + width: 50, | ||
33 | + rules: [{ required: true, message: '请输入跟进人' }], | ||
34 | + dataIndex: 'createByName', | ||
35 | + }, | ||
36 | + // { | ||
37 | + // title: '跟进类型', | ||
38 | + // width: 150, | ||
39 | + // ellipsis: true, | ||
40 | + // dataIndex: 'wayText', | ||
41 | + // hideInSearch: true, | ||
42 | + // }, | ||
43 | + { | ||
44 | + title: '跟进类型', | ||
45 | + width: 50, | ||
46 | + dataIndex: 'way', | ||
47 | + rules: [{ required: true, message: '请选择方式' }], | ||
48 | + request: async () => { | ||
49 | + const res = await postServiceConstClientWay(); | ||
50 | + return enumToSelect(res.data); | ||
51 | + }, | ||
52 | + }, | ||
53 | + { | ||
54 | + title: '内容', | ||
55 | + width: 100, | ||
56 | + valueType: 'textarea', | ||
57 | + rules: [{ required: true, message: '请输入内容' }], | ||
58 | + dataIndex: 'content', | ||
59 | + }, | ||
60 | + { | ||
61 | + title: '操作', | ||
62 | + valueType: 'option', | ||
63 | + width: 50, | ||
64 | + render: (text, record, _, action) => [ | ||
65 | + <a | ||
66 | + key="editable" | ||
67 | + onClick={() => { | ||
68 | + action?.startEditable?.(record.tid); | ||
69 | + }} | ||
70 | + > | ||
71 | + 编辑 | ||
72 | + </a>, | ||
73 | + <Popconfirm | ||
74 | + key={'delete'} | ||
75 | + title="删除记录" | ||
76 | + description="确认删除记录?" | ||
77 | + onConfirm={async () => { | ||
78 | + setDataSource(dataSource.filter((item) => item.tid !== record.tid)); | ||
79 | + const res = await postAdminClientRemoveClientComunicationInfo({ | ||
80 | + query: { | ||
81 | + id: record.id, | ||
82 | + }, | ||
83 | + }); | ||
84 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
85 | + message.success(res.message); | ||
86 | + action?.reload(); | ||
87 | + } else { | ||
88 | + message.error('删除失败'); | ||
89 | + } | ||
90 | + }} | ||
91 | + okText="是" | ||
92 | + cancelText="否" | ||
93 | + > | ||
94 | + <a type={'danger'}>删除</a> | ||
95 | + </Popconfirm>, | ||
96 | + ], | ||
97 | + }, | ||
98 | + ]; | ||
99 | + const [name, setName] = useState(''); // 客户名称 | ||
100 | + const [contacts, setContacts] = useState(''); // 联系人 | ||
101 | + const [sourceText, setSourceText] = useState(''); // 来源文本 | ||
102 | + const [phoneNumber, setPhoneNumber] = useState(''); // 联系电话 | ||
103 | + const [hasSchemeText, setHasSchemeText] = useState(''); // 报方案状态文本 | ||
104 | + const [quoteDatetime, setQuoteDatetime] = useState(null); // 报价时间 | ||
105 | + const [referrers, setReferrers] = useState(''); // 推荐人 | ||
106 | + const [requirementsText, setRequirementsText] = useState(''); // 需求文本 | ||
107 | + const [tradeStatusText, setTradeStatusText] = useState(''); // 跟进状态文本 | ||
108 | + const [levelText, setLevelText] = useState(''); // 客户等级文本 | ||
109 | + const [createTime, setCreateTime] = useState(null); // 最新沟通时间 | ||
110 | + const [address, setAddress] = useState(''); // 客户地址 | ||
111 | + const [notes, setNotes] = useState(''); // 备注信息 | ||
112 | + const [createByName, setCreateByName] = useState(''); // 创建人 | ||
113 | + const [latestObject, setLatestObject] = useState(); // 最新跟进时间 | ||
114 | + useEffect(() => { | ||
115 | + const request = async () => { | ||
116 | + const resShow = await postAdminClientQueryClientComunicationInfo({ | ||
117 | + data: { | ||
118 | + clientId: record.id, | ||
119 | + }, | ||
120 | + }); | ||
121 | + if (resShow?.data?.data !== null) { | ||
122 | + const data = resShow?.data?.data; | ||
123 | + // const latest = data.reduce((latest: any, current: any) => { | ||
124 | + // return new Date(current.updateTime) > new Date(latest.updateTime) ? current : latest; | ||
125 | + // }); | ||
126 | + // const data = []; | ||
127 | + const latestObject2 = | ||
128 | + data?.length > 0 | ||
129 | + ? data.reduce((latest, current) => | ||
130 | + new Date(current.datetime) > new Date(latest.datetime) | ||
131 | + ? current | ||
132 | + : latest, | ||
133 | + ) | ||
134 | + : null; // 或返回其他默认值 | ||
135 | + setLatestObject(latestObject2?.datetime); | ||
136 | + } | ||
137 | + | ||
138 | + setName(record.name); | ||
139 | + setContacts(record.contacts); | ||
140 | + setSourceText(record.sourceText); | ||
141 | + setPhoneNumber(record.phoneNumber); | ||
142 | + setHasSchemeText(record.hasSchemeText); | ||
143 | + setQuoteDatetime(record.quoteDatetime); | ||
144 | + setReferrers(record.referrers); | ||
145 | + setRequirementsText(record.requirementsText); | ||
146 | + setTradeStatusText(record.tradeStatusText); | ||
147 | + setLevelText(record.levelText); | ||
148 | + setCreateTime(record.createTime); | ||
149 | + setAddress(record.address); | ||
150 | + setNotes(record.notes); | ||
151 | + setCreateByName(record.createByName); | ||
152 | + }; | ||
153 | + request(); | ||
154 | + }, []); | ||
155 | + const items = [ | ||
156 | + { | ||
157 | + key: '1', | ||
158 | + label: '客户名称', | ||
159 | + children: name, // 客户名称 | ||
160 | + }, | ||
161 | + { | ||
162 | + key: '2', | ||
163 | + label: '联系人', | ||
164 | + children: contacts, // 联系人 | ||
165 | + }, | ||
166 | + { | ||
167 | + key: '3', | ||
168 | + label: '来源', | ||
169 | + children: sourceText, // 来源文本 | ||
170 | + }, | ||
171 | + { | ||
172 | + key: '4', | ||
173 | + label: '联系电话', | ||
174 | + children: phoneNumber, // 联系电话 | ||
175 | + }, | ||
176 | + { | ||
177 | + key: '5', | ||
178 | + label: '是否已报方案', | ||
179 | + children: hasSchemeText, // 报方案状态文本 | ||
180 | + }, | ||
181 | + { | ||
182 | + key: '6', | ||
183 | + label: '报价时间', | ||
184 | + children: quoteDatetime, // 报价时间 | ||
185 | + }, | ||
186 | + { | ||
187 | + key: '7', | ||
188 | + label: '推荐人', | ||
189 | + children: referrers, // 推荐人 | ||
190 | + }, | ||
191 | + { | ||
192 | + key: '8', | ||
193 | + label: '需求', | ||
194 | + children: requirementsText, // 需求文本 | ||
195 | + }, | ||
196 | + { | ||
197 | + key: '9', | ||
198 | + label: '跟进状态', | ||
199 | + children: tradeStatusText, // 跟进状态文本 | ||
200 | + }, | ||
201 | + { | ||
202 | + key: '10', | ||
203 | + label: '客户等级', | ||
204 | + children: levelText, // 客户等级文本 | ||
205 | + }, | ||
206 | + { | ||
207 | + key: '11', | ||
208 | + label: '创建时间', | ||
209 | + children: createTime, // 最新沟通时间 | ||
210 | + }, | ||
211 | + { | ||
212 | + key: '12', | ||
213 | + label: '客户地址', | ||
214 | + children: address, // 客户地址 | ||
215 | + }, | ||
216 | + { | ||
217 | + key: '13', | ||
218 | + label: '备注', | ||
219 | + children: notes, // 备注信息 | ||
220 | + }, | ||
221 | + { | ||
222 | + key: '14', | ||
223 | + label: '创建人', | ||
224 | + children: createByName, // 创建人 | ||
225 | + }, | ||
226 | + { | ||
227 | + key: '15', | ||
228 | + label: '最新跟进时间', | ||
229 | + children: latestObject, // 最新跟进时间 | ||
230 | + }, | ||
231 | + ]; | ||
232 | + return ( | ||
233 | + <ModalForm | ||
234 | + title="客户详情" | ||
235 | + trigger={<a type="primary">查看</a>} | ||
236 | + modalProps={{ | ||
237 | + destroyOnClose: true, | ||
238 | + }} | ||
239 | + onFinish={async () => { | ||
240 | + return true; | ||
241 | + }} | ||
242 | + > | ||
243 | + <Descriptions items={items} column={2} /> | ||
244 | + <EditableProTable | ||
245 | + rowKey="tid" | ||
246 | + formRef={ref} | ||
247 | + actionRef={actionRef} | ||
248 | + recordCreatorProps={{ | ||
249 | + record: () => ({ tid: (Math.random() * 1000000).toFixed(0) }), | ||
250 | + }} | ||
251 | + loading={false} | ||
252 | + columns={columns} | ||
253 | + request={async () => { | ||
254 | + const res = await postAdminClientQueryClientComunicationInfo({ | ||
255 | + data: { | ||
256 | + clientId: record.id, | ||
257 | + }, | ||
258 | + }); | ||
259 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
260 | + console.log(JSON.stringify(res.data)); | ||
261 | + return { | ||
262 | + ...res.data, | ||
263 | + data: res.data.data.map((item) => { | ||
264 | + return { | ||
265 | + ...item, | ||
266 | + tid: (Math.random() * 1000000).toFixed(0), | ||
267 | + }; | ||
268 | + }), | ||
269 | + }; | ||
270 | + } else { | ||
271 | + message.error('获取失败'); | ||
272 | + } | ||
273 | + }} | ||
274 | + value={dataSource} | ||
275 | + onChange={setDataSource} | ||
276 | + editable={{ | ||
277 | + type: 'multiple', | ||
278 | + editableKeys, | ||
279 | + onSave: async (rowKey, data, row) => { | ||
280 | + console.log(rowKey, data, row); | ||
281 | + if (data?.way === '拜访') { | ||
282 | + data.way = 'VISIT'; | ||
283 | + } else if (data?.way === '电话') { | ||
284 | + data.way = 'PHONE'; | ||
285 | + } else if (data?.way === '微信') { | ||
286 | + data.way = 'WECHAT'; | ||
287 | + } else if (data?.way === '邮件') { | ||
288 | + data.way = 'EMAIL'; | ||
289 | + } else if (data?.way === '其他') { | ||
290 | + data.way = 'OTHER'; | ||
291 | + } | ||
292 | + const res = await postAdminClientAddOrModifyClientComunicationInfo({ | ||
293 | + data: { | ||
294 | + ...data, | ||
295 | + clientId: record.id, | ||
296 | + }, | ||
297 | + }); | ||
298 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
299 | + message.success(res.message); | ||
300 | + } else { | ||
301 | + message.error('修改失败'); | ||
302 | + } | ||
303 | + actionRef.current?.reload(); | ||
304 | + }, | ||
305 | + onChange: setEditableRowKeys, | ||
306 | + }} | ||
307 | + /> | ||
308 | + {/* <Descriptions title="User Info" items={items} column={2} /> */} | ||
309 | + {/*<ProCard title="表格数据" headerBordered collapsible defaultCollapsed> | ||
310 | + <ProFormField | ||
311 | + ignoreFormItem | ||
312 | + fieldProps={{ | ||
313 | + style: { | ||
314 | + width: '100%', | ||
315 | + }, | ||
316 | + }} | ||
317 | + mode="read" | ||
318 | + valueType="jsonCode" | ||
319 | + text={JSON.stringify(dataSource)} | ||
320 | + /> | ||
321 | + </ProCard>*/} | ||
322 | + </ModalForm> | ||
323 | + ); | ||
324 | +}; |
src/pages/Client/index.tsx renamed to src/pages/Client/Client/index.tsx
1 | -import ClientDrawer from '@/pages/Client/Components/ClientDrawer'; | ||
2 | -import ClientImportModal from '@/pages/Client/Components/ClientImportModal'; | ||
3 | -import ClientStatistic from '@/pages/Client/Components/ClientStatistic'; | ||
4 | -import CommunicationHistoryModal from '@/pages/Client/Components/CommunicationHistoryModal'; | 1 | +import ClientDrawer from '@/pages/Client/Client/Components/ClientDrawer'; |
2 | +import ClientImportModal from '@/pages/Client/Client/Components/ClientImportModal'; | ||
3 | +import ClientModal from '@/pages/Client/Client/Components/ClientModal'; | ||
4 | +import CommunicationHistoryModal from '@/pages/Client/Client/Components/CommunicationHistoryModal'; | ||
5 | import { | 5 | import { |
6 | + postAdminClientDeleteAdminClient, | ||
7 | + postAdminClientGetStatisticalData, | ||
6 | postAdminClientQueryClientPage, | 8 | postAdminClientQueryClientPage, |
7 | - postServiceConstClientGroupFilters, | ||
8 | postServiceConstClientLevels, | 9 | postServiceConstClientLevels, |
10 | + postServiceConstClientRequirements, | ||
11 | + postServiceConstClientSource, | ||
9 | postServiceConstTradeStatus, | 12 | postServiceConstTradeStatus, |
10 | } from '@/services'; | 13 | } from '@/services'; |
11 | import { orderExport } from '@/services/order'; | 14 | import { orderExport } from '@/services/order'; |
12 | import { enumToSelect } from '@/utils'; | 15 | import { enumToSelect } from '@/utils'; |
13 | import type { ActionType } from '@ant-design/pro-components'; | 16 | import type { ActionType } from '@ant-design/pro-components'; |
14 | import { ProTable } from '@ant-design/pro-components'; | 17 | import { ProTable } from '@ant-design/pro-components'; |
15 | -import { Button, Radio, Space, message } from 'antd'; | 18 | +import { Badge, Button, Radio, Space, message } from 'antd'; |
16 | import { useEffect, useRef, useState } from 'react'; | 19 | import { useEffect, useRef, useState } from 'react'; |
17 | 20 | ||
18 | const columns = [ | 21 | const columns = [ |
@@ -25,23 +28,30 @@ const columns = [ | @@ -25,23 +28,30 @@ const columns = [ | ||
25 | { | 28 | { |
26 | title: '客户名称', | 29 | title: '客户名称', |
27 | dataIndex: 'name', | 30 | dataIndex: 'name', |
28 | - width: 100, | 31 | + width: 150, |
29 | ellipsis: true, | 32 | ellipsis: true, |
30 | hideInSearch: true, | 33 | hideInSearch: true, |
31 | }, | 34 | }, |
35 | + // { | ||
36 | + // title: '单位名称', | ||
37 | + // width: 150, | ||
38 | + // ellipsis: true, | ||
39 | + // dataIndex: 'companyName', | ||
40 | + // hideInSearch: true, | ||
41 | + // }, | ||
32 | { | 42 | { |
33 | - title: '单位名称', | ||
34 | - width: 150, | 43 | + title: '客户地址', |
44 | + width: 250, | ||
35 | ellipsis: true, | 45 | ellipsis: true, |
36 | - dataIndex: 'companyName', | ||
37 | - hideInSearch: true, | 46 | + dataIndex: 'address', |
47 | + hideInSearch: false, | ||
38 | }, | 48 | }, |
39 | { | 49 | { |
40 | - title: '单位地址', | ||
41 | - width: 250, | 50 | + title: '联系人', |
51 | + width: 150, | ||
42 | ellipsis: true, | 52 | ellipsis: true, |
43 | - dataIndex: 'companyAddressText', | ||
44 | - hideInSearch: true, | 53 | + dataIndex: 'contacts', |
54 | + hideInSearch: false, | ||
45 | }, | 55 | }, |
46 | { | 56 | { |
47 | title: '联系电话', | 57 | title: '联系电话', |
@@ -54,10 +64,20 @@ const columns = [ | @@ -54,10 +64,20 @@ const columns = [ | ||
54 | title: '客户来源', | 64 | title: '客户来源', |
55 | width: 150, | 65 | width: 150, |
56 | ellipsis: true, | 66 | ellipsis: true, |
57 | - dataIndex: 'source', | 67 | + dataIndex: 'sourceText', |
58 | hideInSearch: true, | 68 | hideInSearch: true, |
59 | }, | 69 | }, |
60 | { | 70 | { |
71 | + title: '客户来源', | ||
72 | + valueType: 'select', | ||
73 | + hideInTable: true, | ||
74 | + dataIndex: 'source', | ||
75 | + request: async () => { | ||
76 | + const res = await postServiceConstClientSource(); | ||
77 | + return enumToSelect(res.data); | ||
78 | + }, | ||
79 | + }, | ||
80 | + { | ||
61 | title: '推荐人', | 81 | title: '推荐人', |
62 | dataIndex: 'referrers', | 82 | dataIndex: 'referrers', |
63 | width: 150, | 83 | width: 150, |
@@ -66,12 +86,22 @@ const columns = [ | @@ -66,12 +86,22 @@ const columns = [ | ||
66 | }, | 86 | }, |
67 | { | 87 | { |
68 | title: '客户需求', | 88 | title: '客户需求', |
69 | - dataIndex: 'requirements', | ||
70 | width: 150, | 89 | width: 150, |
71 | ellipsis: true, | 90 | ellipsis: true, |
91 | + dataIndex: 'requirementsText', | ||
72 | hideInSearch: true, | 92 | hideInSearch: true, |
73 | }, | 93 | }, |
74 | { | 94 | { |
95 | + title: '客户需求', | ||
96 | + dataIndex: 'requirements', | ||
97 | + valueType: 'select', | ||
98 | + hideInTable: true, | ||
99 | + request: async () => { | ||
100 | + const res = await postServiceConstClientRequirements(); | ||
101 | + return enumToSelect(res.data); | ||
102 | + }, | ||
103 | + }, | ||
104 | + { | ||
75 | title: '是否已报方案', | 105 | title: '是否已报方案', |
76 | width: 150, | 106 | width: 150, |
77 | ellipsis: true, | 107 | ellipsis: true, |
@@ -111,26 +141,35 @@ const columns = [ | @@ -111,26 +141,35 @@ const columns = [ | ||
111 | hideInSearch: true, | 141 | hideInSearch: true, |
112 | }, | 142 | }, |
113 | { | 143 | { |
114 | - title: '最新跟进时间', | 144 | + title: '最新更进时间', |
115 | key: 'since', | 145 | key: 'since', |
116 | width: 150, | 146 | width: 150, |
117 | ellipsis: true, | 147 | ellipsis: true, |
118 | - dataIndex: 'latestCommunicationTime', | 148 | + dataIndex: 'updateTime', |
119 | valueType: 'dateTime', | 149 | valueType: 'dateTime', |
120 | hideInSearch: true, | 150 | hideInSearch: true, |
121 | }, | 151 | }, |
152 | + // { | ||
153 | + // title: '最新跟进时间', | ||
154 | + // key: 'since', | ||
155 | + // width: 150, | ||
156 | + // ellipsis: true, | ||
157 | + // dataIndex: 'latestCommunicationTime', | ||
158 | + // valueType: 'dateTime', | ||
159 | + // hideInSearch: true, | ||
160 | + // }, | ||
122 | { | 161 | { |
123 | title: '客户名称', | 162 | title: '客户名称', |
124 | dataIndex: 'nameLike', | 163 | dataIndex: 'nameLike', |
125 | valueType: 'Text', | 164 | valueType: 'Text', |
126 | hideInTable: true, | 165 | hideInTable: true, |
127 | }, | 166 | }, |
128 | - { | ||
129 | - title: '单位名称', | ||
130 | - dataIndex: 'companyNameLike', | ||
131 | - valueType: 'Text', | ||
132 | - hideInTable: true, | ||
133 | - }, | 167 | + // { |
168 | + // title: '单位名称', | ||
169 | + // dataIndex: 'companyNameLike', | ||
170 | + // valueType: 'Text', | ||
171 | + // hideInTable: true, | ||
172 | + // }, | ||
134 | { | 173 | { |
135 | title: '联系电话', | 174 | title: '联系电话', |
136 | dataIndex: 'phoneNumberLike', | 175 | dataIndex: 'phoneNumberLike', |
@@ -194,11 +233,23 @@ const columns = [ | @@ -194,11 +233,23 @@ const columns = [ | ||
194 | key: 'option', | 233 | key: 'option', |
195 | width: 150, | 234 | width: 150, |
196 | render: (text, record, index, action) => { | 235 | render: (text, record, index, action) => { |
236 | + const handleDelete = async () => { | ||
237 | + console.log(JSON.stringify(record), '5656record'); | ||
238 | + // 调用删除接口 | ||
239 | + const success = await postAdminClientDeleteAdminClient({ | ||
240 | + query: { | ||
241 | + id: record.id, | ||
242 | + }, | ||
243 | + }); | ||
244 | + if (success) { | ||
245 | + action.reload(); // 刷新表格 | ||
246 | + } | ||
247 | + }; | ||
197 | console.log(JSON.stringify(record)); | 248 | console.log(JSON.stringify(record)); |
198 | return [ | 249 | return [ |
199 | <CommunicationHistoryModal | 250 | <CommunicationHistoryModal |
200 | key={'communicationHistory'} | 251 | key={'communicationHistory'} |
201 | - clientId={record.id} | 252 | + record={record} |
202 | />, | 253 | />, |
203 | <ClientDrawer | 254 | <ClientDrawer |
204 | key={'detail'} | 255 | key={'detail'} |
@@ -208,6 +259,14 @@ const columns = [ | @@ -208,6 +259,14 @@ const columns = [ | ||
208 | action.reload(); | 259 | action.reload(); |
209 | }} | 260 | }} |
210 | ></ClientDrawer>, | 261 | ></ClientDrawer>, |
262 | + <ClientModal | ||
263 | + key={'add'} | ||
264 | + data={record} | ||
265 | + reloadTable={() => { | ||
266 | + action?.reload(); | ||
267 | + }} | ||
268 | + type={'add'} | ||
269 | + />, | ||
211 | <ClientDrawer | 270 | <ClientDrawer |
212 | key={'edit'} | 271 | key={'edit'} |
213 | record={record} | 272 | record={record} |
@@ -216,6 +275,9 @@ const columns = [ | @@ -216,6 +275,9 @@ const columns = [ | ||
216 | action.reload(); | 275 | action.reload(); |
217 | }} | 276 | }} |
218 | ></ClientDrawer>, | 277 | ></ClientDrawer>, |
278 | + <a key={'delete'} onClick={handleDelete} style={{ color: 'red' }}> | ||
279 | + 删除 | ||
280 | + </a>, | ||
219 | ]; | 281 | ]; |
220 | }, | 282 | }, |
221 | }, | 283 | }, |
@@ -224,23 +286,79 @@ const columns = [ | @@ -224,23 +286,79 @@ const columns = [ | ||
224 | export default () => { | 286 | export default () => { |
225 | const [messageApi, contextHolder] = message.useMessage(); | 287 | const [messageApi, contextHolder] = message.useMessage(); |
226 | const [groupFilter, setGroupFilter] = useState('All'); | 288 | const [groupFilter, setGroupFilter] = useState('All'); |
227 | - const [groupFilterOptions, setGroupFilterDataOptions] = useState([]); | 289 | + // const [groupFilterOptions, setGroupFilterDataOptions] = useState([]); |
228 | const actionRef = useRef<ActionType>(); | 290 | const actionRef = useRef<ActionType>(); |
291 | + //获得预警/全部数量 | ||
292 | + const [clientStatistic, setClientStatistic] = useState([]); | ||
293 | + const [allClientStatistic, setAllClientStatistic] = useState([]); | ||
294 | + const [warningClientStatistic, setWarningClientStatistic] = useState([]); | ||
295 | + // const reloadTable = () => { | ||
296 | + // actionRef.current?.reload(); | ||
297 | + // }; | ||
229 | useEffect(() => { | 298 | useEffect(() => { |
230 | - const pullGroupFilterDataOptions = async () => { | ||
231 | - const res = await postServiceConstClientGroupFilters(); | ||
232 | - console.log('setGroupFilterDataOptions' + JSON.stringify(res.data)); | ||
233 | - setGroupFilterDataOptions(enumToSelect(res.data)); | 299 | + const pullStatistic = async () => { |
300 | + let statisticalData = await postAdminClientGetStatisticalData(); | ||
301 | + console.log('stati' + JSON.stringify(statisticalData.data)); | ||
302 | + setClientStatistic(statisticalData.data); | ||
303 | + setWarningClientStatistic(statisticalData.data[1].value); | ||
304 | + setAllClientStatistic(statisticalData.data[0].value); | ||
305 | + setTimeout(() => { | ||
306 | + console.log(clientStatistic, '5656groupFilterOptions1'); | ||
307 | + // groupFilterOptions[0].label = groupFilterOptions[0].label + '(' + clientStatistic + ')'; | ||
308 | + }, 100); | ||
309 | + actionRef.current?.reload(); // 可能需要在这里刷新 | ||
234 | }; | 310 | }; |
235 | - pullGroupFilterDataOptions(); | 311 | + pullStatistic(); |
236 | }, []); | 312 | }, []); |
313 | + const groupFilterOptions = [ | ||
314 | + { | ||
315 | + value: 'All', | ||
316 | + label: ( | ||
317 | + <span> | ||
318 | + 全部 | ||
319 | + <Badge count={allClientStatistic} style={{ marginLeft: 8 }} /> | ||
320 | + </span> | ||
321 | + ), | ||
322 | + }, | ||
323 | + { | ||
324 | + value: 'WARNING_CLIENT', | ||
325 | + label: ( | ||
326 | + <span> | ||
327 | + 预警客户 | ||
328 | + <Badge count={warningClientStatistic} style={{ marginLeft: 8 }} /> | ||
329 | + </span> | ||
330 | + ), | ||
331 | + }, | ||
332 | + ]; | ||
333 | + // useEffect(() => { | ||
334 | + // const pullGroupFilterDataOptions = async () => { | ||
335 | + // const res = await postServiceConstClientGroupFilters(); | ||
336 | + // // console.log('setGroupFilterDataOptions' + JSON.stringify(res.data)); | ||
337 | + // const select = enumToSelect(res.data); | ||
338 | + // console.log(select, '5656selet'); | ||
339 | + // setGroupFilterDataOptions(select); | ||
340 | + // }; | ||
341 | + // pullGroupFilterDataOptions(); | ||
342 | + // }, []); | ||
237 | useEffect(() => { | 343 | useEffect(() => { |
344 | + // console.log(groupFilterOptions, '5656groupFilterOptions2'); | ||
345 | + console.log(clientStatistic, '5656clientStatistic'); | ||
346 | + console.log(warningClientStatistic, '5656warningClientStatistic'); | ||
238 | actionRef.current?.reload(); | 347 | actionRef.current?.reload(); |
239 | }, [groupFilter]); | 348 | }, [groupFilter]); |
240 | return ( | 349 | return ( |
241 | <> | 350 | <> |
242 | <Space direction="vertical" size="middle" style={{ display: 'flex' }}> | 351 | <Space direction="vertical" size="middle" style={{ display: 'flex' }}> |
243 | - <ClientStatistic></ClientStatistic> | 352 | + <div key={'groupFilter'}> |
353 | + <Radio.Group | ||
354 | + options={groupFilterOptions} | ||
355 | + onChange={(e) => { | ||
356 | + setGroupFilter(e.target.value); | ||
357 | + }} | ||
358 | + value={groupFilter} | ||
359 | + optionType="button" | ||
360 | + /> | ||
361 | + </div> | ||
244 | <ProTable | 362 | <ProTable |
245 | columns={columns} | 363 | columns={columns} |
246 | actionRef={actionRef} | 364 | actionRef={actionRef} |
@@ -273,6 +391,7 @@ export default () => { | @@ -273,6 +391,7 @@ export default () => { | ||
273 | 'POST', | 391 | 'POST', |
274 | values, | 392 | values, |
275 | () => { | 393 | () => { |
394 | + console.log(searchConfig, '5656searchConfig'); | ||
276 | messageApi.destroy(); | 395 | messageApi.destroy(); |
277 | }, | 396 | }, |
278 | ); | 397 | ); |
@@ -323,16 +442,6 @@ export default () => { | @@ -323,16 +442,6 @@ export default () => { | ||
323 | dateFormatter="string" | 442 | dateFormatter="string" |
324 | headerTitle="高级表格" | 443 | headerTitle="高级表格" |
325 | toolBarRender={() => [ | 444 | toolBarRender={() => [ |
326 | - <div key={'groupFilter'}> | ||
327 | - <Radio.Group | ||
328 | - options={groupFilterOptions} | ||
329 | - onChange={(e) => { | ||
330 | - setGroupFilter(e.target.value); | ||
331 | - }} | ||
332 | - value={groupFilter} | ||
333 | - optionType="button" | ||
334 | - /> | ||
335 | - </div>, | ||
336 | <ClientDrawer | 445 | <ClientDrawer |
337 | optType={'add'} | 446 | optType={'add'} |
338 | key="button" | 447 | key="button" |
src/pages/Client/Components/ClientStatistic.tsx deleted
100644 → 0
1 | -import { postAdminClientGetStatisticalData } from '@/services'; | ||
2 | -import { StatisticCard } from '@ant-design/pro-components'; | ||
3 | -import { useEffect, useState } from 'react'; | ||
4 | - | ||
5 | -export default () => { | ||
6 | - const [clientStatistic, setClientStatistic] = useState([]); | ||
7 | - useEffect(() => { | ||
8 | - const pullStatistic = async () => { | ||
9 | - let statisticalData = await postAdminClientGetStatisticalData(); | ||
10 | - console.log('stati' + JSON.stringify(statisticalData.data)); | ||
11 | - setClientStatistic(statisticalData.data); | ||
12 | - }; | ||
13 | - pullStatistic(); | ||
14 | - }, []); | ||
15 | - return ( | ||
16 | - <StatisticCard.Group> | ||
17 | - {clientStatistic.map((stat, index) => ( | ||
18 | - <StatisticCard | ||
19 | - key={index} | ||
20 | - statistic={{ | ||
21 | - title: stat.title, | ||
22 | - tip: stat.tip || '', // 如果tip不存在,则使用空字符串 | ||
23 | - value: stat.value, | ||
24 | - status: stat.status || 'default', // 如果status不存在,则使用'default' | ||
25 | - }} | ||
26 | - /> | ||
27 | - ))} | ||
28 | - </StatisticCard.Group> | ||
29 | - ); | ||
30 | -}; |
src/pages/Client/Components/CommunicationHistoryModal.tsx deleted
100644 → 0
1 | -import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | -import { | ||
3 | - postAdminClientAddOrModifyClientComunicationInfo, | ||
4 | - postAdminClientQueryClientComunicationInfo, | ||
5 | - postAdminClientRemoveClientComunicationInfo, | ||
6 | -} from '@/services'; | ||
7 | -import { | ||
8 | - ActionType, | ||
9 | - EditableProTable, | ||
10 | - ModalForm, | ||
11 | - ProFormInstance, | ||
12 | -} from '@ant-design/pro-components'; | ||
13 | -import { Popconfirm, message } from 'antd'; | ||
14 | -import { useEffect, useRef, useState } from 'react'; | ||
15 | -export default ({ clientId }) => { | ||
16 | - const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]); | ||
17 | - const [dataSource, setDataSource] = useState(); | ||
18 | - const ref = useRef<ProFormInstance>(); | ||
19 | - const actionRef = useRef<ActionType>(); | ||
20 | - const columns = [ | ||
21 | - { | ||
22 | - title: '跟进时间', | ||
23 | - dataIndex: 'datetime', | ||
24 | - width: 50, | ||
25 | - valueType: 'dateTime', | ||
26 | - rules: [{ required: true, message: '请选择时间' }], | ||
27 | - }, | ||
28 | - { | ||
29 | - title: '方式', | ||
30 | - width: 50, | ||
31 | - dataIndex: 'way', | ||
32 | - rules: [{ required: true, message: '请选择方式' }], | ||
33 | - }, | ||
34 | - { | ||
35 | - title: '内容', | ||
36 | - width: 100, | ||
37 | - valueType: 'textarea', | ||
38 | - rules: [{ required: true, message: '请输入内容' }], | ||
39 | - dataIndex: 'content', | ||
40 | - }, | ||
41 | - { | ||
42 | - title: '操作', | ||
43 | - valueType: 'option', | ||
44 | - width: 50, | ||
45 | - render: (text, record, _, action) => [ | ||
46 | - <a | ||
47 | - key="editable" | ||
48 | - onClick={() => { | ||
49 | - action?.startEditable?.(record.tid); | ||
50 | - }} | ||
51 | - > | ||
52 | - 编辑 | ||
53 | - </a>, | ||
54 | - <Popconfirm | ||
55 | - key={'delete'} | ||
56 | - title="删除记录" | ||
57 | - description="确认删除记录?" | ||
58 | - onConfirm={async () => { | ||
59 | - setDataSource(dataSource.filter((item) => item.tid !== record.tid)); | ||
60 | - const res = await postAdminClientRemoveClientComunicationInfo({ | ||
61 | - query: { | ||
62 | - id: record.id, | ||
63 | - }, | ||
64 | - }); | ||
65 | - if (res.result === RESPONSE_CODE.SUCCESS) { | ||
66 | - message.success(res.message); | ||
67 | - action?.reload(); | ||
68 | - } else { | ||
69 | - message.error('删除失败'); | ||
70 | - } | ||
71 | - }} | ||
72 | - okText="是" | ||
73 | - cancelText="否" | ||
74 | - > | ||
75 | - <a type={'danger'}>删除</a> | ||
76 | - </Popconfirm>, | ||
77 | - ], | ||
78 | - }, | ||
79 | - ]; | ||
80 | - | ||
81 | - useEffect(() => { | ||
82 | - console.log('clientId', clientId); | ||
83 | - }, []); | ||
84 | - return ( | ||
85 | - <ModalForm | ||
86 | - title="跟进记录" | ||
87 | - trigger={<a type="primary">跟进记录</a>} | ||
88 | - modalProps={{ | ||
89 | - destroyOnClose: true, | ||
90 | - }} | ||
91 | - > | ||
92 | - <EditableProTable | ||
93 | - rowKey="tid" | ||
94 | - formRef={ref} | ||
95 | - actionRef={actionRef} | ||
96 | - recordCreatorProps={{ | ||
97 | - record: () => ({ tid: (Math.random() * 1000000).toFixed(0) }), | ||
98 | - }} | ||
99 | - loading={false} | ||
100 | - columns={columns} | ||
101 | - request={async () => { | ||
102 | - const res = await postAdminClientQueryClientComunicationInfo({ | ||
103 | - data: { | ||
104 | - clientId: clientId, | ||
105 | - }, | ||
106 | - }); | ||
107 | - if (res.result === RESPONSE_CODE.SUCCESS) { | ||
108 | - console.log(JSON.stringify(res.data)); | ||
109 | - return { | ||
110 | - ...res.data, | ||
111 | - data: res.data.data.map((item) => { | ||
112 | - return { | ||
113 | - ...item, | ||
114 | - tid: (Math.random() * 1000000).toFixed(0), | ||
115 | - }; | ||
116 | - }), | ||
117 | - }; | ||
118 | - } else { | ||
119 | - message.error('获取失败'); | ||
120 | - } | ||
121 | - }} | ||
122 | - value={dataSource} | ||
123 | - onChange={setDataSource} | ||
124 | - editable={{ | ||
125 | - type: 'multiple', | ||
126 | - editableKeys, | ||
127 | - onSave: async (rowKey, data, row) => { | ||
128 | - console.log(rowKey, data, row); | ||
129 | - const res = await postAdminClientAddOrModifyClientComunicationInfo({ | ||
130 | - data: { | ||
131 | - ...data, | ||
132 | - clientId: clientId, | ||
133 | - }, | ||
134 | - }); | ||
135 | - if (res.result === RESPONSE_CODE.SUCCESS) { | ||
136 | - message.success(res.message); | ||
137 | - } else { | ||
138 | - message.error('修改失败'); | ||
139 | - } | ||
140 | - actionRef.current?.reload(); | ||
141 | - }, | ||
142 | - onChange: setEditableRowKeys, | ||
143 | - }} | ||
144 | - /> | ||
145 | - {/*<ProCard title="表格数据" headerBordered collapsible defaultCollapsed> | ||
146 | - <ProFormField | ||
147 | - ignoreFormItem | ||
148 | - fieldProps={{ | ||
149 | - style: { | ||
150 | - width: '100%', | ||
151 | - }, | ||
152 | - }} | ||
153 | - mode="read" | ||
154 | - valueType="jsonCode" | ||
155 | - text={JSON.stringify(dataSource)} | ||
156 | - /> | ||
157 | - </ProCard>*/} | ||
158 | - </ModalForm> | ||
159 | - ); | ||
160 | -}; |
src/pages/Client/FollowRecord/Components/ClientImportModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { orderExport } from '@/services/order'; | ||
3 | +import { blobToJson } from '@/utils'; | ||
4 | +import { ModalForm, ProFormUploadDragger } from '@ant-design/pro-components'; | ||
5 | +import { Button, Form, message } from 'antd'; | ||
6 | +import { RcFile } from 'antd/es/upload'; | ||
7 | +import axios from 'axios'; | ||
8 | + | ||
9 | +export default () => { | ||
10 | + const [form] = Form.useForm(); | ||
11 | + const [messageApi, contextHolder] = message.useMessage(); | ||
12 | + const downloadImportTemplate = () => { | ||
13 | + messageApi.open({ | ||
14 | + type: 'loading', | ||
15 | + content: '正在导入...', | ||
16 | + duration: 0, | ||
17 | + }); | ||
18 | + orderExport( | ||
19 | + '/api/admin/client/downloadImportTemplate', | ||
20 | + '客户导入模板.xlsx', | ||
21 | + 'post', | ||
22 | + {}, | ||
23 | + () => { | ||
24 | + messageApi.destroy(); | ||
25 | + }, | ||
26 | + ); | ||
27 | + }; | ||
28 | + | ||
29 | + return ( | ||
30 | + <ModalForm | ||
31 | + title="导入客户信息" | ||
32 | + trigger={<Button type="primary">导入客户信息</Button>} | ||
33 | + form={form} | ||
34 | + autoFocusFirstInput | ||
35 | + modalProps={{ | ||
36 | + destroyOnClose: true, | ||
37 | + onCancel: () => console.log('run'), | ||
38 | + }} | ||
39 | + submitTimeout={2000} | ||
40 | + onFinish={async (values) => { | ||
41 | + const formData = new FormData(); | ||
42 | + values.file.forEach((file) => { | ||
43 | + formData.append('file', file.originFileObj as RcFile); | ||
44 | + }); | ||
45 | + axios({ | ||
46 | + url: '/api/admin/client/importClient', | ||
47 | + method: 'post', | ||
48 | + responseType: 'blob', | ||
49 | + headers: { | ||
50 | + Authorization: localStorage.getItem('token'), | ||
51 | + 'Content-Type': | ||
52 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | ||
53 | + }, | ||
54 | + data: formData, | ||
55 | + }) | ||
56 | + .then((response) => { | ||
57 | + let data = response.data; | ||
58 | + if (data.type === 'application/json') { | ||
59 | + blobToJson(data).then((dataJson) => { | ||
60 | + if (dataJson?.result === RESPONSE_CODE.SUCCESS) { | ||
61 | + message.success(dataJson?.message); | ||
62 | + } else { | ||
63 | + message.error(dataJson?.message); | ||
64 | + } | ||
65 | + }); | ||
66 | + } else { | ||
67 | + message.error('上传失败,已下载错误信息表格'); | ||
68 | + // 创建一个新的 Blob 对象,它包含了服务器响应的数据(即你的 Excel 文件) | ||
69 | + const blob = new Blob([response.data]); // Excel 的 MIME 类型 | ||
70 | + const downloadUrl = window.URL.createObjectURL(blob); | ||
71 | + const a = document.createElement('a'); | ||
72 | + a.href = downloadUrl; | ||
73 | + a.download = '银行流水导入模板.xlsx'; // 你可以为文件命名 | ||
74 | + document.body.appendChild(a); | ||
75 | + a.click(); // 模拟点击操作来下载文件 | ||
76 | + URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存 | ||
77 | + document.body.removeChild(a); | ||
78 | + } | ||
79 | + }) | ||
80 | + .catch((error) => { | ||
81 | + // 处理错误 | ||
82 | + message.error('系统出现异常了,请联系管理员', error); | ||
83 | + }) | ||
84 | + .finally(() => {}); | ||
85 | + return true; | ||
86 | + }} | ||
87 | + > | ||
88 | + <ProFormUploadDragger max={1} label="上传" name="file" /> | ||
89 | + <Button type="link" onClick={downloadImportTemplate}> | ||
90 | + 下载导入模板 | ||
91 | + </Button> | ||
92 | + {contextHolder} | ||
93 | + </ModalForm> | ||
94 | + ); | ||
95 | +}; |
src/pages/Client/FollowRecord/Components/ClientModal.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import { | ||
3 | + postAdminClientAddOrModifyClientComunicationInfo, | ||
4 | + postAdminClientQueryClientPage, | ||
5 | + postOrderErpOrderStagesUpload, | ||
6 | + postServiceConstClientWay, | ||
7 | +} from '@/services'; | ||
8 | +import { enumToSelect } from '@/utils'; | ||
9 | +import { | ||
10 | + ModalForm, | ||
11 | + ProFormDateTimePicker, | ||
12 | + ProFormSelect, | ||
13 | + ProFormText, | ||
14 | + ProFormTextArea, | ||
15 | + ProFormUploadDragger, | ||
16 | +} from '@ant-design/pro-components'; | ||
17 | +import { Button, Form, message } from 'antd'; | ||
18 | +import { RcFile } from 'antd/es/upload'; | ||
19 | +export default ({ data, type, reloadTable }) => { | ||
20 | + const [form] = Form.useForm(); | ||
21 | + const onfinish = async (values) => { | ||
22 | + const resSearchId = await postAdminClientQueryClientPage({ | ||
23 | + data: { | ||
24 | + groupFilter: 'all', | ||
25 | + }, | ||
26 | + }); | ||
27 | + const matchingItem = resSearchId.data.data.find( | ||
28 | + (item) => item.name === values.name, | ||
29 | + ); | ||
30 | + let matchedId; | ||
31 | + if (matchingItem) { | ||
32 | + matchedId = matchingItem.id; // 匹配成功,取出 id | ||
33 | + } else { | ||
34 | + matchedId = null; // 如果没有匹配项,可以设置为 null 或其他值 | ||
35 | + } | ||
36 | + const res = await postAdminClientAddOrModifyClientComunicationInfo({ | ||
37 | + data: { | ||
38 | + ...values, | ||
39 | + clientId: matchedId, | ||
40 | + }, | ||
41 | + }); | ||
42 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
43 | + message.success('新增成功'); | ||
44 | + reloadTable(); | ||
45 | + return true; | ||
46 | + } | ||
47 | + // 不返回不会关闭弹框 | ||
48 | + }; | ||
49 | + const optType = { | ||
50 | + add: { | ||
51 | + readOnly: false, | ||
52 | + title: '新增跟进记录', | ||
53 | + button: ( | ||
54 | + <Button size={'middle'} type="primary"> | ||
55 | + 新增 | ||
56 | + </Button> | ||
57 | + ), | ||
58 | + onFinish: onfinish, | ||
59 | + }, | ||
60 | + modify: { | ||
61 | + readOnly: false, | ||
62 | + title: '修改跟进记录', | ||
63 | + button: ( | ||
64 | + <Button size={'middle'} type="primary"> | ||
65 | + 编辑 | ||
66 | + </Button> | ||
67 | + ), | ||
68 | + onFinish: onfinish, | ||
69 | + }, | ||
70 | + detail: { | ||
71 | + readOnly: true, | ||
72 | + title: '查看跟进记录', | ||
73 | + button: ( | ||
74 | + <Button size={'middle'} type="primary" color="red"> | ||
75 | + 查看 | ||
76 | + </Button> | ||
77 | + ), | ||
78 | + onFinish: () => {}, | ||
79 | + }, | ||
80 | + }; | ||
81 | + return ( | ||
82 | + <ModalForm | ||
83 | + title={optType[type].title} | ||
84 | + resize={{ | ||
85 | + onResize() { | ||
86 | + console.log('resize!'); | ||
87 | + }, | ||
88 | + maxWidth: window.innerWidth * 0.8, | ||
89 | + minWidth: 400, | ||
90 | + }} | ||
91 | + form={form} | ||
92 | + trigger={optType[type].button} | ||
93 | + autoFocusFirstInput | ||
94 | + drawerProps={{ | ||
95 | + destroyOnClose: true, | ||
96 | + }} | ||
97 | + submitTimeout={2000} | ||
98 | + onFinish={optType[type].onFinish} | ||
99 | + > | ||
100 | + <ProFormSelect | ||
101 | + name="name" | ||
102 | + readonly={optType[type].readOnly} | ||
103 | + fieldProps={{ | ||
104 | + labelInValue: false, | ||
105 | + disabled: type === 'modify', | ||
106 | + }} | ||
107 | + initialValue={data ? data?.clientName + '' : null} | ||
108 | + label="客户" | ||
109 | + width="sm" | ||
110 | + request={async () => { | ||
111 | + const res = await postAdminClientQueryClientPage({ | ||
112 | + data: { | ||
113 | + groupFilter: 'all', | ||
114 | + }, | ||
115 | + }); | ||
116 | + console.log(data, '5656data?.nameedit'); | ||
117 | + const namesArray = res.data.data.map((item) => item.name); | ||
118 | + const formattedObject = namesArray.reduce((acc, name) => { | ||
119 | + acc[name] = name; // 将名称作为键和值 | ||
120 | + return acc; | ||
121 | + }, {}); | ||
122 | + console.log(namesArray, '5656namesArray'); | ||
123 | + return enumToSelect(formattedObject); | ||
124 | + }} | ||
125 | + rules={[ | ||
126 | + { | ||
127 | + required: true, | ||
128 | + message: '请选择客户', | ||
129 | + }, | ||
130 | + ]} | ||
131 | + ></ProFormSelect> | ||
132 | + <ProFormDateTimePicker | ||
133 | + name="datetime" | ||
134 | + label="日期" | ||
135 | + initialValue={data ? data?.datetime + '' : null} | ||
136 | + placeholder="请选择跟进时间" | ||
137 | + width="sm" | ||
138 | + rules={[ | ||
139 | + { | ||
140 | + required: true, | ||
141 | + message: '请选择日期', | ||
142 | + }, | ||
143 | + ]} | ||
144 | + /> | ||
145 | + <ProFormSelect | ||
146 | + name="way" | ||
147 | + width="sm" | ||
148 | + readonly={optType[type].readOnly} | ||
149 | + fieldProps={{ | ||
150 | + labelInValue: false, | ||
151 | + }} | ||
152 | + initialValue={data?.way ? data?.way + '' : null} | ||
153 | + label="类型" | ||
154 | + request={async () => { | ||
155 | + const res = await postServiceConstClientWay(); | ||
156 | + return enumToSelect(res.data); | ||
157 | + }} | ||
158 | + rules={[ | ||
159 | + { | ||
160 | + required: true, | ||
161 | + message: '请选择跟进类型', | ||
162 | + }, | ||
163 | + ]} | ||
164 | + ></ProFormSelect> | ||
165 | + <ProFormTextArea | ||
166 | + name="content" | ||
167 | + label="详情" | ||
168 | + placeholder="请输入详情" | ||
169 | + initialValue={data?.content} | ||
170 | + readonly={optType[type].readOnly} | ||
171 | + rules={[ | ||
172 | + { | ||
173 | + required: true, | ||
174 | + message: '请输入详情', | ||
175 | + }, | ||
176 | + ]} | ||
177 | + ></ProFormTextArea> | ||
178 | + <ProFormUploadDragger | ||
179 | + label="附件" | ||
180 | + name="attachment" | ||
181 | + action="upload.do" | ||
182 | + hidden={optType[type].readOnly} | ||
183 | + onChange={(info) => { | ||
184 | + const uploadFile = async ({ fileList: newFileList }) => { | ||
185 | + if (newFileList.length > 0) { | ||
186 | + const formData = new FormData(); | ||
187 | + formData.append('file', newFileList[0].originFileObj as RcFile); | ||
188 | + const res = await postOrderErpOrderStagesUpload({ | ||
189 | + data: formData, | ||
190 | + headers: { | ||
191 | + 'Content-Type': | ||
192 | + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq', | ||
193 | + }, | ||
194 | + }); | ||
195 | + const url = res.data; | ||
196 | + console.log('attachments' + JSON.stringify(url)); | ||
197 | + form.setFieldValue('attachments', url); | ||
198 | + } else { | ||
199 | + form.setFieldValue('attachments', null); | ||
200 | + } | ||
201 | + }; | ||
202 | + uploadFile(info); | ||
203 | + }} | ||
204 | + max={1} | ||
205 | + /> | ||
206 | + <a hidden={!optType[type].readOnly} href={data?.attachments} download> | ||
207 | + 下载附件 | ||
208 | + </a> | ||
209 | + <ProFormText | ||
210 | + initialValue={data?.attachments} | ||
211 | + name="attachments" | ||
212 | + hidden | ||
213 | + ></ProFormText> | ||
214 | + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText> | ||
215 | + </ModalForm> | ||
216 | + ); | ||
217 | +}; |
src/pages/Client/FollowRecord/Components/CommunicationHistoryModal.tsx
0 → 100644
1 | +import ClientModal from '@/pages/Client/FollowRecord/Components/ClientModal'; | ||
2 | +import { | ||
3 | + postAdminClientQueryClientComunicationInfo, | ||
4 | + postAdminClientRemoveClientComunicationInfo, | ||
5 | +} from '@/services/request'; | ||
6 | +import { ModalForm } from '@ant-design/pro-components'; | ||
7 | +import { Button, Descriptions, Space } from 'antd'; | ||
8 | +import { useEffect, useRef, useState } from 'react'; | ||
9 | + | ||
10 | +export default ({ data, reloadTable }) => { | ||
11 | + // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示 | ||
12 | + const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法 | ||
13 | + | ||
14 | + const [datetime, setDatetime] = useState(); // 跟进日期 | ||
15 | + const [createByName, setCreateByName] = useState(''); // 跟进人员 | ||
16 | + const [clientName, setClientName] = useState(''); // 客户名称 | ||
17 | + // const [clientAddress, setClientAddress] = useState(''); // 客户地址 | ||
18 | + const [way, setWay] = useState(); // 类型 | ||
19 | + // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询 | ||
20 | + // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询 | ||
21 | + // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态 | ||
22 | + // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询 | ||
23 | + const [content, setContent] = useState(''); // 跟进详情 | ||
24 | + const [createTime, setCreateTime] = useState(null); // 创建时间 | ||
25 | + const [attachments, setAttachments] = useState(); // 创建时间 | ||
26 | + | ||
27 | + useEffect(() => { | ||
28 | + const request = async () => { | ||
29 | + console.log(data, '5656datasearch'); | ||
30 | + const res = await postAdminClientQueryClientComunicationInfo({ | ||
31 | + data: { | ||
32 | + id: data.id, | ||
33 | + }, | ||
34 | + }); | ||
35 | + console.log(res, '5656res'); | ||
36 | + const dataSearch = res.data.data[0]; | ||
37 | + if (dataSearch) { | ||
38 | + setDatetime(dataSearch.datetime); // 设置跟进日期 | ||
39 | + // setDateRange(data.dateRange || []); // 设置跟进时间范围 | ||
40 | + setCreateByName(dataSearch.createByName); // 设置跟进人员 | ||
41 | + setClientName(dataSearch.clientName); // 设置客户名称 | ||
42 | + // setClientAddress(data.clientAddress || ''); // 设置客户地址 | ||
43 | + // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询 | ||
44 | + // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询 | ||
45 | + // setTradeStatus(data.tradeStatus || ''); // 设置客户状态 | ||
46 | + // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询 | ||
47 | + setContent(dataSearch.content); // 设置跟进详情 | ||
48 | + setCreateTime(dataSearch.createTime); // 设置创建时间 | ||
49 | + setWay(dataSearch.wayText); | ||
50 | + setAttachments(dataSearch.attachments); | ||
51 | + } | ||
52 | + console.log(attachments, '5656attachments'); | ||
53 | + }; | ||
54 | + request(); | ||
55 | + }, []); | ||
56 | + const items = [ | ||
57 | + { | ||
58 | + key: '1', | ||
59 | + label: '跟进日期', | ||
60 | + children: datetime, // 跟进日期 | ||
61 | + }, | ||
62 | + { | ||
63 | + key: '2', | ||
64 | + label: '跟进人员', | ||
65 | + children: createByName, // 跟进人员 | ||
66 | + }, | ||
67 | + { | ||
68 | + key: '3', | ||
69 | + label: '客户名称', | ||
70 | + children: clientName, // 客户名称 | ||
71 | + }, | ||
72 | + { | ||
73 | + key: '4', | ||
74 | + label: '跟进详情', | ||
75 | + children: content, // 跟进详情 | ||
76 | + }, | ||
77 | + { | ||
78 | + key: '5', | ||
79 | + label: '创建时间', | ||
80 | + children: createTime, // 创建时间 | ||
81 | + }, | ||
82 | + { | ||
83 | + key: '6', | ||
84 | + label: '跟进类型', | ||
85 | + children: way, // 跟进类型 | ||
86 | + }, | ||
87 | + ]; | ||
88 | + const handleDelete = async () => { | ||
89 | + console.log(JSON.stringify(data), '5656record'); | ||
90 | + // 调用删除接口 | ||
91 | + const success = await postAdminClientRemoveClientComunicationInfo({ | ||
92 | + query: { | ||
93 | + id: data.id, | ||
94 | + }, | ||
95 | + }); | ||
96 | + // setIsModalVisible(false); | ||
97 | + if (success) { | ||
98 | + actionRef?.current?.reload(); // 重新加载表格数据 | ||
99 | + } | ||
100 | + }; | ||
101 | + return ( | ||
102 | + <Space> | ||
103 | + <ModalForm | ||
104 | + title="跟进记录" | ||
105 | + trigger={<Button type="link">查看</Button>} | ||
106 | + submitter={{ | ||
107 | + resetButtonProps: { | ||
108 | + style: { | ||
109 | + display: 'none', | ||
110 | + }, | ||
111 | + }, | ||
112 | + submitButtonProps: { | ||
113 | + style: { | ||
114 | + display: 'none', | ||
115 | + }, | ||
116 | + }, | ||
117 | + render: (props, defaultDoms) => { | ||
118 | + return [ | ||
119 | + ...defaultDoms, | ||
120 | + <> | ||
121 | + <ClientModal | ||
122 | + key={'modify'} | ||
123 | + data={data} // 将表单数据传递给 ClientModal | ||
124 | + reloadTable={() => { | ||
125 | + actionRef?.current?.reload(); // 重新加载表格数据 | ||
126 | + props.submit(); | ||
127 | + reloadTable(); | ||
128 | + console.log('5656close'); | ||
129 | + }} | ||
130 | + type={'modify'} | ||
131 | + onFinish={() => { | ||
132 | + // setIsModalVisible(false); | ||
133 | + }} // 关闭 Modal | ||
134 | + style={{ marginRight: '10px' }} | ||
135 | + /> | ||
136 | + <Button | ||
137 | + key={'delete'} | ||
138 | + onClick={() => { | ||
139 | + handleDelete(); | ||
140 | + props.submit(); | ||
141 | + reloadTable(); | ||
142 | + }} | ||
143 | + type="primary" | ||
144 | + size="middle" | ||
145 | + danger // 使用 danger 属性来将按钮颜色设置为红色 | ||
146 | + style={{ marginLeft: '10px' }} | ||
147 | + onFinish={() => { | ||
148 | + actionRef.current.reload(); | ||
149 | + }} | ||
150 | + > | ||
151 | + 删除 | ||
152 | + </Button> | ||
153 | + </>, | ||
154 | + ]; | ||
155 | + }, | ||
156 | + }} | ||
157 | + onFinish={async () => { | ||
158 | + // 提交成功后,显示 ClientDrawer | ||
159 | + // setIsModalVisible(true); | ||
160 | + return true; | ||
161 | + }} | ||
162 | + > | ||
163 | + <Descriptions items={items} column={1} /> | ||
164 | + <a href={attachments} download> | ||
165 | + 下载附件 | ||
166 | + </a> | ||
167 | + </ModalForm> | ||
168 | + </Space> | ||
169 | + ); | ||
170 | +}; |
src/pages/Client/FollowRecord/index.tsx
0 → 100644
1 | +import { RESPONSE_CODE } from '@/constants/enum'; | ||
2 | +import ClientModal from '@/pages/Client/FollowRecord/Components/ClientModal'; | ||
3 | +import CommunicationHistoryModal from '@/pages/Client/FollowRecord/Components/CommunicationHistoryModal'; | ||
4 | +import { | ||
5 | + postAdminClientQueryClientComunicationInfo, | ||
6 | + postAdminClientRemoveClientComunicationInfo, | ||
7 | + // postServiceConstClientGroupFilters, | ||
8 | + postServiceConstClientWay, | ||
9 | + postServiceConstTradeStatus, | ||
10 | +} from '@/services'; | ||
11 | +import { enumToSelect } from '@/utils'; | ||
12 | +import type { ActionType } from '@ant-design/pro-components'; | ||
13 | +import { ProTable } from '@ant-design/pro-components'; | ||
14 | +import { Button, Space, message } from 'antd'; | ||
15 | +import { useRef, useState } from 'react'; | ||
16 | + | ||
17 | +export default () => { | ||
18 | + const actionRef = useRef<ActionType>(); | ||
19 | + const [refreshKey, setRefreshKey] = useState(0); // 用于强制刷新的键 | ||
20 | + | ||
21 | + const reload = () => { | ||
22 | + actionRef.current.reload(); // 重新加载数据 | ||
23 | + console.log('5656flush'); | ||
24 | + | ||
25 | + // 更新 refreshKey,强制刷新 CommunicationHistoryModal | ||
26 | + setRefreshKey((prevKey) => prevKey + 1); | ||
27 | + }; | ||
28 | + //biaoji | ||
29 | + const columns = [ | ||
30 | + { | ||
31 | + title: '跟进日期', | ||
32 | + key: 'datetime', | ||
33 | + width: 150, | ||
34 | + ellipsis: true, | ||
35 | + dataIndex: 'datetime', | ||
36 | + valueType: 'dateTime', | ||
37 | + hideInSearch: true, | ||
38 | + search: { | ||
39 | + transform: (value) => { | ||
40 | + if (value) { | ||
41 | + return { | ||
42 | + createTimeGe: value[0], | ||
43 | + createTimeLe: value[1], | ||
44 | + }; | ||
45 | + } | ||
46 | + }, | ||
47 | + }, | ||
48 | + }, | ||
49 | + { | ||
50 | + title: '跟进时间', | ||
51 | + dataIndex: 'dateRange', | ||
52 | + valueType: 'dateRange', | ||
53 | + hideInTable: true, | ||
54 | + search: { | ||
55 | + transform: (value) => { | ||
56 | + if (value) { | ||
57 | + return { | ||
58 | + createTimeGe: value[0], | ||
59 | + createTimeLe: value[1], | ||
60 | + }; | ||
61 | + } | ||
62 | + }, | ||
63 | + }, | ||
64 | + }, | ||
65 | + { | ||
66 | + title: '跟进人员', | ||
67 | + dataIndex: 'createByName', | ||
68 | + width: 100, | ||
69 | + ellipsis: true, | ||
70 | + hideInSearch: false, | ||
71 | + }, | ||
72 | + { | ||
73 | + title: '客户名称', | ||
74 | + dataIndex: 'clientName', | ||
75 | + width: 150, | ||
76 | + ellipsis: true, | ||
77 | + hideInSearch: true, | ||
78 | + }, | ||
79 | + { | ||
80 | + title: '客户地址', | ||
81 | + dataIndex: 'clientAddress', | ||
82 | + width: 250, | ||
83 | + ellipsis: true, | ||
84 | + hideInSearch: true, | ||
85 | + }, | ||
86 | + { | ||
87 | + title: '类型', | ||
88 | + dataIndex: 'wayText', | ||
89 | + width: 100, | ||
90 | + ellipsis: true, | ||
91 | + hideInSearch: true, | ||
92 | + }, | ||
93 | + { | ||
94 | + title: '类型', | ||
95 | + dataIndex: 'way', | ||
96 | + width: 100, | ||
97 | + ellipsis: true, | ||
98 | + hideInSearch: false, | ||
99 | + hideInTable: true, | ||
100 | + request: async () => { | ||
101 | + const res = await postServiceConstClientWay(); | ||
102 | + return enumToSelect(res.data); | ||
103 | + }, | ||
104 | + }, | ||
105 | + { | ||
106 | + title: '客户名称', | ||
107 | + dataIndex: 'clientNameLike', | ||
108 | + width: 150, | ||
109 | + ellipsis: true, | ||
110 | + hideInSearch: false, | ||
111 | + hideInTable: true, | ||
112 | + }, | ||
113 | + { | ||
114 | + title: '客户地址', | ||
115 | + dataIndex: 'clientAddressLike', | ||
116 | + width: 250, | ||
117 | + ellipsis: true, | ||
118 | + hideInSearch: false, | ||
119 | + hideInTable: true, | ||
120 | + }, | ||
121 | + { | ||
122 | + title: '客户状态', | ||
123 | + dataIndex: 'tradeStatus', | ||
124 | + width: 100, | ||
125 | + ellipsis: true, | ||
126 | + hideInSearch: true, | ||
127 | + }, | ||
128 | + { | ||
129 | + title: '客户状态', | ||
130 | + dataIndex: 'tradeStatusLike', | ||
131 | + width: 100, | ||
132 | + ellipsis: true, | ||
133 | + hideInSearch: false, | ||
134 | + hideInTable: true, | ||
135 | + request: async () => { | ||
136 | + const res = await postServiceConstTradeStatus(); | ||
137 | + return enumToSelect(res.data); | ||
138 | + }, | ||
139 | + }, | ||
140 | + { | ||
141 | + title: '跟进详情', | ||
142 | + dataIndex: 'content', | ||
143 | + width: 250, | ||
144 | + ellipsis: true, | ||
145 | + hideInSearch: false, | ||
146 | + }, | ||
147 | + { | ||
148 | + title: '创建时间', | ||
149 | + dataIndex: 'createTime', | ||
150 | + width: 150, | ||
151 | + ellipsis: true, | ||
152 | + hideInSearch: true, | ||
153 | + }, | ||
154 | + { | ||
155 | + title: '附件', | ||
156 | + dataIndex: 'attachments', | ||
157 | + width: 150, | ||
158 | + ellipsis: true, | ||
159 | + hideInSearch: true, | ||
160 | + hideInTable: true, | ||
161 | + }, | ||
162 | + { | ||
163 | + title: '操作', | ||
164 | + valueType: 'option', | ||
165 | + key: 'option', | ||
166 | + width: 150, | ||
167 | + render: (text, record, index, action) => { | ||
168 | + const handleDelete = async () => { | ||
169 | + // console.log(JSON.stringify(record), '5656record'); | ||
170 | + // 调用删除接口 | ||
171 | + const success = await postAdminClientRemoveClientComunicationInfo({ | ||
172 | + query: { | ||
173 | + id: record.id, | ||
174 | + }, | ||
175 | + }); | ||
176 | + if (success) { | ||
177 | + action.reload(); // 刷新表格 | ||
178 | + } | ||
179 | + }; | ||
180 | + return [ | ||
181 | + <CommunicationHistoryModal | ||
182 | + // key={'communicationHistory'} | ||
183 | + key={`communicationHistory-${refreshKey}`} // 使用 refreshKey 来强制更新组件 | ||
184 | + data={record} | ||
185 | + // reloadTable={() => { | ||
186 | + // actionRef.current.reload(); | ||
187 | + // console.log('5656flush'); | ||
188 | + // }} | ||
189 | + reloadTable={reload} | ||
190 | + />, | ||
191 | + <> | ||
192 | + <Button | ||
193 | + key={'delete'} | ||
194 | + onClick={() => { | ||
195 | + handleDelete(); | ||
196 | + actionRef.current.reload(); | ||
197 | + }} | ||
198 | + // reloadTable={() => { | ||
199 | + // actionRef.current.reload(); | ||
200 | + // }} | ||
201 | + type="link" | ||
202 | + size="middle" | ||
203 | + danger // 使用 danger 属性来将按钮颜色设置为红色 | ||
204 | + // onFinish={() => { | ||
205 | + // actionRef.current.reload(); | ||
206 | + // }} | ||
207 | + > | ||
208 | + 删除 | ||
209 | + </Button> | ||
210 | + </>, | ||
211 | + ]; | ||
212 | + }, | ||
213 | + }, | ||
214 | + ]; | ||
215 | + | ||
216 | + // useEffect(() => { | ||
217 | + // const pullGroupFilterDataOptions = async () => { | ||
218 | + // const res = await postServiceConstClientGroupFilters(); | ||
219 | + // console.log('setGroupFilterDataOptions' + JSON.stringify(res.data)); | ||
220 | + // setGroupFilterDataOptions(enumToSelect(res.data)); | ||
221 | + // }; | ||
222 | + // pullGroupFilterDataOptions(); | ||
223 | + // }, []); | ||
224 | + // useEffect(() => { | ||
225 | + // actionRef.current?.reload(); | ||
226 | + // }, [groupFilter]); | ||
227 | + return ( | ||
228 | + <> | ||
229 | + <Space direction="vertical" size="middle" style={{ display: 'flex' }}> | ||
230 | + <ProTable | ||
231 | + columns={columns} | ||
232 | + actionRef={actionRef} | ||
233 | + cardBordered | ||
234 | + request={async (params) => { | ||
235 | + const res = await postAdminClientQueryClientComunicationInfo({ | ||
236 | + data: { | ||
237 | + ...params, | ||
238 | + }, | ||
239 | + }); | ||
240 | + console.log(params, '5656566params'); | ||
241 | + if (res.result === RESPONSE_CODE.SUCCESS) { | ||
242 | + console.log(JSON.stringify(res.data)); | ||
243 | + return { | ||
244 | + ...res.data, | ||
245 | + data: res.data.data.map((item) => { | ||
246 | + return { | ||
247 | + ...item, | ||
248 | + tid: (Math.random() * 1000000).toFixed(0), | ||
249 | + }; | ||
250 | + }), | ||
251 | + }; | ||
252 | + } else { | ||
253 | + message.error('获取失败'); | ||
254 | + } | ||
255 | + }} | ||
256 | + search={{ | ||
257 | + optionRender: (searchConfig, formProps, dom) => [...dom.reverse()], | ||
258 | + }} | ||
259 | + scroll={{ | ||
260 | + x: 1400, | ||
261 | + }} | ||
262 | + editable={{ | ||
263 | + type: 'multiple', | ||
264 | + }} | ||
265 | + columnsState={{ | ||
266 | + persistenceKey: 'pro-table-singe-demos', | ||
267 | + persistenceType: 'localStorage', | ||
268 | + defaultValue: { | ||
269 | + option: { fixed: 'right', disable: true }, | ||
270 | + }, | ||
271 | + onChange(value) { | ||
272 | + console.log('value: ', value); | ||
273 | + }, | ||
274 | + }} | ||
275 | + rowKey="id" | ||
276 | + options={{ | ||
277 | + setting: { | ||
278 | + listsHeight: 400, | ||
279 | + }, | ||
280 | + }} | ||
281 | + form={{ | ||
282 | + // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下 | ||
283 | + syncToUrl: (values, type) => { | ||
284 | + if (type === 'get') { | ||
285 | + return { | ||
286 | + ...values, | ||
287 | + created_at: [values.startTime, values.endTime], | ||
288 | + }; | ||
289 | + } | ||
290 | + return values; | ||
291 | + }, | ||
292 | + }} | ||
293 | + pagination={{ | ||
294 | + pageSize: 5, | ||
295 | + onChange: (page) => console.log(page), | ||
296 | + }} | ||
297 | + dateFormatter="string" | ||
298 | + headerTitle="高级表格" | ||
299 | + toolBarRender={() => [ | ||
300 | + <ClientModal | ||
301 | + key={'add'} | ||
302 | + reloadTable={() => { | ||
303 | + actionRef.current.reload(); | ||
304 | + }} | ||
305 | + type={'add'} | ||
306 | + />, | ||
307 | + ]} | ||
308 | + /> | ||
309 | + </Space> | ||
310 | + {/* {contextHolder} */} | ||
311 | + </> | ||
312 | + ); | ||
313 | +}; |
src/services/definition.ts
@@ -94,6 +94,11 @@ export interface AdminAuthUserVO { | @@ -94,6 +94,11 @@ export interface AdminAuthUserVO { | ||
94 | export interface AdminClientDto { | 94 | export interface AdminClientDto { |
95 | /** | 95 | /** |
96 | * @description | 96 | * @description |
97 | + * 客户地址 | ||
98 | + */ | ||
99 | + address?: string; | ||
100 | + /** | ||
101 | + * @description | ||
97 | * 市 | 102 | * 市 |
98 | */ | 103 | */ |
99 | city?: string; | 104 | city?: string; |
@@ -108,17 +113,17 @@ export interface AdminClientDto { | @@ -108,17 +113,17 @@ export interface AdminClientDto { | ||
108 | */ | 113 | */ |
109 | companyAddressText?: string; | 114 | companyAddressText?: string; |
110 | companyId?: string; | 115 | companyId?: string; |
111 | - /** | ||
112 | - * @description | ||
113 | - * 单位名称 | ||
114 | - */ | ||
115 | - companyName?: string; | ||
116 | contacts?: string; | 116 | contacts?: string; |
117 | createBy?: string; | 117 | createBy?: string; |
118 | /** @format date-time */ | 118 | /** @format date-time */ |
119 | createTime?: string; | 119 | createTime?: string; |
120 | /** | 120 | /** |
121 | * @description | 121 | * @description |
122 | + * 详细地址 | ||
123 | + */ | ||
124 | + detailAddress?: string; | ||
125 | + /** | ||
126 | + * @description | ||
122 | * 区 | 127 | * 区 |
123 | */ | 128 | */ |
124 | district?: string; | 129 | district?: string; |
@@ -2791,6 +2796,7 @@ export interface QueryBankStatementDto { | @@ -2791,6 +2796,7 @@ export interface QueryBankStatementDto { | ||
2791 | } | 2796 | } |
2792 | 2797 | ||
2793 | export interface QueryClientDto { | 2798 | export interface QueryClientDto { |
2799 | + address?: string; | ||
2794 | companyAddressLike?: string; | 2800 | companyAddressLike?: string; |
2795 | companyIds?: Array<number>; | 2801 | companyIds?: Array<number>; |
2796 | companyNameLike?: string; | 2802 | companyNameLike?: string; |
@@ -2802,6 +2808,7 @@ export interface QueryClientDto { | @@ -2802,6 +2808,7 @@ export interface QueryClientDto { | ||
2802 | createTimeLe?: string; | 2808 | createTimeLe?: string; |
2803 | /** @format int32 */ | 2809 | /** @format int32 */ |
2804 | current?: number; | 2810 | current?: number; |
2811 | + detailAddress?: string; | ||
2805 | /** @format int32 */ | 2812 | /** @format int32 */ |
2806 | end?: number; | 2813 | end?: number; |
2807 | groupFilter?: string; | 2814 | groupFilter?: string; |
@@ -2811,6 +2818,8 @@ export interface QueryClientDto { | @@ -2811,6 +2818,8 @@ export interface QueryClientDto { | ||
2811 | /** @format int32 */ | 2818 | /** @format int32 */ |
2812 | pageSize?: number; | 2819 | pageSize?: number; |
2813 | phoneNumber?: string; | 2820 | phoneNumber?: string; |
2821 | + requirements?: string; | ||
2822 | + source?: string; | ||
2814 | /** @format int32 */ | 2823 | /** @format int32 */ |
2815 | start?: number; | 2824 | start?: number; |
2816 | /** @format int32 */ | 2825 | /** @format int32 */ |
src/services/request.ts
@@ -64,6 +64,7 @@ import type { | @@ -64,6 +64,7 @@ import type { | ||
64 | MaterialUnitListRes, | 64 | MaterialUnitListRes, |
65 | MeasureUnitListRes, | 65 | MeasureUnitListRes, |
66 | MessageQueryDTO, | 66 | MessageQueryDTO, |
67 | + ModelAndView, | ||
67 | OrderAddVO, | 68 | OrderAddVO, |
68 | OrderAuditLogQueryVO, | 69 | OrderAuditLogQueryVO, |
69 | OrderBaseInfoQueryVO, | 70 | OrderBaseInfoQueryVO, |
@@ -360,6 +361,79 @@ export const postAdminClientAddOrModifyClientComunicationInfo = | @@ -360,6 +361,79 @@ export const postAdminClientAddOrModifyClientComunicationInfo = | ||
360 | return request; | 361 | return request; |
361 | })(); | 362 | })(); |
362 | 363 | ||
364 | +/** @description request parameter type for postAdminClientDeleteAdminClient */ | ||
365 | +export interface PostAdminClientDeleteAdminClientOption { | ||
366 | + /** | ||
367 | + * @description | ||
368 | + * id | ||
369 | + * @format int64 | ||
370 | + */ | ||
371 | + query?: { | ||
372 | + /** | ||
373 | + @description | ||
374 | + id | ||
375 | + @format int64 */ | ||
376 | + id?: number; | ||
377 | + }; | ||
378 | +} | ||
379 | + | ||
380 | +/** @description response type for postAdminClientDeleteAdminClient */ | ||
381 | +export interface PostAdminClientDeleteAdminClientResponse { | ||
382 | + /** | ||
383 | + * @description | ||
384 | + * OK | ||
385 | + */ | ||
386 | + 200: ServerResult; | ||
387 | + /** | ||
388 | + * @description | ||
389 | + * Created | ||
390 | + */ | ||
391 | + 201: any; | ||
392 | + /** | ||
393 | + * @description | ||
394 | + * Unauthorized | ||
395 | + */ | ||
396 | + 401: any; | ||
397 | + /** | ||
398 | + * @description | ||
399 | + * Forbidden | ||
400 | + */ | ||
401 | + 403: any; | ||
402 | + /** | ||
403 | + * @description | ||
404 | + * Not Found | ||
405 | + */ | ||
406 | + 404: any; | ||
407 | +} | ||
408 | + | ||
409 | +export type PostAdminClientDeleteAdminClientResponseSuccess = | ||
410 | + PostAdminClientDeleteAdminClientResponse[200]; | ||
411 | +/** | ||
412 | + * @description | ||
413 | + * 删除客户 | ||
414 | + * @tags 客户管理 | ||
415 | + * @produces * | ||
416 | + * @consumes application/json | ||
417 | + */ | ||
418 | +export const postAdminClientDeleteAdminClient = /* #__PURE__ */ (() => { | ||
419 | + const method = 'post'; | ||
420 | + const url = '/admin/client/deleteAdminClient'; | ||
421 | + function request( | ||
422 | + option?: PostAdminClientDeleteAdminClientOption, | ||
423 | + ): Promise<PostAdminClientDeleteAdminClientResponseSuccess> { | ||
424 | + return requester(request.url, { | ||
425 | + method: request.method, | ||
426 | + ...option, | ||
427 | + }) as unknown as Promise<PostAdminClientDeleteAdminClientResponseSuccess>; | ||
428 | + } | ||
429 | + | ||
430 | + /** http method */ | ||
431 | + request.method = method; | ||
432 | + /** request url */ | ||
433 | + request.url = url; | ||
434 | + return request; | ||
435 | +})(); | ||
436 | + | ||
363 | /** @description response type for postAdminClientDownloadImportTemplate */ | 437 | /** @description response type for postAdminClientDownloadImportTemplate */ |
364 | export interface PostAdminClientDownloadImportTemplateResponse { | 438 | export interface PostAdminClientDownloadImportTemplateResponse { |
365 | /** | 439 | /** |
@@ -3237,9 +3311,7 @@ export interface GetErrorResponse { | @@ -3237,9 +3311,7 @@ export interface GetErrorResponse { | ||
3237 | * @description | 3311 | * @description |
3238 | * OK | 3312 | * OK |
3239 | */ | 3313 | */ |
3240 | - 200: { | ||
3241 | - [propertyName: string]: any; | ||
3242 | - }; | 3314 | + 200: ModelAndView; |
3243 | /** | 3315 | /** |
3244 | * @description | 3316 | * @description |
3245 | * Unauthorized | 3317 | * Unauthorized |
@@ -3260,9 +3332,9 @@ export interface GetErrorResponse { | @@ -3260,9 +3332,9 @@ export interface GetErrorResponse { | ||
3260 | export type GetErrorResponseSuccess = GetErrorResponse[200]; | 3332 | export type GetErrorResponseSuccess = GetErrorResponse[200]; |
3261 | /** | 3333 | /** |
3262 | * @description | 3334 | * @description |
3263 | - * error | 3335 | + * errorHtml |
3264 | * @tags basic-error-controller | 3336 | * @tags basic-error-controller |
3265 | - * @produces * | 3337 | + * @produces text/html |
3266 | */ | 3338 | */ |
3267 | export const getError = /* #__PURE__ */ (() => { | 3339 | export const getError = /* #__PURE__ */ (() => { |
3268 | const method = 'get'; | 3340 | const method = 'get'; |
@@ -3286,9 +3358,7 @@ export interface PutErrorResponse { | @@ -3286,9 +3358,7 @@ export interface PutErrorResponse { | ||
3286 | * @description | 3358 | * @description |
3287 | * OK | 3359 | * OK |
3288 | */ | 3360 | */ |
3289 | - 200: { | ||
3290 | - [propertyName: string]: any; | ||
3291 | - }; | 3361 | + 200: ModelAndView; |
3292 | /** | 3362 | /** |
3293 | * @description | 3363 | * @description |
3294 | * Created | 3364 | * Created |
@@ -3314,9 +3384,9 @@ export interface PutErrorResponse { | @@ -3314,9 +3384,9 @@ export interface PutErrorResponse { | ||
3314 | export type PutErrorResponseSuccess = PutErrorResponse[200]; | 3384 | export type PutErrorResponseSuccess = PutErrorResponse[200]; |
3315 | /** | 3385 | /** |
3316 | * @description | 3386 | * @description |
3317 | - * error | 3387 | + * errorHtml |
3318 | * @tags basic-error-controller | 3388 | * @tags basic-error-controller |
3319 | - * @produces * | 3389 | + * @produces text/html |
3320 | * @consumes application/json | 3390 | * @consumes application/json |
3321 | */ | 3391 | */ |
3322 | export const putError = /* #__PURE__ */ (() => { | 3392 | export const putError = /* #__PURE__ */ (() => { |
@@ -3341,9 +3411,7 @@ export interface PostErrorResponse { | @@ -3341,9 +3411,7 @@ export interface PostErrorResponse { | ||
3341 | * @description | 3411 | * @description |
3342 | * OK | 3412 | * OK |
3343 | */ | 3413 | */ |
3344 | - 200: { | ||
3345 | - [propertyName: string]: any; | ||
3346 | - }; | 3414 | + 200: ModelAndView; |
3347 | /** | 3415 | /** |
3348 | * @description | 3416 | * @description |
3349 | * Created | 3417 | * Created |
@@ -3369,9 +3437,9 @@ export interface PostErrorResponse { | @@ -3369,9 +3437,9 @@ export interface PostErrorResponse { | ||
3369 | export type PostErrorResponseSuccess = PostErrorResponse[200]; | 3437 | export type PostErrorResponseSuccess = PostErrorResponse[200]; |
3370 | /** | 3438 | /** |
3371 | * @description | 3439 | * @description |
3372 | - * error | 3440 | + * errorHtml |
3373 | * @tags basic-error-controller | 3441 | * @tags basic-error-controller |
3374 | - * @produces * | 3442 | + * @produces text/html |
3375 | * @consumes application/json | 3443 | * @consumes application/json |
3376 | */ | 3444 | */ |
3377 | export const postError = /* #__PURE__ */ (() => { | 3445 | export const postError = /* #__PURE__ */ (() => { |
@@ -3396,9 +3464,7 @@ export interface DeleteErrorResponse { | @@ -3396,9 +3464,7 @@ export interface DeleteErrorResponse { | ||
3396 | * @description | 3464 | * @description |
3397 | * OK | 3465 | * OK |
3398 | */ | 3466 | */ |
3399 | - 200: { | ||
3400 | - [propertyName: string]: any; | ||
3401 | - }; | 3467 | + 200: ModelAndView; |
3402 | /** | 3468 | /** |
3403 | * @description | 3469 | * @description |
3404 | * No Content | 3470 | * No Content |
@@ -3419,9 +3485,9 @@ export interface DeleteErrorResponse { | @@ -3419,9 +3485,9 @@ export interface DeleteErrorResponse { | ||
3419 | export type DeleteErrorResponseSuccess = DeleteErrorResponse[200]; | 3485 | export type DeleteErrorResponseSuccess = DeleteErrorResponse[200]; |
3420 | /** | 3486 | /** |
3421 | * @description | 3487 | * @description |
3422 | - * error | 3488 | + * errorHtml |
3423 | * @tags basic-error-controller | 3489 | * @tags basic-error-controller |
3424 | - * @produces * | 3490 | + * @produces text/html |
3425 | */ | 3491 | */ |
3426 | export const deleteError = /* #__PURE__ */ (() => { | 3492 | export const deleteError = /* #__PURE__ */ (() => { |
3427 | const method = 'delete'; | 3493 | const method = 'delete'; |
@@ -3445,9 +3511,7 @@ export interface OptionsErrorResponse { | @@ -3445,9 +3511,7 @@ export interface OptionsErrorResponse { | ||
3445 | * @description | 3511 | * @description |
3446 | * OK | 3512 | * OK |
3447 | */ | 3513 | */ |
3448 | - 200: { | ||
3449 | - [propertyName: string]: any; | ||
3450 | - }; | 3514 | + 200: ModelAndView; |
3451 | /** | 3515 | /** |
3452 | * @description | 3516 | * @description |
3453 | * No Content | 3517 | * No Content |
@@ -3468,9 +3532,9 @@ export interface OptionsErrorResponse { | @@ -3468,9 +3532,9 @@ export interface OptionsErrorResponse { | ||
3468 | export type OptionsErrorResponseSuccess = OptionsErrorResponse[200]; | 3532 | export type OptionsErrorResponseSuccess = OptionsErrorResponse[200]; |
3469 | /** | 3533 | /** |
3470 | * @description | 3534 | * @description |
3471 | - * error | 3535 | + * errorHtml |
3472 | * @tags basic-error-controller | 3536 | * @tags basic-error-controller |
3473 | - * @produces * | 3537 | + * @produces text/html |
3474 | * @consumes application/json | 3538 | * @consumes application/json |
3475 | */ | 3539 | */ |
3476 | export const optionsError = /* #__PURE__ */ (() => { | 3540 | export const optionsError = /* #__PURE__ */ (() => { |
@@ -3495,9 +3559,7 @@ export interface HeadErrorResponse { | @@ -3495,9 +3559,7 @@ export interface HeadErrorResponse { | ||
3495 | * @description | 3559 | * @description |
3496 | * OK | 3560 | * OK |
3497 | */ | 3561 | */ |
3498 | - 200: { | ||
3499 | - [propertyName: string]: any; | ||
3500 | - }; | 3562 | + 200: ModelAndView; |
3501 | /** | 3563 | /** |
3502 | * @description | 3564 | * @description |
3503 | * No Content | 3565 | * No Content |
@@ -3518,9 +3580,9 @@ export interface HeadErrorResponse { | @@ -3518,9 +3580,9 @@ export interface HeadErrorResponse { | ||
3518 | export type HeadErrorResponseSuccess = HeadErrorResponse[200]; | 3580 | export type HeadErrorResponseSuccess = HeadErrorResponse[200]; |
3519 | /** | 3581 | /** |
3520 | * @description | 3582 | * @description |
3521 | - * error | 3583 | + * errorHtml |
3522 | * @tags basic-error-controller | 3584 | * @tags basic-error-controller |
3523 | - * @produces * | 3585 | + * @produces text/html |
3524 | * @consumes application/json | 3586 | * @consumes application/json |
3525 | */ | 3587 | */ |
3526 | export const headError = /* #__PURE__ */ (() => { | 3588 | export const headError = /* #__PURE__ */ (() => { |
@@ -3545,9 +3607,7 @@ export interface PatchErrorResponse { | @@ -3545,9 +3607,7 @@ export interface PatchErrorResponse { | ||
3545 | * @description | 3607 | * @description |
3546 | * OK | 3608 | * OK |
3547 | */ | 3609 | */ |
3548 | - 200: { | ||
3549 | - [propertyName: string]: any; | ||
3550 | - }; | 3610 | + 200: ModelAndView; |
3551 | /** | 3611 | /** |
3552 | * @description | 3612 | * @description |
3553 | * No Content | 3613 | * No Content |
@@ -3568,9 +3628,9 @@ export interface PatchErrorResponse { | @@ -3568,9 +3628,9 @@ export interface PatchErrorResponse { | ||
3568 | export type PatchErrorResponseSuccess = PatchErrorResponse[200]; | 3628 | export type PatchErrorResponseSuccess = PatchErrorResponse[200]; |
3569 | /** | 3629 | /** |
3570 | * @description | 3630 | * @description |
3571 | - * error | 3631 | + * errorHtml |
3572 | * @tags basic-error-controller | 3632 | * @tags basic-error-controller |
3573 | - * @produces * | 3633 | + * @produces text/html |
3574 | * @consumes application/json | 3634 | * @consumes application/json |
3575 | */ | 3635 | */ |
3576 | export const patchError = /* #__PURE__ */ (() => { | 3636 | export const patchError = /* #__PURE__ */ (() => { |
@@ -13049,6 +13109,168 @@ export const postServiceConstClientLevels = /* #__PURE__ */ (() => { | @@ -13049,6 +13109,168 @@ export const postServiceConstClientLevels = /* #__PURE__ */ (() => { | ||
13049 | return request; | 13109 | return request; |
13050 | })(); | 13110 | })(); |
13051 | 13111 | ||
13112 | +/** @description response type for postServiceConstClientRequirements */ | ||
13113 | +export interface PostServiceConstClientRequirementsResponse { | ||
13114 | + /** | ||
13115 | + * @description | ||
13116 | + * OK | ||
13117 | + */ | ||
13118 | + 200: ServerResult; | ||
13119 | + /** | ||
13120 | + * @description | ||
13121 | + * Created | ||
13122 | + */ | ||
13123 | + 201: any; | ||
13124 | + /** | ||
13125 | + * @description | ||
13126 | + * Unauthorized | ||
13127 | + */ | ||
13128 | + 401: any; | ||
13129 | + /** | ||
13130 | + * @description | ||
13131 | + * Forbidden | ||
13132 | + */ | ||
13133 | + 403: any; | ||
13134 | + /** | ||
13135 | + * @description | ||
13136 | + * Not Found | ||
13137 | + */ | ||
13138 | + 404: any; | ||
13139 | +} | ||
13140 | + | ||
13141 | +export type PostServiceConstClientRequirementsResponseSuccess = | ||
13142 | + PostServiceConstClientRequirementsResponse[200]; | ||
13143 | +/** | ||
13144 | + * @description | ||
13145 | + * 客户需求 | ||
13146 | + * @tags front-const-controller | ||
13147 | + * @produces * | ||
13148 | + * @consumes application/json | ||
13149 | + */ | ||
13150 | +export const postServiceConstClientRequirements = /* #__PURE__ */ (() => { | ||
13151 | + const method = 'post'; | ||
13152 | + const url = '/service/const/clientRequirements'; | ||
13153 | + function request(): Promise<PostServiceConstClientRequirementsResponseSuccess> { | ||
13154 | + return requester(request.url, { | ||
13155 | + method: request.method, | ||
13156 | + }) as unknown as Promise<PostServiceConstClientRequirementsResponseSuccess>; | ||
13157 | + } | ||
13158 | + | ||
13159 | + /** http method */ | ||
13160 | + request.method = method; | ||
13161 | + /** request url */ | ||
13162 | + request.url = url; | ||
13163 | + return request; | ||
13164 | +})(); | ||
13165 | + | ||
13166 | +/** @description response type for postServiceConstClientSource */ | ||
13167 | +export interface PostServiceConstClientSourceResponse { | ||
13168 | + /** | ||
13169 | + * @description | ||
13170 | + * OK | ||
13171 | + */ | ||
13172 | + 200: ServerResult; | ||
13173 | + /** | ||
13174 | + * @description | ||
13175 | + * Created | ||
13176 | + */ | ||
13177 | + 201: any; | ||
13178 | + /** | ||
13179 | + * @description | ||
13180 | + * Unauthorized | ||
13181 | + */ | ||
13182 | + 401: any; | ||
13183 | + /** | ||
13184 | + * @description | ||
13185 | + * Forbidden | ||
13186 | + */ | ||
13187 | + 403: any; | ||
13188 | + /** | ||
13189 | + * @description | ||
13190 | + * Not Found | ||
13191 | + */ | ||
13192 | + 404: any; | ||
13193 | +} | ||
13194 | + | ||
13195 | +export type PostServiceConstClientSourceResponseSuccess = | ||
13196 | + PostServiceConstClientSourceResponse[200]; | ||
13197 | +/** | ||
13198 | + * @description | ||
13199 | + * 客户来源 | ||
13200 | + * @tags front-const-controller | ||
13201 | + * @produces * | ||
13202 | + * @consumes application/json | ||
13203 | + */ | ||
13204 | +export const postServiceConstClientSource = /* #__PURE__ */ (() => { | ||
13205 | + const method = 'post'; | ||
13206 | + const url = '/service/const/clientSource'; | ||
13207 | + function request(): Promise<PostServiceConstClientSourceResponseSuccess> { | ||
13208 | + return requester(request.url, { | ||
13209 | + method: request.method, | ||
13210 | + }) as unknown as Promise<PostServiceConstClientSourceResponseSuccess>; | ||
13211 | + } | ||
13212 | + | ||
13213 | + /** http method */ | ||
13214 | + request.method = method; | ||
13215 | + /** request url */ | ||
13216 | + request.url = url; | ||
13217 | + return request; | ||
13218 | +})(); | ||
13219 | + | ||
13220 | +/** @description response type for postServiceConstClientWay */ | ||
13221 | +export interface PostServiceConstClientWayResponse { | ||
13222 | + /** | ||
13223 | + * @description | ||
13224 | + * OK | ||
13225 | + */ | ||
13226 | + 200: ServerResult; | ||
13227 | + /** | ||
13228 | + * @description | ||
13229 | + * Created | ||
13230 | + */ | ||
13231 | + 201: any; | ||
13232 | + /** | ||
13233 | + * @description | ||
13234 | + * Unauthorized | ||
13235 | + */ | ||
13236 | + 401: any; | ||
13237 | + /** | ||
13238 | + * @description | ||
13239 | + * Forbidden | ||
13240 | + */ | ||
13241 | + 403: any; | ||
13242 | + /** | ||
13243 | + * @description | ||
13244 | + * Not Found | ||
13245 | + */ | ||
13246 | + 404: any; | ||
13247 | +} | ||
13248 | + | ||
13249 | +export type PostServiceConstClientWayResponseSuccess = | ||
13250 | + PostServiceConstClientWayResponse[200]; | ||
13251 | +/** | ||
13252 | + * @description | ||
13253 | + * 类型 | ||
13254 | + * @tags front-const-controller | ||
13255 | + * @produces * | ||
13256 | + * @consumes application/json | ||
13257 | + */ | ||
13258 | +export const postServiceConstClientWay = /* #__PURE__ */ (() => { | ||
13259 | + const method = 'post'; | ||
13260 | + const url = '/service/const/clientWay'; | ||
13261 | + function request(): Promise<PostServiceConstClientWayResponseSuccess> { | ||
13262 | + return requester(request.url, { | ||
13263 | + method: request.method, | ||
13264 | + }) as unknown as Promise<PostServiceConstClientWayResponseSuccess>; | ||
13265 | + } | ||
13266 | + | ||
13267 | + /** http method */ | ||
13268 | + request.method = method; | ||
13269 | + /** request url */ | ||
13270 | + request.url = url; | ||
13271 | + return request; | ||
13272 | +})(); | ||
13273 | + | ||
13052 | /** @description response type for postServiceConstGetPayeeEnum */ | 13274 | /** @description response type for postServiceConstGetPayeeEnum */ |
13053 | export interface PostServiceConstGetPayeeEnumResponse { | 13275 | export interface PostServiceConstGetPayeeEnumResponse { |
13054 | /** | 13276 | /** |