Commit 42506df2bc1673fd20301b8081729db26177a02b

Authored by boyang
2 parents 07dd077f a11effeb

Merge branch 'by' into warning

Showing 45 changed files with 7922 additions and 687 deletions
.umirc.ts
@@ -141,10 +141,21 @@ export default defineConfig({ @@ -141,10 +141,21 @@ export default defineConfig({
141 }, 141 },
142 { 142 {
143 name: '客户管理', 143 name: '客户管理',
144 - path: '/client',  
145 - component: './Client', 144 + path: '/Client',
146 icon: 'BookOutlined', 145 icon: 'BookOutlined',
147 access: 'canReadAdminAndSales', 146 access: 'canReadAdminAndSales',
  147 + routes: [
  148 + {
  149 + name: '客户列表',
  150 + path: 'clint',
  151 + component: './Client/Client',
  152 + },
  153 + {
  154 + name: '跟进记录',
  155 + path: 'FollowRecord',
  156 + component: './Client/FollowRecord',
  157 + },
  158 + ],
148 }, 159 },
149 { 160 {
150 name: '打印', 161 name: '打印',
order-erp.service-1.0-SNAPSHOT.jar 0 → 100644
No preview for this file type
src/pages/Client/Components/ClientDrawer.tsx renamed to src/pages/Client/Client/Components/ClientDrawer.tsx
@@ -6,23 +6,34 @@ import { @@ -6,23 +6,34 @@ import {
6 postDistrictSelectByNameAndLevel, 6 postDistrictSelectByNameAndLevel,
7 postDistrictSelOrderProvince, 7 postDistrictSelOrderProvince,
8 postServiceConstClientLevels, 8 postServiceConstClientLevels,
  9 + postServiceConstClientSource,
9 postServiceConstTradeStatus, 10 postServiceConstTradeStatus,
10 } from '@/services'; 11 } from '@/services';
  12 +
11 import { enumToSelect } from '@/utils'; 13 import { enumToSelect } from '@/utils';
12 import { 14 import {
13 DrawerForm, 15 DrawerForm,
14 - ProFormDateTimePicker, 16 + ProFormDatePicker,
15 ProFormSelect, 17 ProFormSelect,
16 ProFormText, 18 ProFormText,
17 } from '@ant-design/pro-components'; 19 } from '@ant-design/pro-components';
18 import { Button, Form, message } from 'antd'; 20 import { Button, Form, message } from 'antd';
  21 +// import { options } from 'node_modules/axios/index.cjs';
19 import { useState } from 'react'; 22 import { useState } from 'react';
20 23
21 export default ({ optType, record, onFinish }) => { 24 export default ({ optType, record, onFinish }) => {
22 const [form] = Form.useForm(); 25 const [form] = Form.useForm();
  26 + const requirementsEnum = {
  27 + EXPERIMENTAL_EQUIPMENT: '实验设备',
  28 + EXPERIMENTAL_MATERIALS: '实验材料',
  29 + OTHER: '其他',
  30 + PILOT_TEST_VALIDATION_SERVICES: '中式验证服务',
  31 + };
23 //省市区 32 //省市区
24 const [province, setProvince] = useState(''); 33 const [province, setProvince] = useState('');
25 const [city, setCity] = useState(''); 34 const [city, setCity] = useState('');
  35 + const [showReferrers, setShowReferrers] = useState(false); // 控制显示的状态,初始为false
  36 + const [showQuoteDatetime, setShowQuoteDatetime] = useState(false); // 控制显示的状态,初始为false
26 const optTypeEnum = { 37 const optTypeEnum = {
27 add: { 38 add: {
28 text: '新增', 39 text: '新增',
@@ -42,7 +53,7 @@ export default ({ optType, record, onFinish }) => { @@ -42,7 +53,7 @@ export default ({ optType, record, onFinish }) => {
42 }, 53 },
43 edit: { 54 edit: {
44 text: '编辑', 55 text: '编辑',
45 - button: <a type="primary">编辑</a>, 56 + button: <a type="link">编辑</a>,
46 readonly: false, 57 readonly: false,
47 onFinish: async (values) => { 58 onFinish: async (values) => {
48 const res = await postAdminClientModifyClientInfo({ 59 const res = await postAdminClientModifyClientInfo({
@@ -58,11 +69,43 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -58,11 +69,43 @@ export default ({ optType, record, onFinish }) =&gt; {
58 }, 69 },
59 detail: { 70 detail: {
60 text: '详情', 71 text: '详情',
61 - button: <a type="primary">详情</a>, 72 + // button: <a type="primary">详情</a>,
62 readonly: true, 73 readonly: true,
63 }, 74 },
64 }; 75 };
65 76
  77 + const handleSourceChange = (value) => {
  78 + if (value === 'REFERRAL_BY_ACQUAINTANCE') {
  79 + setShowReferrers(true);
  80 + } else {
  81 + setShowReferrers(false);
  82 + }
  83 + // 在这里可以添加其他逻辑,比如根据选择更新其他表单项的值
  84 + };
  85 + const handleSchemeChange = (value) => {
  86 + console.log(value);
  87 + if (value === true) {
  88 + setShowQuoteDatetime(true);
  89 + } else {
  90 + setShowQuoteDatetime(false);
  91 + }
  92 + // 在这里可以添加其他逻辑,比如根据选择更新其他表单项的值
  93 + };
  94 +
  95 + // MODIFIED: 增加处理非 JSON 格式字符串的逻辑
  96 + const parsedRecord = record
  97 + ? {
  98 + ...record,
  99 + requirements: (() => {
  100 + try {
  101 + return JSON.parse(record.requirements); // 尝试解析 JSON
  102 + } catch (error) {
  103 + return record.requirements ? record.requirements.split(',') : []; // 如果不是 JSON,则按逗号分隔字符串
  104 + }
  105 + })(),
  106 + }
  107 + : {}; // 如果 record 为空,返回一个空对象
  108 +
66 return ( 109 return (
67 <DrawerForm 110 <DrawerForm
68 title={optTypeEnum[optType].text} 111 title={optTypeEnum[optType].text}
@@ -73,7 +116,7 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -73,7 +116,7 @@ export default ({ optType, record, onFinish }) =&gt; {
73 maxWidth: window.innerWidth * 0.8, 116 maxWidth: window.innerWidth * 0.8,
74 minWidth: 300, 117 minWidth: 300,
75 }} 118 }}
76 - initialValues={record} 119 + initialValues={parsedRecord}
77 form={form} 120 form={form}
78 trigger={optTypeEnum[optType].button} 121 trigger={optTypeEnum[optType].button}
79 autoFocusFirstInput 122 autoFocusFirstInput
@@ -98,7 +141,7 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -98,7 +141,7 @@ export default ({ optType, record, onFinish }) =&gt; {
98 }, 141 },
99 ]} 142 ]}
100 /> 143 />
101 - <ProFormText 144 + {/* <ProFormText
102 name="companyName" 145 name="companyName"
103 label="单位名称" 146 label="单位名称"
104 placeholder="请输入单位名称" 147 placeholder="请输入单位名称"
@@ -108,7 +151,7 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -108,7 +151,7 @@ export default ({ optType, record, onFinish }) =&gt; {
108 message: '请输入单位名称', 151 message: '请输入单位名称',
109 }, 152 },
110 ]} 153 ]}
111 - /> 154 + /> */}
112 <div 155 <div
113 style={{ 156 style={{
114 display: 'flex', 157 display: 'flex',
@@ -260,7 +303,7 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -260,7 +303,7 @@ export default ({ optType, record, onFinish }) =&gt; {
260 /> 303 />
261 </div> 304 </div>
262 <ProFormText 305 <ProFormText
263 - name="companyAddress" 306 + name="detailAddress"
264 label="详细地址" 307 label="详细地址"
265 placeholder="请输入单位地址" 308 placeholder="请输入单位地址"
266 rules={[ 309 rules={[
@@ -271,6 +314,17 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -271,6 +314,17 @@ export default ({ optType, record, onFinish }) =&gt; {
271 ]} 314 ]}
272 /> 315 />
273 <ProFormText 316 <ProFormText
  317 + name="contacts"
  318 + label="联系人"
  319 + placeholder="请输入联系人"
  320 + rules={[
  321 + {
  322 + required: true,
  323 + message: '请输入联系人',
  324 + },
  325 + ]}
  326 + />
  327 + <ProFormText
274 name="phoneNumber" 328 name="phoneNumber"
275 label="联系电话" 329 label="联系电话"
276 placeholder="请输入联系电话" 330 placeholder="请输入联系电话"
@@ -281,23 +335,52 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -281,23 +335,52 @@ export default ({ optType, record, onFinish }) =&gt; {
281 }, 335 },
282 ]} 336 ]}
283 /> 337 />
284 - <ProFormText 338 + <ProFormSelect
285 name="source" 339 name="source"
286 label="客户来源" 340 label="客户来源"
287 - placeholder="请输入客户来源" 341 + placeholder="请选择客户来源"
  342 + request={async () => {
  343 + const res = await postServiceConstClientSource();
  344 + return enumToSelect(res.data);
  345 + }}
  346 + rules={[
  347 + {
  348 + required: true,
  349 + message: '请选择客户来源',
  350 + },
  351 + ]}
  352 + fieldProps={{
  353 + onChange: handleSourceChange, // 添加onChange事件处理函数
  354 + }}
288 /> 355 />
289 - <ProFormText 356 + {showReferrers && (
  357 + <ProFormText
  358 + name="referrers"
  359 + label="推荐人"
  360 + placeholder="请输入推荐人"
  361 + />
  362 + )}
  363 + <ProFormSelect
290 name="requirements" 364 name="requirements"
291 label="客户需求" 365 label="客户需求"
292 placeholder="请输入客户需求" 366 placeholder="请输入客户需求"
  367 + valueEnum={requirementsEnum}
  368 + fieldProps={{
  369 + mode: 'multiple',
  370 + }}
293 rules={[ 371 rules={[
294 { 372 {
295 required: true, 373 required: true,
296 message: '请输入客户需求', 374 message: '请输入客户需求',
  375 + type: 'array',
297 }, 376 },
298 ]} 377 ]}
  378 + // request={async () => {
  379 + // const res = await postServiceConstClientRequirements();
  380 + // console.log(res.data, '5656require');
  381 + // return enumToSelect(res.data);
  382 + // }}
299 /> 383 />
300 - <ProFormText name="referrers" label="推荐人" placeholder="请输入推荐人" />  
301 <ProFormSelect 384 <ProFormSelect
302 name="hasScheme" 385 name="hasScheme"
303 label="是否已报方案" 386 label="是否已报方案"
@@ -318,12 +401,17 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -318,12 +401,17 @@ export default ({ optType, record, onFinish }) =&gt; {
318 message: '请选择是否已报方案', 401 message: '请选择是否已报方案',
319 }, 402 },
320 ]} 403 ]}
  404 + fieldProps={{
  405 + onChange: handleSchemeChange, // 添加onChange事件处理函数
  406 + }}
321 /> 407 />
322 - <ProFormDateTimePicker  
323 - name="quoteDatetime"  
324 - label="报价时间"  
325 - placeholder="请输入报价时间"  
326 - /> 408 + {showQuoteDatetime && (
  409 + <ProFormDatePicker
  410 + name="quoteDatetime"
  411 + label="报价时间"
  412 + placeholder="请输入报价时间"
  413 + />
  414 + )}
327 <ProFormSelect 415 <ProFormSelect
328 name="level" 416 name="level"
329 label="客户等级" 417 label="客户等级"
@@ -336,7 +424,17 @@ export default ({ optType, record, onFinish }) =&gt; { @@ -336,7 +424,17 @@ export default ({ optType, record, onFinish }) =&gt; {
336 ]} 424 ]}
337 request={async () => { 425 request={async () => {
338 const res = await postServiceConstClientLevels(); 426 const res = await postServiceConstClientLevels();
339 - return enumToSelect(res.data); 427 + function enumToSelectLevel(data: any) {
  428 + const order = [
  429 + 'PRIMARY_CLIENT',
  430 + 'SECONDARY_CLIENT',
  431 + 'TERTIARY_CLIENT',
  432 + ];
  433 + return order.map((key) => {
  434 + return { label: data[key], value: key };
  435 + });
  436 + }
  437 + return enumToSelectLevel(res.data);
340 }} 438 }}
341 /> 439 />
342 <ProFormSelect 440 <ProFormSelect
src/pages/Client/Client/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 ({ reloadTable }) => {
  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 + reloadTable();
  63 + } else {
  64 + message.error(dataJson?.message);
  65 + }
  66 + });
  67 + } else {
  68 + message.error('上传失败,已下载错误信息表格');
  69 + // 创建一个新的 Blob 对象,它包含了服务器响应的数据(即你的 Excel 文件)
  70 + const blob = new Blob([response.data]); // Excel 的 MIME 类型
  71 + const downloadUrl = window.URL.createObjectURL(blob);
  72 + const a = document.createElement('a');
  73 + a.href = downloadUrl;
  74 + a.download = '银行流水导入模板.xlsx'; // 你可以为文件命名
  75 + document.body.appendChild(a);
  76 + a.click(); // 模拟点击操作来下载文件
  77 + URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存
  78 + document.body.removeChild(a);
  79 + }
  80 + })
  81 + .catch((error) => {
  82 + // 处理错误
  83 + message.error('系统出现异常了,请联系管理员', error);
  84 + })
  85 + .finally(() => {});
  86 + return true;
  87 + }}
  88 + >
  89 + <ProFormUploadDragger max={1} label="上传" name="file" />
  90 + <Button type="link" onClick={downloadImportTemplate}>
  91 + 下载导入模板
  92 + </Button>
  93 + {contextHolder}
  94 + </ModalForm>
  95 + );
  96 +};
src/pages/Client/Client/Components/ClientInformationModal.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.id === values.name,
  29 + );
  30 + let matchedId;
  31 + if (matchingItem) {
  32 + matchedId = matchingItem.id; // 匹配成功,取出 id
  33 + values.name = matchingItem.name;
  34 + } else {
  35 + matchedId = null; // 如果没有匹配项,可以设置为 null 或其他值
  36 + }
  37 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  38 + data: {
  39 + ...values,
  40 + clientId: matchedId,
  41 + },
  42 + });
  43 + if (res.result === RESPONSE_CODE.SUCCESS) {
  44 + message.success('新增成功');
  45 + reloadTable();
  46 + return true;
  47 + }
  48 + // 不返回不会关闭弹框
  49 + };
  50 + const editOnfinish = async (values) => {
  51 + // setEditClientId(data.clientId);
  52 + values.clientId = data.clientId;
  53 + console.log(values, '5656editClientId');
  54 +
  55 + // const resSearchId = await postAdminClientQueryClientPage({
  56 + // data: {
  57 + // groupFilter: 'all',
  58 + // },
  59 + // });
  60 + // const matchingItem = resSearchId.data.data.find(
  61 + // (item) => item.id === values.name,
  62 + // );
  63 +
  64 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  65 + data: {
  66 + ...values,
  67 + },
  68 + });
  69 + if (res.result === RESPONSE_CODE.SUCCESS) {
  70 + message.success('新增成功');
  71 + reloadTable();
  72 + return true;
  73 + }
  74 + // 不返回不会关闭弹框
  75 + };
  76 + const optType = {
  77 + add: {
  78 + readOnly: false,
  79 + title: '新增跟进记录',
  80 + button: (
  81 + <Button size={'middle'} type="primary">
  82 + 新增
  83 + </Button>
  84 + ),
  85 + onFinish: onfinish,
  86 + },
  87 + modify: {
  88 + readOnly: false,
  89 + title: '修改跟进记录',
  90 + button: (
  91 + <Button size={'middle'} type="primary">
  92 + 编辑
  93 + </Button>
  94 + ),
  95 + onFinish: editOnfinish,
  96 + },
  97 + detail: {
  98 + readOnly: true,
  99 + title: '查看跟进记录',
  100 + button: (
  101 + <Button size={'middle'} type="primary" color="red">
  102 + 查看
  103 + </Button>
  104 + ),
  105 + onFinish: () => {},
  106 + },
  107 + };
  108 + return (
  109 + <ModalForm
  110 + title={optType[type].title}
  111 + resize={{
  112 + onResize() {
  113 + console.log('resize!');
  114 + },
  115 + maxWidth: window.innerWidth * 0.8,
  116 + minWidth: 400,
  117 + }}
  118 + form={form}
  119 + trigger={optType[type].button}
  120 + autoFocusFirstInput
  121 + drawerProps={{
  122 + destroyOnClose: true,
  123 + }}
  124 + submitTimeout={2000}
  125 + onFinish={optType[type].onFinish}
  126 + >
  127 + <ProFormSelect
  128 + name="name"
  129 + readonly={optType[type].readOnly}
  130 + fieldProps={{
  131 + labelInValue: false,
  132 + disabled: type === 'modify',
  133 + }}
  134 + initialValue={data ? data?.clientName + '' : null}
  135 + label="客户"
  136 + width="sm"
  137 + request={async () => {
  138 + const res = await postAdminClientQueryClientPage({
  139 + data: {
  140 + groupFilter: 'all',
  141 + },
  142 + });
  143 + console.log(data, '5656data?.nameedit');
  144 + // const namesArray = res.data.data.map((item) => item.name);
  145 + // const formattedObject = res.data.data.reduce((acc, name) => {
  146 + // acc[name] = name; // 将名称作为键和值
  147 + // return acc;
  148 + // }, {});
  149 + // console.log(namesArray, '5656namesArray');
  150 + // const formattedObject = res.data.data.reduce((acc, item) => {
  151 + // acc[item.name] = item.name; // 使用 name 作为键,id 作为值
  152 + // return acc;
  153 + // }, {});
  154 + // return enumToSelect(formattedObject);
  155 + const options = res.data.data.reduce((acc, item) => {
  156 + acc.push({ label: item.name, value: item.id }); // 使用 name 作为 label,id 作为 value
  157 + return acc;
  158 + }, []);
  159 + return options;
  160 + }}
  161 + rules={[
  162 + {
  163 + required: true,
  164 + message: '请选择客户',
  165 + },
  166 + ]}
  167 + ></ProFormSelect>
  168 + <ProFormDateTimePicker
  169 + name="datetime"
  170 + label="日期"
  171 + initialValue={data ? data?.datetime + '' : null}
  172 + placeholder="请选择跟进时间"
  173 + width="sm"
  174 + rules={[
  175 + {
  176 + required: true,
  177 + message: '请选择日期',
  178 + },
  179 + ]}
  180 + />
  181 + <ProFormSelect
  182 + name="way"
  183 + width="sm"
  184 + readonly={optType[type].readOnly}
  185 + fieldProps={{
  186 + labelInValue: false,
  187 + }}
  188 + initialValue={data?.way ? data?.way + '' : null}
  189 + label="类型"
  190 + request={async () => {
  191 + const res = await postServiceConstClientWay();
  192 + return enumToSelect(res.data);
  193 + }}
  194 + rules={[
  195 + {
  196 + required: true,
  197 + message: '请选择跟进类型',
  198 + },
  199 + ]}
  200 + ></ProFormSelect>
  201 + <ProFormTextArea
  202 + name="content"
  203 + label="详情"
  204 + placeholder="请输入详情"
  205 + initialValue={data?.content}
  206 + readonly={optType[type].readOnly}
  207 + rules={[
  208 + {
  209 + required: true,
  210 + message: '请输入详情',
  211 + },
  212 + ]}
  213 + ></ProFormTextArea>
  214 + <ProFormUploadDragger
  215 + label="附件"
  216 + name="attachment"
  217 + action="upload.do"
  218 + hidden={optType[type].readOnly}
  219 + onChange={(info) => {
  220 + const uploadFile = async ({ fileList: newFileList }) => {
  221 + if (newFileList.length > 0) {
  222 + const formData = new FormData();
  223 + formData.append('file', newFileList[0].originFileObj as RcFile);
  224 + const res = await postOrderErpOrderStagesUpload({
  225 + data: formData,
  226 + headers: {
  227 + 'Content-Type':
  228 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  229 + },
  230 + });
  231 + const url = res.data;
  232 + console.log('attachments' + JSON.stringify(url));
  233 + form.setFieldValue('attachments', url);
  234 + } else {
  235 + form.setFieldValue('attachments', null);
  236 + }
  237 + };
  238 + uploadFile(info);
  239 + }}
  240 + max={1}
  241 + />
  242 + <a hidden={!optType[type].readOnly} href={data?.attachments} download>
  243 + 下载附件
  244 + </a>
  245 + <ProFormText
  246 + initialValue={data?.attachments}
  247 + name="attachments"
  248 + hidden
  249 + ></ProFormText>
  250 + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  251 + </ModalForm>
  252 + );
  253 +};
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 + id: '',
  28 + clientId: data.id,
  29 + },
  30 + });
  31 + if (res.result === RESPONSE_CODE.SUCCESS) {
  32 + message.success('新增成功');
  33 + reloadTable();
  34 + return true;
  35 + }
  36 + // 不返回不会关闭弹框
  37 + };
  38 + const optType = {
  39 + add: {
  40 + readOnly: false,
  41 + title: '新增跟进记录',
  42 + button: (
  43 + <Button size={'small'} type="link">
  44 + 新增跟进
  45 + </Button>
  46 + ),
  47 + onFinish: onfinish,
  48 + },
  49 + add2: {
  50 + readOnly: false,
  51 + title: '新增跟进记录',
  52 + button: (
  53 + <Button size={'middle'} type="primary">
  54 + 新增跟进
  55 + </Button>
  56 + ),
  57 + onFinish: onfinish,
  58 + },
  59 + modify: {
  60 + readOnly: false,
  61 + title: '修改跟进记录',
  62 + button: (
  63 + <Button size={'small'} type="link">
  64 + 编辑
  65 + </Button>
  66 + ),
  67 + onFinish: onfinish,
  68 + },
  69 + detail: {
  70 + readOnly: true,
  71 + title: '查看跟进记录',
  72 + button: (
  73 + <Button size={'small'} type="link">
  74 + 查看
  75 + </Button>
  76 + ),
  77 + onFinish: () => {},
  78 + },
  79 + };
  80 + return (
  81 + <ModalForm
  82 + title={optType[type].title}
  83 + resize={{
  84 + onResize() {
  85 + console.log('resize!');
  86 + },
  87 + maxWidth: window.innerWidth * 0.8,
  88 + minWidth: 400,
  89 + }}
  90 + form={form}
  91 + trigger={optType[type].button}
  92 + autoFocusFirstInput
  93 + drawerProps={{
  94 + destroyOnClose: true,
  95 + }}
  96 + submitTimeout={2000}
  97 + onFinish={optType[type].onFinish}
  98 + >
  99 + <ProFormSelect
  100 + name="sendStoreCode"
  101 + readonly={optType[type].readOnly}
  102 + fieldProps={{
  103 + labelInValue: false,
  104 + }}
  105 + initialValue={data ? data?.name + '' : null}
  106 + label="客户"
  107 + width="sm"
  108 + request={async () => {
  109 + const res = await postAdminClientQueryClientPage({
  110 + data: {
  111 + groupFilter: 'all',
  112 + },
  113 + });
  114 + console.log(data?.datetime, '5656data?.datetime');
  115 + const namesArray = res.data.data.map((item) => item.name);
  116 + return enumToSelect(namesArray);
  117 + }}
  118 + rules={[
  119 + {
  120 + required: true,
  121 + message: '请选择客户',
  122 + },
  123 + ]}
  124 + disabled
  125 + ></ProFormSelect>
  126 + <ProFormDateTimePicker
  127 + name="datetime"
  128 + label="日期"
  129 + initialValue={data.datetime ? data?.datetime + '' : null}
  130 + placeholder="请选择跟进时间"
  131 + width="sm"
  132 + rules={[
  133 + {
  134 + required: true,
  135 + message: '请选择日期',
  136 + },
  137 + ]}
  138 + />
  139 + <ProFormSelect
  140 + name="way"
  141 + width="sm"
  142 + readonly={optType[type].readOnly}
  143 + fieldProps={{
  144 + labelInValue: false,
  145 + }}
  146 + initialValue={data?.way ? data?.way + '' : null}
  147 + label="类型"
  148 + request={async () => {
  149 + const res = await postServiceConstClientWay();
  150 + return enumToSelect(res.data);
  151 + }}
  152 + rules={[
  153 + {
  154 + required: true,
  155 + message: '请选择跟进类型',
  156 + },
  157 + ]}
  158 + ></ProFormSelect>
  159 + <ProFormTextArea
  160 + name="content"
  161 + label="详情"
  162 + placeholder="请输入详情"
  163 + initialValue={data?.content}
  164 + readonly={optType[type].readOnly}
  165 + rules={[
  166 + {
  167 + required: true,
  168 + message: '请输入详情',
  169 + },
  170 + ]}
  171 + ></ProFormTextArea>
  172 + <ProFormUploadDragger
  173 + label="附件"
  174 + name="attachment"
  175 + action="upload.do"
  176 + hidden={optType[type].readOnly}
  177 + onChange={(info) => {
  178 + const uploadFile = async ({ fileList: newFileList }) => {
  179 + if (newFileList.length > 0) {
  180 + const formData = new FormData();
  181 + formData.append('file', newFileList[0].originFileObj as RcFile);
  182 + const res = await postOrderErpOrderStagesUpload({
  183 + data: formData,
  184 + headers: {
  185 + 'Content-Type':
  186 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  187 + },
  188 + });
  189 + const url = res.data;
  190 + console.log('attachments' + JSON.stringify(url));
  191 + form.setFieldValue('attachments', url);
  192 + } else {
  193 + form.setFieldValue('attachments', null);
  194 + }
  195 + };
  196 + uploadFile(info);
  197 + }}
  198 + max={1}
  199 + />
  200 + <a hidden={!optType[type].readOnly} href={data?.attachments} download>
  201 + 下载附件
  202 + </a>
  203 + <ProFormText
  204 + initialValue={data?.attachments}
  205 + name="attachments"
  206 + hidden
  207 + ></ProFormText>
  208 + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  209 + </ModalForm>
  210 + );
  211 +};
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 +import ClientModal from './ClientModal';
  18 +import InformationHistoryModal from './InformationHistoryModal';
  19 +export default ({ record }) => {
  20 + const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
  21 + const [dataSource, setDataSource] = useState();
  22 + const ref = useRef<ProFormInstance>();
  23 + const actionRef = useRef<ActionType>();
  24 + const [refreshKey, setRefreshKey] = useState(0); // 用于强制刷新的键
  25 +
  26 + const reloadInformationHistoryModal = () => {
  27 + actionRef.current.reload(); // 重新加载数据
  28 + console.log('5656flush');
  29 +
  30 + // 更新 refreshKey,强制刷新 CommunicationHistoryModal
  31 + setRefreshKey((prevKey) => prevKey + 1);
  32 + };
  33 + const columns = [
  34 + {
  35 + title: '跟进时间',
  36 + dataIndex: 'datetime',
  37 + width: 50,
  38 + valueType: 'dateTime',
  39 + rules: [{ required: true, message: '请选择时间' }],
  40 + },
  41 + {
  42 + title: '跟进人',
  43 + width: 50,
  44 + rules: [{ required: true, message: '请输入跟进人' }],
  45 + dataIndex: 'updateByName',
  46 + },
  47 + {
  48 + title: '跟进方式',
  49 + width: 50,
  50 + dataIndex: 'way',
  51 + rules: [{ required: true, message: '请选择方式' }],
  52 + render: (text, record) => record.wayText, // 显示 wayText
  53 + request: async () => {
  54 + const res = await postServiceConstClientWay();
  55 + return enumToSelect(res.data);
  56 + },
  57 + },
  58 + {
  59 + title: '内容',
  60 + width: 100,
  61 + valueType: 'textarea',
  62 + rules: [{ required: true, message: '请输入内容' }],
  63 + dataIndex: 'content',
  64 + },
  65 + {
  66 + title: '操作',
  67 + valueType: 'option',
  68 + width: 50,
  69 + render: (text, record, _, action) => [
  70 + // <a
  71 + // key="editable"
  72 + // onClick={() => {
  73 + // action?.startEditable?.(record.tid);
  74 + // }}
  75 + // >
  76 + // 编辑
  77 + // </a>,
  78 + <InformationHistoryModal
  79 + // key={'communicationHistory'}
  80 + key={`communicationHistory-${refreshKey}`} // 使用 refreshKey 来强制更新组件
  81 + data={record}
  82 + // reloadTable={() => {
  83 + // actionRef.current.reload();
  84 + // console.log('5656flush');
  85 + // }}
  86 + reloadTable={reloadInformationHistoryModal}
  87 + />,
  88 + <Popconfirm
  89 + key={'delete'}
  90 + title="删除记录"
  91 + description="确认删除记录?"
  92 + onConfirm={async () => {
  93 + setDataSource(dataSource.filter((item) => item.tid !== record.tid));
  94 + const res = await postAdminClientRemoveClientComunicationInfo({
  95 + query: {
  96 + id: record.id,
  97 + },
  98 + });
  99 + if (res.result === RESPONSE_CODE.SUCCESS) {
  100 + message.success(res.message);
  101 + action?.reload();
  102 + } else {
  103 + message.error('删除失败');
  104 + }
  105 + }}
  106 + okText="是"
  107 + cancelText="否"
  108 + >
  109 + <a type={'danger'}>删除</a>
  110 + </Popconfirm>,
  111 + ],
  112 + },
  113 + ];
  114 + const [name, setName] = useState(''); // 客户名称
  115 + const [contacts, setContacts] = useState(''); // 联系人
  116 + const [sourceText, setSourceText] = useState(''); // 来源文本
  117 + const [phoneNumber, setPhoneNumber] = useState(''); // 联系电话
  118 + const [hasSchemeText, setHasSchemeText] = useState(''); // 报方案状态文本
  119 + const [quoteDatetime, setQuoteDatetime] = useState(null); // 报价时间
  120 + const [referrers, setReferrers] = useState(''); // 推荐人
  121 + const [requirementsText, setRequirementsText] = useState(''); // 需求文本
  122 + const [tradeStatusText, setTradeStatusText] = useState(''); // 跟进状态文本
  123 + const [levelText, setLevelText] = useState(''); // 客户等级文本
  124 + const [createTime, setCreateTime] = useState(null); // 最新沟通时间
  125 + const [address, setAddress] = useState(''); // 客户地址
  126 + const [notes, setNotes] = useState(''); // 备注信息
  127 + const [createByName, setCreateByName] = useState(''); // 创建人
  128 + const [latestObject, setLatestObject] = useState(); // 最新跟进时间
  129 + const [recordSave, setRecordSave] = useState(); //新增跟进
  130 + useEffect(() => {
  131 + const request = async () => {
  132 + const resShow = await postAdminClientQueryClientComunicationInfo({
  133 + data: {
  134 + clientId: record.id,
  135 + },
  136 + });
  137 + if (resShow?.data?.data !== null) {
  138 + const data = resShow?.data?.data;
  139 + // const latest = data.reduce((latest: any, current: any) => {
  140 + // return new Date(current.updateTime) > new Date(latest.updateTime) ? current : latest;
  141 + // });
  142 + // const data = [];
  143 + const latestObject2 =
  144 + data?.length > 0
  145 + ? data.reduce((latest, current) =>
  146 + new Date(current.datetime) > new Date(latest.datetime)
  147 + ? current
  148 + : latest,
  149 + )
  150 + : null; // 或返回其他默认值
  151 + setLatestObject(latestObject2?.datetime);
  152 + }
  153 + setRecordSave(record);
  154 + setName(record.name);
  155 + setContacts(record.contacts);
  156 + setSourceText(record.sourceText);
  157 + setPhoneNumber(record.phoneNumber);
  158 + setHasSchemeText(record.hasSchemeText);
  159 + setQuoteDatetime(record.quoteDatetime);
  160 + setReferrers(record.referrers);
  161 + setRequirementsText(record.requirementsText);
  162 + setTradeStatusText(record.tradeStatusText);
  163 + setLevelText(record.levelText);
  164 + setCreateTime(record.createTime);
  165 + setAddress(record.address);
  166 + setNotes(record.notes);
  167 + setCreateByName(record.createByName);
  168 + };
  169 + request();
  170 + }, []);
  171 + const items = [
  172 + {
  173 + key: '1',
  174 + label: '客户名称',
  175 + children: name, // 客户名称
  176 + },
  177 + {
  178 + key: '2',
  179 + label: '联系人',
  180 + children: contacts, // 联系人
  181 + },
  182 + {
  183 + key: '3',
  184 + label: '来源',
  185 + children: sourceText, // 来源文本
  186 + },
  187 + {
  188 + key: '4',
  189 + label: '联系电话',
  190 + children: phoneNumber, // 联系电话
  191 + },
  192 + {
  193 + key: '5',
  194 + label: '是否已报方案',
  195 + children: hasSchemeText, // 报方案状态文本
  196 + },
  197 + {
  198 + key: '6',
  199 + label: '报价时间',
  200 + children: quoteDatetime, // 报价时间
  201 + },
  202 + {
  203 + key: '7',
  204 + label: '推荐人',
  205 + children: referrers, // 推荐人
  206 + },
  207 + {
  208 + key: '8',
  209 + label: '需求',
  210 + children: requirementsText, // 需求文本
  211 + },
  212 + {
  213 + key: '9',
  214 + label: '跟进状态',
  215 + children: tradeStatusText, // 跟进状态文本
  216 + },
  217 + {
  218 + key: '10',
  219 + label: '客户等级',
  220 + children: levelText, // 客户等级文本
  221 + },
  222 + {
  223 + key: '11',
  224 + label: '创建时间',
  225 + children: createTime, // 最新沟通时间
  226 + },
  227 + {
  228 + key: '12',
  229 + label: '客户地址',
  230 + children: address, // 客户地址
  231 + },
  232 + {
  233 + key: '13',
  234 + label: '备注',
  235 + children: notes, // 备注信息
  236 + },
  237 + {
  238 + key: '14',
  239 + label: '创建人',
  240 + children: createByName, // 创建人
  241 + },
  242 + {
  243 + key: '15',
  244 + label: '最新跟进时间',
  245 + children: latestObject, // 最新跟进时间
  246 + },
  247 + ];
  248 + return (
  249 + <ModalForm
  250 + title="客户详情"
  251 + trigger={<a type="primary">查看</a>}
  252 + modalProps={{
  253 + destroyOnClose: true,
  254 + }}
  255 + onFinish={async () => {
  256 + return true;
  257 + }}
  258 + >
  259 + <Descriptions items={items} column={2} />
  260 + <ClientModal
  261 + key={'add'}
  262 + data={recordSave}
  263 + reloadTable={() => {
  264 + actionRef.current?.reload();
  265 + }}
  266 + type={'add2'}
  267 + />
  268 + ,
  269 + <EditableProTable
  270 + rowKey="tid"
  271 + formRef={ref}
  272 + actionRef={actionRef}
  273 + recordCreatorProps={false}
  274 + // recordCreatorProps={{
  275 + // record: () => ({ tid: (Math.random() * 1000000).toFixed(0) }),
  276 + // }}
  277 + loading={false}
  278 + columns={columns}
  279 + request={async () => {
  280 + const res = await postAdminClientQueryClientComunicationInfo({
  281 + data: {
  282 + clientId: record.id,
  283 + },
  284 + });
  285 + if (res.result === RESPONSE_CODE.SUCCESS) {
  286 + console.log(JSON.stringify(res.data));
  287 + return {
  288 + ...res.data,
  289 + data: res.data.data.map((item) => {
  290 + return {
  291 + ...item,
  292 + tid: (Math.random() * 1000000).toFixed(0),
  293 + };
  294 + }),
  295 + };
  296 + } else {
  297 + message.error('获取失败');
  298 + }
  299 + }}
  300 + value={dataSource}
  301 + onChange={setDataSource}
  302 + editable={{
  303 + type: 'multiple',
  304 + editableKeys,
  305 + onSave: async (rowKey, data, row) => {
  306 + console.log(rowKey, data, row);
  307 + if (data?.way === '拜访') {
  308 + data.way = 'VISIT';
  309 + } else if (data?.way === '电话') {
  310 + data.way = 'PHONE';
  311 + } else if (data?.way === '微信') {
  312 + data.way = 'WECHAT';
  313 + } else if (data?.way === '邮件') {
  314 + data.way = 'EMAIL';
  315 + } else if (data?.way === '其他') {
  316 + data.way = 'OTHER';
  317 + }
  318 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  319 + data: {
  320 + ...data,
  321 + clientId: record.id,
  322 + },
  323 + });
  324 + if (res.result === RESPONSE_CODE.SUCCESS) {
  325 + message.success(res.message);
  326 + } else {
  327 + message.error('修改失败');
  328 + }
  329 + actionRef.current?.reload();
  330 + },
  331 + onChange: setEditableRowKeys,
  332 + }}
  333 + />
  334 + {/* <Descriptions title="User Info" items={items} column={2} /> */}
  335 + {/*<ProCard title="表格数据" headerBordered collapsible defaultCollapsed>
  336 + <ProFormField
  337 + ignoreFormItem
  338 + fieldProps={{
  339 + style: {
  340 + width: '100%',
  341 + },
  342 + }}
  343 + mode="read"
  344 + valueType="jsonCode"
  345 + text={JSON.stringify(dataSource)}
  346 + />
  347 + </ProCard>*/}
  348 + </ModalForm>
  349 + );
  350 +};
src/pages/Client/Client/Components/InformationHistoryModal.tsx 0 → 100644
  1 +// import ClientModal from '@/pages/Client/FollowRecord/Components/ClientModal';
  2 +import ClientInformationModal from '@/pages/Client/Client/Components/ClientInformationModal';
  3 +
  4 +import {
  5 + postAdminClientQueryClientComunicationInfo,
  6 + postAdminClientRemoveClientComunicationInfo,
  7 +} from '@/services/request';
  8 +import { ModalForm } from '@ant-design/pro-components';
  9 +import { Button, Descriptions, Space } from 'antd';
  10 +import { useEffect, useRef, useState } from 'react';
  11 +
  12 +export default ({ data, reloadTable }) => {
  13 + console.log(data, '5656datafirstshowclient');
  14 +
  15 + // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示
  16 + const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法
  17 +
  18 + const [datetime, setDatetime] = useState(); // 跟进日期
  19 + const [createByName, setCreateByName] = useState(''); // 跟进人员
  20 + const [clientName, setClientName] = useState(''); // 客户名称
  21 + // const [clientAddress, setClientAddress] = useState(''); // 客户地址
  22 + const [way, setWay] = useState(); // 类型
  23 + // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询
  24 + // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询
  25 + // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态
  26 + // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询
  27 + const [content, setContent] = useState(''); // 跟进详情
  28 + const [createTime, setCreateTime] = useState(null); // 创建时间
  29 + const [attachments, setAttachments] = useState(); //附件
  30 + const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称
  31 +
  32 + useEffect(() => {
  33 + const request = async () => {
  34 + console.log(data, '5656datasearch');
  35 + const res = await postAdminClientQueryClientComunicationInfo({
  36 + data: {
  37 + id: data.id,
  38 + },
  39 + });
  40 + console.log(res, '5656res');
  41 + const dataSearch = res.data.data[0];
  42 + if (dataSearch) {
  43 + if (dataSearch.attachments) {
  44 + const url = dataSearch.attachments;
  45 + const match = url.match(/aliyuncs\.com\/(.*?)\?/);
  46 + let decodedStr = '';
  47 +
  48 + if (match) {
  49 + // 获取匹配的字符串并进行解码
  50 + const encodedStr = match[1];
  51 + decodedStr = decodeURIComponent(encodedStr);
  52 + setAttachmentsName(decodedStr); // 设置跟进日期
  53 + }
  54 + }
  55 + setDatetime(dataSearch.datetime); // 设置跟进日期
  56 + // setDateRange(data.dateRange || []); // 设置跟进时间范围
  57 + setCreateByName(dataSearch.createByName); // 设置跟进人员
  58 + setClientName(dataSearch.clientName); // 设置客户名称
  59 + // setClientAddress(data.clientAddress || ''); // 设置客户地址
  60 + // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询
  61 + // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询
  62 + // setTradeStatus(data.tradeStatus || ''); // 设置客户状态
  63 + // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询
  64 + setContent(dataSearch.content); // 设置跟进详情
  65 + setCreateTime(dataSearch.createTime); // 设置创建时间
  66 + setWay(dataSearch.wayText);
  67 + setAttachments(dataSearch.attachments);
  68 + }
  69 + console.log(attachments, '5656attachments');
  70 + };
  71 + request();
  72 + }, []);
  73 + const items = [
  74 + {
  75 + key: '1',
  76 + label: '跟进日期',
  77 + children: datetime, // 跟进日期
  78 + },
  79 + {
  80 + key: '2',
  81 + label: '跟进人员',
  82 + children: createByName, // 跟进人员
  83 + },
  84 + {
  85 + key: '3',
  86 + label: '客户名称',
  87 + children: clientName, // 客户名称
  88 + },
  89 + {
  90 + key: '4',
  91 + label: '跟进详情',
  92 + children: content, // 跟进详情
  93 + },
  94 + {
  95 + key: '5',
  96 + label: '创建时间',
  97 + children: createTime, // 创建时间
  98 + },
  99 + {
  100 + key: '6',
  101 + label: '跟进类型',
  102 + children: way, // 跟进类型
  103 + },
  104 + ];
  105 + const handleDelete = async () => {
  106 + console.log(JSON.stringify(data), '5656record');
  107 + // 调用删除接口
  108 + const success = await postAdminClientRemoveClientComunicationInfo({
  109 + query: {
  110 + id: data.id,
  111 + },
  112 + });
  113 + // setIsModalVisible(false);
  114 + if (success) {
  115 + actionRef?.current?.reload(); // 重新加载表格数据
  116 + }
  117 + };
  118 + return (
  119 + <Space>
  120 + <ModalForm
  121 + title="跟进记录"
  122 + trigger={<Button type="link">查看</Button>}
  123 + submitter={{
  124 + resetButtonProps: {
  125 + style: {
  126 + display: 'none',
  127 + },
  128 + },
  129 + submitButtonProps: {
  130 + style: {
  131 + display: 'none',
  132 + },
  133 + },
  134 + render: (props, defaultDoms) => {
  135 + return [
  136 + ...defaultDoms,
  137 + <>
  138 + <ClientInformationModal
  139 + key={'modify'}
  140 + data={data} // 将表单数据传递给 ClientModal
  141 + reloadTable={() => {
  142 + actionRef?.current?.reload(); // 重新加载表格数据
  143 + props.submit();
  144 + reloadTable();
  145 + console.log('5656close');
  146 + }}
  147 + type={'modify'}
  148 + onFinish={() => {
  149 + // setIsModalVisible(false);
  150 + }} // 关闭 Modal
  151 + style={{ marginRight: '10px' }}
  152 + />
  153 + <Button
  154 + key={'delete'}
  155 + onClick={() => {
  156 + handleDelete();
  157 + props.submit();
  158 + reloadTable();
  159 + }}
  160 + type="primary"
  161 + size="middle"
  162 + danger // 使用 danger 属性来将按钮颜色设置为红色
  163 + style={{ marginLeft: '10px' }}
  164 + onFinish={() => {
  165 + actionRef.current.reload();
  166 + }}
  167 + >
  168 + 删除
  169 + </Button>
  170 + </>,
  171 + ];
  172 + },
  173 + }}
  174 + onFinish={async () => {
  175 + // 提交成功后,显示 ClientDrawer
  176 + // setIsModalVisible(true);
  177 + return true;
  178 + }}
  179 + >
  180 + <Descriptions items={items} column={1} />
  181 + {attachmentsName && (
  182 + <a href={attachments} download>
  183 + 附件:{attachmentsName}
  184 + </a>
  185 + )}
  186 + </ModalForm>
  187 + </Space>
  188 + );
  189 +};
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 ButtonConfirm from '@/components/ButtomConfirm';
  2 +import ClientDrawer from '@/pages/Client/Client/Components/ClientDrawer';
  3 +import ClientImportModal from '@/pages/Client/Client/Components/ClientImportModal';
  4 +import ClientModal from '@/pages/Client/Client/Components/ClientModal';
  5 +import CommunicationHistoryModal from '@/pages/Client/Client/Components/CommunicationHistoryModal';
5 import { 6 import {
  7 + postAdminClientDeleteAdminClient,
  8 + postAdminClientGetStatisticalData,
6 postAdminClientQueryClientPage, 9 postAdminClientQueryClientPage,
7 - postServiceConstClientGroupFilters,  
8 postServiceConstClientLevels, 10 postServiceConstClientLevels,
  11 + postServiceConstClientRequirements,
  12 + postServiceConstClientSource,
9 postServiceConstTradeStatus, 13 postServiceConstTradeStatus,
10 } from '@/services'; 14 } from '@/services';
11 import { orderExport } from '@/services/order'; 15 import { orderExport } from '@/services/order';
12 import { enumToSelect } from '@/utils'; 16 import { enumToSelect } from '@/utils';
13 import type { ActionType } from '@ant-design/pro-components'; 17 import type { ActionType } from '@ant-design/pro-components';
14 import { ProTable } from '@ant-design/pro-components'; 18 import { ProTable } from '@ant-design/pro-components';
15 -import { Button, Radio, Space, message } from 'antd'; 19 +import { Badge, Button, Radio, Space, message } from 'antd';
16 import { useEffect, useRef, useState } from 'react'; 20 import { useEffect, useRef, useState } from 'react';
17 21
18 const columns = [ 22 const columns = [
@@ -25,23 +29,30 @@ const columns = [ @@ -25,23 +29,30 @@ const columns = [
25 { 29 {
26 title: '客户名称', 30 title: '客户名称',
27 dataIndex: 'name', 31 dataIndex: 'name',
28 - width: 100, 32 + width: 150,
29 ellipsis: true, 33 ellipsis: true,
30 hideInSearch: true, 34 hideInSearch: true,
31 }, 35 },
  36 + // {
  37 + // title: '单位名称',
  38 + // width: 150,
  39 + // ellipsis: true,
  40 + // dataIndex: 'companyName',
  41 + // hideInSearch: true,
  42 + // },
32 { 43 {
33 - title: '单位名称',  
34 - width: 150, 44 + title: '客户地址',
  45 + width: 250,
35 ellipsis: true, 46 ellipsis: true,
36 - dataIndex: 'companyName',  
37 - hideInSearch: true, 47 + dataIndex: 'address',
  48 + hideInSearch: false,
38 }, 49 },
39 { 50 {
40 - title: '单位地址',  
41 - width: 250, 51 + title: '联系人',
  52 + width: 150,
42 ellipsis: true, 53 ellipsis: true,
43 - dataIndex: 'companyAddressText',  
44 - hideInSearch: true, 54 + dataIndex: 'contacts',
  55 + hideInSearch: false,
45 }, 56 },
46 { 57 {
47 title: '联系电话', 58 title: '联系电话',
@@ -54,10 +65,20 @@ const columns = [ @@ -54,10 +65,20 @@ const columns = [
54 title: '客户来源', 65 title: '客户来源',
55 width: 150, 66 width: 150,
56 ellipsis: true, 67 ellipsis: true,
57 - dataIndex: 'source', 68 + dataIndex: 'sourceText',
58 hideInSearch: true, 69 hideInSearch: true,
59 }, 70 },
60 { 71 {
  72 + title: '客户来源',
  73 + valueType: 'select',
  74 + hideInTable: true,
  75 + dataIndex: 'source',
  76 + request: async () => {
  77 + const res = await postServiceConstClientSource();
  78 + return enumToSelect(res.data);
  79 + },
  80 + },
  81 + {
61 title: '推荐人', 82 title: '推荐人',
62 dataIndex: 'referrers', 83 dataIndex: 'referrers',
63 width: 150, 84 width: 150,
@@ -66,12 +87,28 @@ const columns = [ @@ -66,12 +87,28 @@ const columns = [
66 }, 87 },
67 { 88 {
68 title: '客户需求', 89 title: '客户需求',
69 - dataIndex: 'requirements',  
70 - width: 150, 90 + width: 240,
71 ellipsis: true, 91 ellipsis: true,
  92 + dataIndex: 'requirementsText',
72 hideInSearch: true, 93 hideInSearch: true,
73 }, 94 },
74 { 95 {
  96 + title: '客户需求',
  97 + dataIndex: 'requirements',
  98 + valueType: 'select',
  99 + hideInTable: true,
  100 + request: async () => {
  101 + const res = await postServiceConstClientRequirements();
  102 + // function enumToSelect(data: any) {
  103 + // const keys = Object.keys(data);
  104 + // return keys.map((value) => {
  105 + // return { label: data[value], value: value };
  106 + // });
  107 + // }
  108 + return enumToSelect(res.data);
  109 + },
  110 + },
  111 + {
75 title: '是否已报方案', 112 title: '是否已报方案',
76 width: 150, 113 width: 150,
77 ellipsis: true, 114 ellipsis: true,
@@ -84,7 +121,7 @@ const columns = [ @@ -84,7 +121,7 @@ const columns = [
84 width: 150, 121 width: 150,
85 ellipsis: true, 122 ellipsis: true,
86 dataIndex: 'quoteDatetime', 123 dataIndex: 'quoteDatetime',
87 - valueType: 'dateTime', 124 + valueType: 'date',
88 hideInSearch: true, 125 hideInSearch: true,
89 }, 126 },
90 { 127 {
@@ -111,26 +148,35 @@ const columns = [ @@ -111,26 +148,35 @@ const columns = [
111 hideInSearch: true, 148 hideInSearch: true,
112 }, 149 },
113 { 150 {
114 - title: '最新进时间', 151 + title: '最新进时间',
115 key: 'since', 152 key: 'since',
116 width: 150, 153 width: 150,
117 ellipsis: true, 154 ellipsis: true,
118 - dataIndex: 'latestCommunicationTime', 155 + dataIndex: 'updateTime',
119 valueType: 'dateTime', 156 valueType: 'dateTime',
120 hideInSearch: true, 157 hideInSearch: true,
121 }, 158 },
  159 + // {
  160 + // title: '最新跟进时间',
  161 + // key: 'since',
  162 + // width: 150,
  163 + // ellipsis: true,
  164 + // dataIndex: 'latestCommunicationTime',
  165 + // valueType: 'dateTime',
  166 + // hideInSearch: true,
  167 + // },
122 { 168 {
123 title: '客户名称', 169 title: '客户名称',
124 dataIndex: 'nameLike', 170 dataIndex: 'nameLike',
125 valueType: 'Text', 171 valueType: 'Text',
126 hideInTable: true, 172 hideInTable: true,
127 }, 173 },
128 - {  
129 - title: '单位名称',  
130 - dataIndex: 'companyNameLike',  
131 - valueType: 'Text',  
132 - hideInTable: true,  
133 - }, 174 + // {
  175 + // title: '单位名称',
  176 + // dataIndex: 'companyNameLike',
  177 + // valueType: 'Text',
  178 + // hideInTable: true,
  179 + // },
134 { 180 {
135 title: '联系电话', 181 title: '联系电话',
136 dataIndex: 'phoneNumberLike', 182 dataIndex: 'phoneNumberLike',
@@ -141,6 +187,7 @@ const columns = [ @@ -141,6 +187,7 @@ const columns = [
141 title: '是否已报方案', 187 title: '是否已报方案',
142 dataIndex: 'hasScheme', 188 dataIndex: 'hasScheme',
143 valueType: 'select', 189 valueType: 'select',
  190 + width: 1550,
144 valueEnum: { 191 valueEnum: {
145 true: { 192 true: {
146 text: '是', 193 text: '是',
@@ -160,7 +207,14 @@ const columns = [ @@ -160,7 +207,14 @@ const columns = [
160 hideInTable: true, 207 hideInTable: true,
161 request: async () => { 208 request: async () => {
162 const res = await postServiceConstClientLevels(); 209 const res = await postServiceConstClientLevels();
163 - return enumToSelect(res.data); 210 + // 明确指定所需的顺序(后端返回顺序正确,直接修改enumToSelect没作用)
  211 + function enumToSelectLevel(data: any) {
  212 + const order = ['PRIMARY_CLIENT', 'SECONDARY_CLIENT', 'TERTIARY_CLIENT'];
  213 + return order.map((key) => {
  214 + return { label: data[key], value: key };
  215 + });
  216 + }
  217 + return enumToSelectLevel(res.data);
164 }, 218 },
165 }, 219 },
166 { 220 {
@@ -192,13 +246,25 @@ const columns = [ @@ -192,13 +246,25 @@ const columns = [
192 title: '操作', 246 title: '操作',
193 valueType: 'option', 247 valueType: 'option',
194 key: 'option', 248 key: 'option',
195 - width: 150, 249 + width: 200,
196 render: (text, record, index, action) => { 250 render: (text, record, index, action) => {
197 - console.log(JSON.stringify(record)); 251 + const handleDelete = async () => {
  252 + console.log(JSON.stringify(record), '5656record1');
  253 + // 调用删除接口
  254 + const success = await postAdminClientDeleteAdminClient({
  255 + query: {
  256 + id: record.id,
  257 + },
  258 + });
  259 + if (success) {
  260 + action.reload(); // 刷新表格
  261 + }
  262 + };
  263 + console.log(JSON.stringify(record), '5656record2');
198 return [ 264 return [
199 <CommunicationHistoryModal 265 <CommunicationHistoryModal
200 key={'communicationHistory'} 266 key={'communicationHistory'}
201 - clientId={record.id} 267 + record={record}
202 />, 268 />,
203 <ClientDrawer 269 <ClientDrawer
204 key={'detail'} 270 key={'detail'}
@@ -208,6 +274,14 @@ const columns = [ @@ -208,6 +274,14 @@ const columns = [
208 action.reload(); 274 action.reload();
209 }} 275 }}
210 ></ClientDrawer>, 276 ></ClientDrawer>,
  277 + <ClientModal
  278 + key={'add'}
  279 + data={record}
  280 + reloadTable={() => {
  281 + action?.reload();
  282 + }}
  283 + type={'add'}
  284 + />,
211 <ClientDrawer 285 <ClientDrawer
212 key={'edit'} 286 key={'edit'}
213 record={record} 287 record={record}
@@ -216,6 +290,18 @@ const columns = [ @@ -216,6 +290,18 @@ const columns = [
216 action.reload(); 290 action.reload();
217 }} 291 }}
218 ></ClientDrawer>, 292 ></ClientDrawer>,
  293 + // <a key={'delete'} onClick={handleDelete}>
  294 + // 删除
  295 + // </a>,
  296 + <ButtonConfirm
  297 + key="delete"
  298 + className="p-0"
  299 + title={'删除该客户,客户下的跟进记录会一并删除'}
  300 + text="删除"
  301 + onConfirm={async () => {
  302 + handleDelete();
  303 + }}
  304 + />,
219 ]; 305 ];
220 }, 306 },
221 }, 307 },
@@ -224,23 +310,74 @@ const columns = [ @@ -224,23 +310,74 @@ const columns = [
224 export default () => { 310 export default () => {
225 const [messageApi, contextHolder] = message.useMessage(); 311 const [messageApi, contextHolder] = message.useMessage();
226 const [groupFilter, setGroupFilter] = useState('All'); 312 const [groupFilter, setGroupFilter] = useState('All');
227 - const [groupFilterOptions, setGroupFilterDataOptions] = useState([]); 313 + // const [groupFilterOptions, setGroupFilterDataOptions] = useState([]);
228 const actionRef = useRef<ActionType>(); 314 const actionRef = useRef<ActionType>();
  315 + //获得预警/全部数量
  316 + const [clientStatistic, setClientStatistic] = useState([]);
  317 + // const [allClientStatistic, setAllClientStatistic] = useState([]);
  318 + const [warningClientStatistic, setWarningClientStatistic] = useState([]);
  319 + // const reloadTable = () => {
  320 + // actionRef.current?.reload();
  321 + // };
229 useEffect(() => { 322 useEffect(() => {
230 - const pullGroupFilterDataOptions = async () => {  
231 - const res = await postServiceConstClientGroupFilters();  
232 - console.log('setGroupFilterDataOptions' + JSON.stringify(res.data));  
233 - setGroupFilterDataOptions(enumToSelect(res.data)); 323 + const pullStatistic = async () => {
  324 + let statisticalData = await postAdminClientGetStatisticalData();
  325 + console.log('stati' + JSON.stringify(statisticalData.data));
  326 + setClientStatistic(statisticalData.data);
  327 + setWarningClientStatistic(statisticalData.data[1].value);
  328 + // setAllClientStatistic(statisticalData.data[0].value);
  329 + setTimeout(() => {
  330 + console.log(clientStatistic, '5656groupFilterOptions1');
  331 + // groupFilterOptions[0].label = groupFilterOptions[0].label + '(' + clientStatistic + ')';
  332 + }, 100);
  333 + actionRef.current?.reload(); // 可能需要在这里刷新
234 }; 334 };
235 - pullGroupFilterDataOptions(); 335 + pullStatistic();
236 }, []); 336 }, []);
  337 + const groupFilterOptions = [
  338 + {
  339 + value: 'All',
  340 + label: <span>全部</span>,
  341 + },
  342 + {
  343 + value: 'WARNING_CLIENT',
  344 + label: (
  345 + <span>
  346 + 预警客户
  347 + <Badge count={warningClientStatistic} style={{ marginLeft: 8 }} />
  348 + </span>
  349 + ),
  350 + },
  351 + ];
  352 + // useEffect(() => {
  353 + // const pullGroupFilterDataOptions = async () => {
  354 + // const res = await postServiceConstClientGroupFilters();
  355 + // // console.log('setGroupFilterDataOptions' + JSON.stringify(res.data));
  356 + // const select = enumToSelect(res.data);
  357 + // console.log(select, '5656selet');
  358 + // setGroupFilterDataOptions(select);
  359 + // };
  360 + // pullGroupFilterDataOptions();
  361 + // }, []);
237 useEffect(() => { 362 useEffect(() => {
  363 + // console.log(groupFilterOptions, '5656groupFilterOptions2');
  364 + console.log(clientStatistic, '5656clientStatistic');
  365 + console.log(warningClientStatistic, '5656warningClientStatistic');
238 actionRef.current?.reload(); 366 actionRef.current?.reload();
239 }, [groupFilter]); 367 }, [groupFilter]);
240 return ( 368 return (
241 <> 369 <>
242 <Space direction="vertical" size="middle" style={{ display: 'flex' }}> 370 <Space direction="vertical" size="middle" style={{ display: 'flex' }}>
243 - <ClientStatistic></ClientStatistic> 371 + <div key={'groupFilter'}>
  372 + <Radio.Group
  373 + options={groupFilterOptions}
  374 + onChange={(e) => {
  375 + setGroupFilter(e.target.value);
  376 + }}
  377 + value={groupFilter}
  378 + optionType="button"
  379 + />
  380 + </div>
244 <ProTable 381 <ProTable
245 columns={columns} 382 columns={columns}
246 actionRef={actionRef} 383 actionRef={actionRef}
@@ -256,6 +393,7 @@ export default () =&gt; { @@ -256,6 +393,7 @@ export default () =&gt; {
256 return data; 393 return data;
257 }} 394 }}
258 search={{ 395 search={{
  396 + labelWidth: 'auto',
259 optionRender: (searchConfig, formProps, dom) => [ 397 optionRender: (searchConfig, formProps, dom) => [
260 ...dom.reverse(), 398 ...dom.reverse(),
261 <Button 399 <Button
@@ -273,6 +411,7 @@ export default () =&gt; { @@ -273,6 +411,7 @@ export default () =&gt; {
273 'POST', 411 'POST',
274 values, 412 values,
275 () => { 413 () => {
  414 + console.log(searchConfig, '5656searchConfig');
276 messageApi.destroy(); 415 messageApi.destroy();
277 }, 416 },
278 ); 417 );
@@ -323,16 +462,6 @@ export default () =&gt; { @@ -323,16 +462,6 @@ export default () =&gt; {
323 dateFormatter="string" 462 dateFormatter="string"
324 headerTitle="高级表格" 463 headerTitle="高级表格"
325 toolBarRender={() => [ 464 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 465 <ClientDrawer
337 optType={'add'} 466 optType={'add'}
338 key="button" 467 key="button"
@@ -340,7 +469,12 @@ export default () =&gt; { @@ -340,7 +469,12 @@ export default () =&gt; {
340 actionRef.current.reload(); 469 actionRef.current.reload();
341 }} 470 }}
342 ></ClientDrawer>, 471 ></ClientDrawer>,
343 - <ClientImportModal key="import" />, 472 + <ClientImportModal
  473 + key="import"
  474 + reloadTable={() => {
  475 + actionRef.current.reload();
  476 + }}
  477 + />,
344 ]} 478 ]}
345 /> 479 />
346 </Space> 480 </Space>
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/Components/ClientImportModal.tsx renamed to src/pages/Client/FollowRecord/Components/ClientImportModal.tsx
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.id === values.name,
  29 + );
  30 + let matchedId;
  31 + if (matchingItem) {
  32 + matchedId = matchingItem.id; // 匹配成功,取出 id
  33 + values.name = matchingItem.name;
  34 + } else {
  35 + matchedId = null; // 如果没有匹配项,可以设置为 null 或其他值
  36 + }
  37 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  38 + data: {
  39 + ...values,
  40 + clientId: matchedId,
  41 + },
  42 + });
  43 + if (res.result === RESPONSE_CODE.SUCCESS) {
  44 + message.success('新增成功');
  45 + reloadTable();
  46 + return true;
  47 + }
  48 + // 不返回不会关闭弹框
  49 + };
  50 + const editOnfinish = async (values) => {
  51 + // setEditClientId(data.clientId);
  52 + values.clientId = data.clientId;
  53 + console.log(values, '5656editClientId');
  54 +
  55 + // const resSearchId = await postAdminClientQueryClientPage({
  56 + // data: {
  57 + // groupFilter: 'all',
  58 + // },
  59 + // });
  60 + // const matchingItem = resSearchId.data.data.find(
  61 + // (item) => item.id === values.name,
  62 + // );
  63 +
  64 + const res = await postAdminClientAddOrModifyClientComunicationInfo({
  65 + data: {
  66 + ...values,
  67 + },
  68 + });
  69 + if (res.result === RESPONSE_CODE.SUCCESS) {
  70 + message.success('新增成功');
  71 + reloadTable();
  72 + return true;
  73 + }
  74 + // 不返回不会关闭弹框
  75 + };
  76 + const optType = {
  77 + add: {
  78 + readOnly: false,
  79 + title: '新增跟进记录',
  80 + button: (
  81 + <Button size={'middle'} type="primary">
  82 + 新增
  83 + </Button>
  84 + ),
  85 + onFinish: onfinish,
  86 + },
  87 + modify: {
  88 + readOnly: false,
  89 + title: '修改跟进记录',
  90 + button: (
  91 + <Button size={'middle'} type="primary">
  92 + 编辑
  93 + </Button>
  94 + ),
  95 + onFinish: editOnfinish,
  96 + },
  97 + detail: {
  98 + readOnly: true,
  99 + title: '查看跟进记录',
  100 + button: (
  101 + <Button size={'middle'} type="primary" color="red">
  102 + 查看
  103 + </Button>
  104 + ),
  105 + onFinish: () => {},
  106 + },
  107 + };
  108 + return (
  109 + <ModalForm
  110 + title={optType[type].title}
  111 + resize={{
  112 + onResize() {
  113 + console.log('resize!');
  114 + },
  115 + maxWidth: window.innerWidth * 0.8,
  116 + minWidth: 400,
  117 + }}
  118 + form={form}
  119 + trigger={optType[type].button}
  120 + autoFocusFirstInput
  121 + drawerProps={{
  122 + destroyOnClose: true,
  123 + }}
  124 + submitTimeout={2000}
  125 + onFinish={optType[type].onFinish}
  126 + >
  127 + <ProFormSelect
  128 + name="name"
  129 + readonly={optType[type].readOnly}
  130 + fieldProps={{
  131 + labelInValue: false,
  132 + disabled: type === 'modify',
  133 + }}
  134 + initialValue={data ? data?.clientName + '' : null}
  135 + label="客户"
  136 + width="sm"
  137 + request={async () => {
  138 + const res = await postAdminClientQueryClientPage({
  139 + data: {
  140 + groupFilter: 'all',
  141 + },
  142 + });
  143 + console.log(data, '5656data?.nameedit');
  144 + // const namesArray = res.data.data.map((item) => item.name);
  145 + // const formattedObject = res.data.data.reduce((acc, name) => {
  146 + // acc[name] = name; // 将名称作为键和值
  147 + // return acc;
  148 + // }, {});
  149 + // console.log(namesArray, '5656namesArray');
  150 + // const formattedObject = res.data.data.reduce((acc, item) => {
  151 + // acc[item.name] = item.name; // 使用 name 作为键,id 作为值
  152 + // return acc;
  153 + // }, {});
  154 + // return enumToSelect(formattedObject);
  155 + const options = res.data.data.reduce((acc, item) => {
  156 + acc.push({ label: item.name, value: item.id }); // 使用 name 作为 label,id 作为 value
  157 + return acc;
  158 + }, []);
  159 + return options;
  160 + }}
  161 + rules={[
  162 + {
  163 + required: true,
  164 + message: '请选择客户',
  165 + },
  166 + ]}
  167 + ></ProFormSelect>
  168 + <ProFormDateTimePicker
  169 + name="datetime"
  170 + label="日期"
  171 + initialValue={data ? data?.datetime + '' : null}
  172 + placeholder="请选择跟进时间"
  173 + width="sm"
  174 + rules={[
  175 + {
  176 + required: true,
  177 + message: '请选择日期',
  178 + },
  179 + ]}
  180 + />
  181 + <ProFormSelect
  182 + name="way"
  183 + width="sm"
  184 + readonly={optType[type].readOnly}
  185 + fieldProps={{
  186 + labelInValue: false,
  187 + }}
  188 + initialValue={data?.way ? data?.way + '' : null}
  189 + label="类型"
  190 + request={async () => {
  191 + const res = await postServiceConstClientWay();
  192 + return enumToSelect(res.data);
  193 + }}
  194 + rules={[
  195 + {
  196 + required: true,
  197 + message: '请选择跟进类型',
  198 + },
  199 + ]}
  200 + ></ProFormSelect>
  201 + <ProFormTextArea
  202 + name="content"
  203 + label="详情"
  204 + placeholder="请输入详情"
  205 + initialValue={data?.content}
  206 + readonly={optType[type].readOnly}
  207 + rules={[
  208 + {
  209 + required: true,
  210 + message: '请输入详情',
  211 + },
  212 + ]}
  213 + ></ProFormTextArea>
  214 + <ProFormUploadDragger
  215 + label="附件"
  216 + name="attachment"
  217 + action="upload.do"
  218 + hidden={optType[type].readOnly}
  219 + onChange={(info) => {
  220 + const uploadFile = async ({ fileList: newFileList }) => {
  221 + if (newFileList.length > 0) {
  222 + const formData = new FormData();
  223 + formData.append('file', newFileList[0].originFileObj as RcFile);
  224 + const res = await postOrderErpOrderStagesUpload({
  225 + data: formData,
  226 + headers: {
  227 + 'Content-Type':
  228 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  229 + },
  230 + });
  231 + const url = res.data;
  232 + console.log('attachments' + JSON.stringify(url));
  233 + form.setFieldValue('attachments', url);
  234 + } else {
  235 + form.setFieldValue('attachments', null);
  236 + }
  237 + };
  238 + uploadFile(info);
  239 + }}
  240 + max={1}
  241 + />
  242 + <a hidden={!optType[type].readOnly} href={data?.attachments} download>
  243 + 下载附件
  244 + </a>
  245 + <ProFormText
  246 + initialValue={data?.attachments}
  247 + name="attachments"
  248 + hidden
  249 + ></ProFormText>
  250 + <ProFormText initialValue={data?.id} name="id" hidden></ProFormText>
  251 + </ModalForm>
  252 + );
  253 +};
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 + console.log(data, '5656datafirstshowgenjin');
  12 +
  13 + // const [isModalVisible, setIsModalVisible] = useState(false); // 控制 ClientModal 的显示
  14 + const actionRef = useRef(); // 引用 actionRef,方便调用 reload 方法
  15 +
  16 + const [datetime, setDatetime] = useState(); // 跟进日期
  17 + const [createByName, setCreateByName] = useState(''); // 跟进人员
  18 + const [clientName, setClientName] = useState(''); // 客户名称
  19 + // const [clientAddress, setClientAddress] = useState(''); // 客户地址
  20 + const [way, setWay] = useState(); // 类型
  21 + // const [clientNameLike, setClientNameLike] = useState(''); // 客户名称模糊查询
  22 + // const [clientAddressLike, setClientAddressLike] = useState(''); // 客户地址模糊查询
  23 + // const [tradeStatus, setTradeStatus] = useState(''); // 客户状态
  24 + // const [tradeStatusLike, setTradeStatusLike] = useState(''); // 客户状态模糊查询
  25 + const [content, setContent] = useState(''); // 跟进详情
  26 + const [createTime, setCreateTime] = useState(null); // 创建时间
  27 + const [attachments, setAttachments] = useState(); //附件
  28 + const [attachmentsName, setAttachmentsName] = useState(''); // 附件名称
  29 +
  30 + useEffect(() => {
  31 + const request = async () => {
  32 + console.log(data, '5656datasearch');
  33 + const res = await postAdminClientQueryClientComunicationInfo({
  34 + data: {
  35 + id: data.id,
  36 + },
  37 + });
  38 + console.log(res, '5656res');
  39 + const dataSearch = res.data.data[0];
  40 + if (dataSearch) {
  41 + if (dataSearch.attachments) {
  42 + const url = dataSearch.attachments;
  43 + const match = url.match(/aliyuncs\.com\/(.*?)\?/);
  44 + let decodedStr = '';
  45 +
  46 + if (match) {
  47 + // 获取匹配的字符串并进行解码
  48 + const encodedStr = match[1];
  49 + decodedStr = decodeURIComponent(encodedStr);
  50 + setAttachmentsName(decodedStr); // 设置跟进日期
  51 + }
  52 + }
  53 + setDatetime(dataSearch.datetime); // 设置跟进日期
  54 + // setDateRange(data.dateRange || []); // 设置跟进时间范围
  55 + setCreateByName(dataSearch.createByName); // 设置跟进人员
  56 + setClientName(dataSearch.clientName); // 设置客户名称
  57 + // setClientAddress(data.clientAddress || ''); // 设置客户地址
  58 + // setClientNameLike(data.clientNameLike || ''); // 设置客户名称模糊查询
  59 + // setClientAddressLike(data.clientAddressLike || ''); // 设置客户地址模糊查询
  60 + // setTradeStatus(data.tradeStatus || ''); // 设置客户状态
  61 + // setTradeStatusLike(data.tradeStatusLike || ''); // 设置客户状态模糊查询
  62 + setContent(dataSearch.content); // 设置跟进详情
  63 + setCreateTime(dataSearch.createTime); // 设置创建时间
  64 + setWay(dataSearch.wayText);
  65 + setAttachments(dataSearch.attachments);
  66 + }
  67 + console.log(attachments, '5656attachments');
  68 + };
  69 + request();
  70 + }, []);
  71 + const items = [
  72 + {
  73 + key: '1',
  74 + label: '跟进日期',
  75 + children: datetime, // 跟进日期
  76 + },
  77 + {
  78 + key: '2',
  79 + label: '跟进人员',
  80 + children: createByName, // 跟进人员
  81 + },
  82 + {
  83 + key: '3',
  84 + label: '客户名称',
  85 + children: clientName, // 客户名称
  86 + },
  87 + {
  88 + key: '4',
  89 + label: '跟进详情',
  90 + children: content, // 跟进详情
  91 + },
  92 + {
  93 + key: '5',
  94 + label: '创建时间',
  95 + children: createTime, // 创建时间
  96 + },
  97 + {
  98 + key: '6',
  99 + label: '跟进类型',
  100 + children: way, // 跟进类型
  101 + },
  102 + ];
  103 + const handleDelete = async () => {
  104 + console.log(JSON.stringify(data), '5656record');
  105 + // 调用删除接口
  106 + const success = await postAdminClientRemoveClientComunicationInfo({
  107 + query: {
  108 + id: data.id,
  109 + },
  110 + });
  111 + // setIsModalVisible(false);
  112 + if (success) {
  113 + actionRef?.current?.reload(); // 重新加载表格数据
  114 + }
  115 + };
  116 + return (
  117 + <Space>
  118 + <ModalForm
  119 + title="跟进记录"
  120 + trigger={<Button type="link">查看</Button>}
  121 + submitter={{
  122 + resetButtonProps: {
  123 + style: {
  124 + display: 'none',
  125 + },
  126 + },
  127 + submitButtonProps: {
  128 + style: {
  129 + display: 'none',
  130 + },
  131 + },
  132 + render: (props, defaultDoms) => {
  133 + return [
  134 + ...defaultDoms,
  135 + <>
  136 + <ClientModal
  137 + key={'modify'}
  138 + data={data} // 将表单数据传递给 ClientModal
  139 + reloadTable={() => {
  140 + actionRef?.current?.reload(); // 重新加载表格数据
  141 + props.submit();
  142 + reloadTable();
  143 + console.log('5656close');
  144 + }}
  145 + type={'modify'}
  146 + onFinish={() => {
  147 + // setIsModalVisible(false);
  148 + }} // 关闭 Modal
  149 + style={{ marginRight: '10px' }}
  150 + />
  151 + <Button
  152 + key={'delete'}
  153 + onClick={() => {
  154 + handleDelete();
  155 + props.submit();
  156 + reloadTable();
  157 + }}
  158 + type="primary"
  159 + size="middle"
  160 + danger // 使用 danger 属性来将按钮颜色设置为红色
  161 + style={{ marginLeft: '10px' }}
  162 + onFinish={() => {
  163 + actionRef.current.reload();
  164 + }}
  165 + >
  166 + 删除
  167 + </Button>
  168 + </>,
  169 + ];
  170 + },
  171 + }}
  172 + onFinish={async () => {
  173 + // 提交成功后,显示 ClientDrawer
  174 + // setIsModalVisible(true);
  175 + return true;
  176 + }}
  177 + >
  178 + <Descriptions items={items} column={1} />
  179 + {attachmentsName && (
  180 + <a href={attachments} download>
  181 + 附件:{attachmentsName}
  182 + </a>
  183 + )}
  184 + </ModalForm>
  185 + </Space>
  186 + );
  187 +};
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 + postServiceConstClientWay,
  8 + postServiceConstTradeStatus,
  9 +} from '@/services';
  10 +import { enumToSelect } from '@/utils';
  11 +import type { ActionType } from '@ant-design/pro-components';
  12 +import { ProTable } from '@ant-design/pro-components';
  13 +import { Button, Space, message } from 'antd';
  14 +import { useRef, useState } from 'react';
  15 +
  16 +export default () => {
  17 + const actionRef = useRef<ActionType>();
  18 + const [refreshKey, setRefreshKey] = useState(0); // 用于强制刷新的键
  19 +
  20 + const reload = () => {
  21 + actionRef.current.reload(); // 重新加载数据
  22 + console.log('5656flush');
  23 +
  24 + // 更新 refreshKey,强制刷新 CommunicationHistoryModal
  25 + setRefreshKey((prevKey) => prevKey + 1);
  26 + };
  27 + //biaoji
  28 + const columns = [
  29 + {
  30 + title: '跟进日期',
  31 + key: 'datetime',
  32 + width: 150,
  33 + ellipsis: true,
  34 + dataIndex: 'datetime',
  35 + valueType: 'dateTime',
  36 + hideInSearch: true,
  37 + // search: {
  38 + // transform: (value) => {
  39 + // if (value) {
  40 + // return {
  41 + // createTimeGe: value[0],
  42 + // createTimeLe: value[1],
  43 + // };
  44 + // }
  45 + // },
  46 + // },
  47 + },
  48 + {
  49 + title: '跟进时间',
  50 + dataIndex: 'dateRange',
  51 + valueType: 'dateRange',
  52 + hideInTable: true,
  53 + search: {
  54 + transform: (value) => {
  55 + if (value) {
  56 + return {
  57 + dateTimeGe: value[0],
  58 + dateTimeLe: value[1],
  59 + };
  60 + }
  61 + },
  62 + },
  63 + },
  64 + {
  65 + title: '跟进人员',
  66 + dataIndex: 'updateByName',
  67 + width: 100,
  68 + ellipsis: true,
  69 + hideInSearch: false,
  70 + },
  71 + {
  72 + title: '客户名称',
  73 + dataIndex: 'clientName',
  74 + width: 150,
  75 + ellipsis: true,
  76 + hideInSearch: true,
  77 + },
  78 + {
  79 + title: '客户地址',
  80 + dataIndex: 'clientAddress',
  81 + width: 250,
  82 + ellipsis: true,
  83 + hideInSearch: true,
  84 + },
  85 + {
  86 + title: '跟进类型',
  87 + dataIndex: 'wayText',
  88 + width: 100,
  89 + ellipsis: true,
  90 + hideInSearch: true,
  91 + },
  92 + {
  93 + title: '跟进类型',
  94 + dataIndex: 'way',
  95 + width: 100,
  96 + ellipsis: true,
  97 + hideInSearch: false,
  98 + hideInTable: true,
  99 + request: async () => {
  100 + const res = await postServiceConstClientWay();
  101 + return enumToSelect(res.data);
  102 + },
  103 + },
  104 + {
  105 + title: '客户名称',
  106 + dataIndex: 'clientNameLike',
  107 + width: 150,
  108 + ellipsis: true,
  109 + hideInSearch: false,
  110 + hideInTable: true,
  111 + },
  112 + {
  113 + title: '客户地址',
  114 + dataIndex: 'clientAddressLike',
  115 + width: 250,
  116 + ellipsis: true,
  117 + hideInSearch: false,
  118 + hideInTable: true,
  119 + },
  120 + {
  121 + title: '客户状态',
  122 + dataIndex: 'tradeStatus',
  123 + width: 100,
  124 + ellipsis: true,
  125 + hideInSearch: true,
  126 + },
  127 + {
  128 + title: '客户状态',
  129 + dataIndex: 'tradeStatusLike',
  130 + width: 100,
  131 + ellipsis: true,
  132 + hideInSearch: false,
  133 + hideInTable: true,
  134 + request: async () => {
  135 + const res = await postServiceConstTradeStatus();
  136 + return enumToSelect(res.data);
  137 + },
  138 + },
  139 + {
  140 + title: '跟进详情',
  141 + dataIndex: 'content',
  142 + width: 250,
  143 + ellipsis: true,
  144 + hideInSearch: false,
  145 + },
  146 + {
  147 + title: '创建时间',
  148 + dataIndex: 'createTime',
  149 + width: 150,
  150 + ellipsis: true,
  151 + hideInSearch: true,
  152 + },
  153 + {
  154 + title: '附件',
  155 + dataIndex: 'attachments',
  156 + width: 150,
  157 + ellipsis: true,
  158 + hideInSearch: true,
  159 + hideInTable: true,
  160 + },
  161 + {
  162 + title: '操作',
  163 + valueType: 'option',
  164 + key: 'option',
  165 + width: 150,
  166 + render: (text, record, index, action) => {
  167 + const handleDelete = async () => {
  168 + // console.log(JSON.stringify(record), '5656record');
  169 + // 调用删除接口
  170 + const success = await postAdminClientRemoveClientComunicationInfo({
  171 + query: {
  172 + id: record.id,
  173 + },
  174 + });
  175 + if (success) {
  176 + action.reload(); // 刷新表格
  177 + }
  178 + };
  179 + return [
  180 + <CommunicationHistoryModal
  181 + // key={'communicationHistory'}
  182 + key={`communicationHistory-${refreshKey}`} // 使用 refreshKey 来强制更新组件
  183 + data={record}
  184 + // reloadTable={() => {
  185 + // actionRef.current.reload();
  186 + // console.log('5656flush');
  187 + // }}
  188 + reloadTable={reload}
  189 + />,
  190 + <>
  191 + <Button
  192 + key={'delete'}
  193 + onClick={() => {
  194 + handleDelete();
  195 + actionRef.current.reload();
  196 + }}
  197 + // reloadTable={() => {
  198 + // actionRef.current.reload();
  199 + // }}
  200 + type="link"
  201 + size="middle"
  202 + // 使用 danger 属性来将按钮颜色设置为红色
  203 + // onFinish={() => {
  204 + // actionRef.current.reload();
  205 + // }}
  206 + >
  207 + 删除
  208 + </Button>
  209 + </>,
  210 + ];
  211 + },
  212 + },
  213 + ];
  214 +
  215 + // useEffect(() => {
  216 + // const pullGroupFilterDataOptions = async () => {
  217 + // const res = await postServiceConstClientGroupFilters();
  218 + // console.log('setGroupFilterDataOptions' + JSON.stringify(res.data));
  219 + // setGroupFilterDataOptions(enumToSelect(res.data));
  220 + // };
  221 + // pullGroupFilterDataOptions();
  222 + // }, []);
  223 + // useEffect(() => {
  224 + // actionRef.current?.reload();
  225 + // }, [groupFilter]);
  226 + return (
  227 + <>
  228 + <Space direction="vertical" size="middle" style={{ display: 'flex' }}>
  229 + <ProTable
  230 + columns={columns}
  231 + actionRef={actionRef}
  232 + cardBordered
  233 + request={async (params) => {
  234 + const res = await postAdminClientQueryClientComunicationInfo({
  235 + data: {
  236 + ...params,
  237 + },
  238 + });
  239 + console.log(params, '5656566params');
  240 + if (res.result === RESPONSE_CODE.SUCCESS) {
  241 + console.log(JSON.stringify(res.data));
  242 + return {
  243 + ...res.data,
  244 + data: res.data.data.map((item) => {
  245 + return {
  246 + ...item,
  247 + tid: (Math.random() * 1000000).toFixed(0),
  248 + };
  249 + }),
  250 + };
  251 + } else {
  252 + message.error('获取失败');
  253 + }
  254 + }}
  255 + search={{
  256 + optionRender: (searchConfig, formProps, dom) => [...dom.reverse()],
  257 + }}
  258 + scroll={{
  259 + x: 1400,
  260 + }}
  261 + editable={{
  262 + type: 'multiple',
  263 + }}
  264 + columnsState={{
  265 + persistenceKey: 'pro-table-singe-demos',
  266 + persistenceType: 'localStorage',
  267 + defaultValue: {
  268 + option: { fixed: 'right', disable: true },
  269 + },
  270 + onChange(value) {
  271 + console.log('value: ', value);
  272 + },
  273 + }}
  274 + rowKey="id"
  275 + options={{
  276 + setting: {
  277 + listsHeight: 400,
  278 + },
  279 + }}
  280 + form={{
  281 + // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
  282 + syncToUrl: (values, type) => {
  283 + if (type === 'get') {
  284 + return {
  285 + ...values,
  286 + created_at: [values.startTime, values.endTime],
  287 + };
  288 + }
  289 + return values;
  290 + },
  291 + }}
  292 + pagination={{
  293 + pageSize: 5,
  294 + onChange: (page) => console.log(page),
  295 + }}
  296 + dateFormatter="string"
  297 + headerTitle="高级表格"
  298 + toolBarRender={() => [
  299 + <ClientModal
  300 + key={'add'}
  301 + reloadTable={() => {
  302 + actionRef.current.reload();
  303 + }}
  304 + type={'add'}
  305 + />,
  306 + ]}
  307 + />
  308 + </Space>
  309 + {/* {contextHolder} */}
  310 + </>
  311 + );
  312 +};
src/pages/Order/Order/components/ConfirmReceiptModal.tsx
@@ -107,8 +107,8 @@ export default ({ data, onClose }) =&gt; { @@ -107,8 +107,8 @@ export default ({ data, onClose }) =&gt; {
107 setPreviewOpen(true); 107 setPreviewOpen(true);
108 setPreviewTitle( 108 setPreviewTitle(
109 file.name || 109 file.name ||
110 - file.originFileObj?.name ||  
111 - file.url!.substring(file.url!.lastIndexOf('/') + 1), 110 + file.originFileObj?.name ||
  111 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
112 ); 112 );
113 }; 113 };
114 114
src/pages/Order/Order/components/DeliverModal.tsx
@@ -260,7 +260,7 @@ const DeliverModal = ({ @@ -260,7 +260,7 @@ const DeliverModal = ({
260 serialNumber: item.serialNumber, 260 serialNumber: item.serialNumber,
261 packageNumber: 261 packageNumber:
262 item.packageNumber === null || 262 item.packageNumber === null ||
263 - item.packageNumber === undefined 263 + item.packageNumber === undefined
264 ? 1 264 ? 1
265 : item.packageNumber, 265 : item.packageNumber,
266 logisticsNotes: item.logisticsNotes, 266 logisticsNotes: item.logisticsNotes,
src/pages/Order/Order/components/FeedbackRegistrationModal.tsx 0 → 100644
  1 +import { postServiceOrderFeedbackRegistration } from '@/services/request';
  2 +import { Input, Modal } from 'antd';
  3 +import { useState } from 'react';
  4 +
  5 +// import { cloneDeep } from 'lodash';
  6 +export default ({ subOrders, onClose }) => {
  7 + const [isModalOpen] = useState(true);
  8 + const { TextArea } = Input;
  9 + const [textValue, setTextValue] = useState('');
  10 +
  11 + const handleOk = async () => {
  12 + console.log(textValue); // 处理输入的文本
  13 + console.log(subOrders, '5656subOrders');
  14 + let res = await postServiceOrderFeedbackRegistration({
  15 + data: {
  16 + id: subOrders[0].id,
  17 + feedbackRegistrationContent: textValue,
  18 + },
  19 + });
  20 + console.log(res, '5656res');
  21 + onClose();
  22 + // setIsModalOpen(false);
  23 + // onClose();
  24 + };
  25 + const handleCancel = () => {
  26 + onClose();
  27 + // setIsModalOpen(false);
  28 + // onClose();
  29 + };
  30 + const handleChange = (e) => {
  31 + setTextValue(e.target.value);
  32 + };
  33 + return (
  34 + <>
  35 + {/* <ModalForm<{
  36 + filePaths: any;
  37 + }>
  38 + width={500}
  39 + open
  40 + title="回访登记"
  41 + form={form}
  42 + autoFocusFirstInput
  43 + modalProps={{
  44 + okText: '提交',
  45 + cancelText: '取消',
  46 + destroyOnClose: true,
  47 + onCancel: () => {
  48 + setVisible(false);
  49 + },
  50 + }}
  51 + onFinish={async () => {
  52 + onClose();
  53 + }}
  54 + onOpenChange={setVisible}
  55 + >
  56 + <TextArea rows={6} placeholder="请输入" />
  57 + </ModalForm> */}
  58 + <Modal
  59 + title="回访登记"
  60 + open={isModalOpen}
  61 + onOk={handleOk}
  62 + onCancel={handleCancel}
  63 + >
  64 + <TextArea
  65 + rows={6}
  66 + placeholder="请输入"
  67 + onChange={handleChange}
  68 + value={textValue}
  69 + />
  70 + </Modal>
  71 + </>
  72 + );
  73 +};
src/pages/Order/Order/components/FinancialDrawer.tsx
@@ -144,107 +144,107 @@ export default ({ @@ -144,107 +144,107 @@ export default ({
144 144
145 {invoicingStatus !== 'UN_INVOICE' 145 {invoicingStatus !== 'UN_INVOICE'
146 ? [ 146 ? [
147 - <ProFormDatePicker  
148 - key="invoicingTime"  
149 - width="lg"  
150 - name="invoicingTime"  
151 - label="开票时间"  
152 - disabled={isEdit}  
153 - rules={[  
154 - { required: !isEdit ? true : false, message: '这是必填项' },  
155 - ]}  
156 - initialValue={subOrders[0]?.invoicingTime}  
157 - />,  
158 - <ProFormText  
159 - key="purchaser"  
160 - width="lg"  
161 - name="purchaser"  
162 - label="抬头名称"  
163 - disabled={isEdit}  
164 - rules={[  
165 - { required: !isEdit ? true : false, message: '这是必填项' },  
166 - ]}  
167 - initialValue={subOrders[0]?.purchaser}  
168 - />,  
169 - <ProFormDatePicker  
170 - key="financialReceiptIssuanceTime"  
171 - width="lg"  
172 - name="financialReceiptIssuanceTime"  
173 - label="开收据时间"  
174 - initialValue={subOrders[0]?.financialReceiptIssuanceTime}  
175 - />,  
176 - <ProFormDatePicker  
177 - key="collectMoneyTime"  
178 - width="lg"  
179 - name="collectMoneyTime"  
180 - label="收款时间"  
181 - initialValue={subOrders[0]?.collectMoneyTime}  
182 - />,  
183 - <ProFormText  
184 - width="lg"  
185 - key="invoiceNumber"  
186 - name="invoiceNumber"  
187 - label="发票号码"  
188 - initialValue={subOrders[0]?.invoiceNumber}  
189 - rules={[{ required: true, message: '发票号码必填' }]}  
190 - />,  
191 - <div  
192 - key="salesChooseReceivingCompany"  
193 - hidden={subOrders[0].receivingCompany === null}  
194 - >  
195 - <span className={'pl-2 text-xs text-gray-400'}>  
196 - 销售申请开票时选择了:  
197 - {enumValueToLabel(  
198 - subOrders[0].receivingCompany,  
199 - getReceivingCompanyOptions(PAYEE_OPTIONS),  
200 - )}  
201 - </span>  
202 - <span  
203 - hidden={subOrders[0].receivingCompany === 'ANY'}  
204 - className={  
205 - 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'  
206 - }  
207 - onClick={() => {  
208 - chooseReceivingCompany(subOrders[0].receivingCompany);  
209 - }} 147 + <ProFormDatePicker
  148 + key="invoicingTime"
  149 + width="lg"
  150 + name="invoicingTime"
  151 + label="开票时间"
  152 + disabled={isEdit}
  153 + rules={[
  154 + { required: !isEdit ? true : false, message: '这是必填项' },
  155 + ]}
  156 + initialValue={subOrders[0]?.invoicingTime}
  157 + />,
  158 + <ProFormText
  159 + key="purchaser"
  160 + width="lg"
  161 + name="purchaser"
  162 + label="抬头名称"
  163 + disabled={isEdit}
  164 + rules={[
  165 + { required: !isEdit ? true : false, message: '这是必填项' },
  166 + ]}
  167 + initialValue={subOrders[0]?.purchaser}
  168 + />,
  169 + <ProFormDatePicker
  170 + key="financialReceiptIssuanceTime"
  171 + width="lg"
  172 + name="financialReceiptIssuanceTime"
  173 + label="开收据时间"
  174 + initialValue={subOrders[0]?.financialReceiptIssuanceTime}
  175 + />,
  176 + <ProFormDatePicker
  177 + key="collectMoneyTime"
  178 + width="lg"
  179 + name="collectMoneyTime"
  180 + label="收款时间"
  181 + initialValue={subOrders[0]?.collectMoneyTime}
  182 + />,
  183 + <ProFormText
  184 + width="lg"
  185 + key="invoiceNumber"
  186 + name="invoiceNumber"
  187 + label="发票号码"
  188 + initialValue={subOrders[0]?.invoiceNumber}
  189 + rules={[{ required: true, message: '发票号码必填' }]}
  190 + />,
  191 + <div
  192 + key="salesChooseReceivingCompany"
  193 + hidden={subOrders[0].receivingCompany === null}
210 > 194 >
211 - 选择  
212 - </span>  
213 - </div>,  
214 - <ProFormSelect  
215 - key="payee"  
216 - placeholder="选择收款单位"  
217 - name="payee"  
218 - width="lg"  
219 - showSearch  
220 - label="收款单位"  
221 - options={enumToSelect(PAYEE_OPTIONS)}  
222 - initialValue={subOrders[0]?.payee}  
223 - rules={[{ required: true, message: '收款单位必填' }]}  
224 - />,  
225 -  
226 - <div id="total-payment" key="money">  
227 - <ProFormDigit  
228 - key="money"  
229 - name="money" 195 + <span className={'pl-2 text-xs text-gray-400'}>
  196 + 销售申请开票时选择了:
  197 + {enumValueToLabel(
  198 + subOrders[0].receivingCompany,
  199 + getReceivingCompanyOptions(PAYEE_OPTIONS),
  200 + )}
  201 + </span>
  202 + <span
  203 + hidden={subOrders[0].receivingCompany === 'ANY'}
  204 + className={
  205 + 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'
  206 + }
  207 + onClick={() => {
  208 + chooseReceivingCompany(subOrders[0].receivingCompany);
  209 + }}
  210 + >
  211 + 选择
  212 + </span>
  213 + </div>,
  214 + <ProFormSelect
  215 + key="payee"
  216 + placeholder="选择收款单位"
  217 + name="payee"
230 width="lg" 218 width="lg"
231 - label="金额"  
232 - rules={[{ required: true, message: '金额必填' }]}  
233 - tooltip="点击计算,合计所有子订单对应主订单总额"  
234 - fieldProps={{  
235 - addonAfter: (  
236 - <Button  
237 - className="rounded-l-none"  
238 - type="primary"  
239 - onClick={computeTotalPayment}  
240 - >  
241 - 计算  
242 - </Button>  
243 - ),  
244 - }}  
245 - />  
246 - </div>,  
247 - ] 219 + showSearch
  220 + label="收款单位"
  221 + options={enumToSelect(PAYEE_OPTIONS)}
  222 + initialValue={subOrders[0]?.payee}
  223 + rules={[{ required: true, message: '收款单位必填' }]}
  224 + />,
  225 +
  226 + <div id="total-payment" key="money">
  227 + <ProFormDigit
  228 + key="money"
  229 + name="money"
  230 + width="lg"
  231 + label="金额"
  232 + rules={[{ required: true, message: '金额必填' }]}
  233 + tooltip="点击计算,合计所有子订单对应主订单总额"
  234 + fieldProps={{
  235 + addonAfter: (
  236 + <Button
  237 + className="rounded-l-none"
  238 + type="primary"
  239 + onClick={computeTotalPayment}
  240 + >
  241 + 计算
  242 + </Button>
  243 + ),
  244 + }}
  245 + />
  246 + </div>,
  247 + ]
248 : ''} 248 : ''}
249 249
250 <ProFormSelect 250 <ProFormSelect
src/pages/Order/Order/components/FinancialEditDrawer.tsx
@@ -130,24 +130,24 @@ export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) =&gt; { @@ -130,24 +130,24 @@ export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) =&gt; {
130 width="lg" 130 width="lg"
131 name="financialReceiptIssuanceTime" 131 name="financialReceiptIssuanceTime"
132 label="开收据时间" 132 label="开收据时间"
133 - // rules={[  
134 - // {  
135 - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',  
136 - // message: '开收据时间必填',  
137 - // },  
138 - // ]} 133 + // rules={[
  134 + // {
  135 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  136 + // message: '开收据时间必填',
  137 + // },
  138 + // ]}
139 /> 139 />
140 <ProFormDatePicker 140 <ProFormDatePicker
141 key="collectMoneyTime" 141 key="collectMoneyTime"
142 width="lg" 142 width="lg"
143 name="collectMoneyTime" 143 name="collectMoneyTime"
144 label="收款时间" 144 label="收款时间"
145 - // rules={[  
146 - // {  
147 - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',  
148 - // message: '收款时间必填',  
149 - // },  
150 - // ]} 145 + // rules={[
  146 + // {
  147 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  148 + // message: '收款时间必填',
  149 + // },
  150 + // ]}
151 /> 151 />
152 </DrawerForm> 152 </DrawerForm>
153 ); 153 );
src/pages/Order/Order/components/ImagesViewerModal.tsx
@@ -3,7 +3,7 @@ import { Button, Divider, Image, Modal } from &#39;antd&#39;; @@ -3,7 +3,7 @@ import { Button, Divider, Image, Modal } from &#39;antd&#39;;
3 import { useEffect, useState } from 'react'; 3 import { useEffect, useState } from 'react';
4 export default ({ setVisible, optType, onClose, orderRow }) => { 4 export default ({ setVisible, optType, onClose, orderRow }) => {
5 const [images, setImages] = useState<any[]>([]); 5 const [images, setImages] = useState<any[]>([]);
6 - const [title, setTitle] = useState("收货凭证"); 6 + const [title, setTitle] = useState('收货凭证');
7 const handleOk = () => { 7 const handleOk = () => {
8 onClose(); 8 onClose();
9 setVisible(false); 9 setVisible(false);
@@ -23,7 +23,7 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; { @@ -23,7 +23,7 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; {
23 } 23 }
24 useEffect(() => { 24 useEffect(() => {
25 if (optType === 'shippingReceipt') { 25 if (optType === 'shippingReceipt') {
26 - setTitle("收货凭证"); 26 + setTitle('收货凭证');
27 getImages(); 27 getImages();
28 } else if (optType === 'paymentReceipt') { 28 } else if (optType === 'paymentReceipt') {
29 let paymentReceiptsImagesList: any[] = []; 29 let paymentReceiptsImagesList: any[] = [];
@@ -34,7 +34,6 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; { @@ -34,7 +34,6 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; {
34 paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)]; 34 paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)];
35 setImages(paymentReceiptsImagesList); 35 setImages(paymentReceiptsImagesList);
36 } 36 }
37 -  
38 }, []); 37 }, []);
39 38
40 return ( 39 return (
src/pages/Order/Order/components/ModifiedDiffModal.tsx
@@ -106,7 +106,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -106,7 +106,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
106 onClick={() => { 106 onClick={() => {
107 window.open( 107 window.open(
108 '/previewApi/onlinePreview?url=' + 108 '/previewApi/onlinePreview?url=' +
109 - encodeURIComponent(Base64.encode(item)), 109 + encodeURIComponent(Base64.encode(item)),
110 ); 110 );
111 }} 111 }}
112 > 112 >
src/pages/Order/Order/components/OrderDrawer copy.tsx
@@ -554,7 +554,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -554,7 +554,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
554 onChange={(_, option) => { 554 onChange={(_, option) => {
555 autoFillSalesInfo(option); 555 autoFillSalesInfo(option);
556 }} 556 }}
557 - // disabled={mainInfoDisbled} 557 + // disabled={mainInfoDisbled}
558 /> 558 />
559 559
560 <ProFormText 560 <ProFormText
@@ -642,7 +642,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -642,7 +642,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
642 }, 642 },
643 }} 643 }}
644 debounceTime={1000} 644 debounceTime={1000}
645 - request={async (value, { }) => { 645 + request={async (value, {}) => {
646 const keywords = value.keyWords; 646 const keywords = value.keyWords;
647 const res = await postKingdeeRepCustomer({ 647 const res = await postKingdeeRepCustomer({
648 data: { search: keywords }, 648 data: { search: keywords },
@@ -740,7 +740,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -740,7 +740,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
740 </Button> 740 </Button>
741 ), 741 ),
742 }} 742 }}
743 - // disabled={mainInfoDisbled} 743 + // disabled={mainInfoDisbled}
744 /> 744 />
745 </div> 745 </div>
746 746
@@ -752,7 +752,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -752,7 +752,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
752 label="支付渠道" 752 label="支付渠道"
753 options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)} 753 options={enumToSelect(PAYMENT_CHANNEL_OPTIONS)}
754 rules={[{ required: true, message: '支付渠道必填' }]} 754 rules={[{ required: true, message: '支付渠道必填' }]}
755 - // disabled={mainInfoDisbled} 755 + // disabled={mainInfoDisbled}
756 /> 756 />
757 <ProFormSelect 757 <ProFormSelect
758 placeholder="请输入支付方式" 758 placeholder="请输入支付方式"
@@ -762,7 +762,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -762,7 +762,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
762 label="支付方式" 762 label="支付方式"
763 options={enumToSelect(PAYMENT_METHOD_OPTIONS)} 763 options={enumToSelect(PAYMENT_METHOD_OPTIONS)}
764 rules={[{ required: true, message: '支付方式必填' }]} 764 rules={[{ required: true, message: '支付方式必填' }]}
765 - // disabled={mainInfoDisbled} 765 + // disabled={mainInfoDisbled}
766 /> 766 />
767 <ProFormSelect 767 <ProFormSelect
768 placeholder="选择是否需要开票" 768 placeholder="选择是否需要开票"
@@ -1094,7 +1094,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1094,7 +1094,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1094 options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)} 1094 options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)}
1095 initialValue={'EXPERIMENTAL_CONSUMABLES'} 1095 initialValue={'EXPERIMENTAL_CONSUMABLES'}
1096 rules={[{ required: true, message: '所属事业部必填' }]} 1096 rules={[{ required: true, message: '所属事业部必填' }]}
1097 - // disabled={mainInfoDisbled} 1097 + // disabled={mainInfoDisbled}
1098 />, 1098 />,
1099 <ProFormTextArea 1099 <ProFormTextArea
1100 key={'notes' + listMeta.index} 1100 key={'notes' + listMeta.index}
src/pages/Order/Order/components/OrderDrawer.tsx
@@ -557,9 +557,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -557,9 +557,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
557 form.setFieldValue( 557 form.setFieldValue(
558 'customerShippingAddress', 558 'customerShippingAddress',
559 getDefaultString(option.province) + 559 getDefaultString(option.province) +
560 - getDefaultString(option.city) +  
561 - getDefaultString(option.district) +  
562 - getDefaultString(option.detail), 560 + getDefaultString(option.city) +
  561 + getDefaultString(option.district) +
  562 + getDefaultString(option.detail),
563 ); 563 );
564 form.setFieldValue('customerNameString', option.realName); 564 form.setFieldValue('customerNameString', option.realName);
565 565
@@ -642,11 +642,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -642,11 +642,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
642 642
643 message.error( 643 message.error(
644 '用户余额不足,当前预减的金额为:' + 644 '用户余额不足,当前预减的金额为:' +
645 - data.subPrice +  
646 - ',当前账号余额为:' +  
647 - data.nowMoney +  
648 - ',当前账号可赊账额度为:' +  
649 - data.creditLimit, 645 + data.subPrice +
  646 + ',当前账号余额为:' +
  647 + data.nowMoney +
  648 + ',当前账号可赊账额度为:' +
  649 + data.creditLimit,
650 ); 650 );
651 return false; 651 return false;
652 } 652 }
@@ -1111,7 +1111,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1111,7 +1111,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1111 }, 1111 },
1112 }} 1112 }}
1113 debounceTime={1000} 1113 debounceTime={1000}
1114 - request={async (value, { }) => { 1114 + request={async (value, {}) => {
1115 const keywords = value.keyWords; 1115 const keywords = value.keyWords;
1116 if (keywords === '') { 1116 if (keywords === '') {
1117 return []; 1117 return [];
@@ -1867,7 +1867,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1867,7 +1867,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1867 placeholder="请输入商品参数" 1867 placeholder="请输入商品参数"
1868 disabled={ 1868 disabled={
1869 productParametersDisabledFlagList[listMeta.index] !== 1869 productParametersDisabledFlagList[listMeta.index] !==
1870 - false || optType('after-sales-check') 1870 + false || optType('after-sales-check')
1871 } 1871 }
1872 />, 1872 />,
1873 <ProFormDigit 1873 <ProFormDigit
@@ -1920,7 +1920,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1920,7 +1920,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1920 placeholder="请输入商品单位" 1920 placeholder="请输入商品单位"
1921 disabled={ 1921 disabled={
1922 productParametersDisabledFlagList[listMeta.index] !== 1922 productParametersDisabledFlagList[listMeta.index] !==
1923 - false || optType('after-sales-check') 1923 + false || optType('after-sales-check')
1924 } 1924 }
1925 rules={[{ required: true, message: '商品单位必填' }]} 1925 rules={[{ required: true, message: '商品单位必填' }]}
1926 />, 1926 />,
src/pages/Order/Order/components/UploadPayBillModal.tsx
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postServiceOrderFileProcess,
  4 + postServiceOrderUploadPaymentReceipt,
  5 +} from '@/services';
  6 +import { transImageFile } from '@/utils';
  7 +import { PlusOutlined } from '@ant-design/icons';
1 import { ModalForm } from '@ant-design/pro-components'; 8 import { ModalForm } from '@ant-design/pro-components';
2 import { Form, Modal, Upload, UploadFile, UploadProps, message } from 'antd'; 9 import { Form, Modal, Upload, UploadFile, UploadProps, message } from 'antd';
3 import { RcFile } from 'antd/lib/upload'; 10 import { RcFile } from 'antd/lib/upload';
4 import { cloneDeep } from 'lodash'; 11 import { cloneDeep } from 'lodash';
5 import { useEffect, useRef, useState } from 'react'; 12 import { useEffect, useRef, useState } from 'react';
6 import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant'; 13 import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant';
7 -import { PlusOutlined } from '@ant-design/icons';  
8 -import { transImageFile } from '@/utils';  
9 -import { postServiceOrderFileProcess, postServiceOrderUploadPaymentReceipt } from '@/services';  
10 -import { RESPONSE_CODE } from '@/constants/enum';  
11 14
12 // import { cloneDeep } from 'lodash'; 15 // import { cloneDeep } from 'lodash';
13 export default ({ setVisible, subOrders, mainOrder, onClose }) => { 16 export default ({ setVisible, subOrders, mainOrder, onClose }) => {
@@ -25,7 +28,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -25,7 +28,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
25 reader.onerror = (error) => reject(error); 28 reader.onerror = (error) => reject(error);
26 }); 29 });
27 30
28 - const subOrderIds = subOrders?.map((item: any) => { return item.id }); 31 + const subOrderIds = subOrders?.map((item: any) => {
  32 + return item.id;
  33 + });
29 const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致 34 const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致
30 const handleBeforeUpload = (file: any) => { 35 const handleBeforeUpload = (file: any) => {
31 setFileList([...fileList, file]); 36 setFileList([...fileList, file]);
@@ -80,6 +85,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -80,6 +85,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
80 85
81 if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) { 86 if (filteredArray.length >= COMFIR_RECEIPT_IMAGES_NUMBER) {
82 message.info('发货照片数量不能超过3'); 87 message.info('发货照片数量不能超过3');
  88 + console.log(mainOrder);
83 return; 89 return;
84 } 90 }
85 fileListObj.current = filteredArray; 91 fileListObj.current = filteredArray;
@@ -105,8 +111,8 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -105,8 +111,8 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
105 setPreviewOpen(true); 111 setPreviewOpen(true);
106 setPreviewTitle( 112 setPreviewTitle(
107 file.name || 113 file.name ||
108 - file.originFileObj?.name ||  
109 - file.url!.substring(file.url!.lastIndexOf('/') + 1), 114 + file.originFileObj?.name ||
  115 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
110 ); 116 );
111 }; 117 };
112 const props: UploadProps = { 118 const props: UploadProps = {
@@ -128,7 +134,6 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -128,7 +134,6 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
128 }; 134 };
129 135
130 useEffect(() => { 136 useEffect(() => {
131 -  
132 document.addEventListener('paste', onPaste); 137 document.addEventListener('paste', onPaste);
133 return () => { 138 return () => {
134 document.removeEventListener('paste', onPaste); 139 document.removeEventListener('paste', onPaste);
@@ -211,14 +216,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -211,14 +216,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
211 }} 216 }}
212 onOpenChange={setVisible} 217 onOpenChange={setVisible}
213 > 218 >
214 -  
215 - <div className="pb-4 text-xs decoration-gray-50">  
216 - 可复制照片粘贴  
217 - </div> 219 + <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div>
218 <Upload {...props}> 220 <Upload {...props}>
219 - {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER  
220 - ? uploadButton  
221 - : ''} 221 + {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER ? uploadButton : ''}
222 </Upload> 222 </Upload>
223 </ModalForm> 223 </ModalForm>
224 224
src/pages/Order/Order/index.css
1 .order-page-container .ant-table .ant-table-middle { 1 .order-page-container .ant-table .ant-table-middle {
2 margin-inline: 0 !important; 2 margin-inline: 0 !important;
3 } 3 }
  4 +
4 .order-page-container td { 5 .order-page-container td {
5 - font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', 'WenQuanYi Micro Hei', sans-serif; 6 + font-family: 'San Francisco', 'Helvetica Neue', Helvetica, Arial,
  7 + 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC',
  8 + 'WenQuanYi Micro Hei', sans-serif;
6 font-size: 13px; 9 font-size: 13px;
7 } 10 }
  11 +
8 #total-payment .ant-input-number-group-addon { 12 #total-payment .ant-input-number-group-addon {
9 padding: 0 !important; 13 padding: 0 !important;
10 } 14 }
  15 +
11 .order-page-container table:hover, 16 .order-page-container table:hover,
12 .order-page-container tr:hover, 17 .order-page-container tr:hover,
13 .order-page-container thead:hover { 18 .order-page-container thead:hover {
14 background: none !important; 19 background: none !important;
15 } 20 }
  21 +
16 #main-table .ant-table-tbody > tr.ant-table-row:hover > td { 22 #main-table .ant-table-tbody > tr.ant-table-row:hover > td {
17 background: none !important; 23 background: none !important;
18 } 24 }
  25 +
19 .order-page-container .ant-pro-card { 26 .order-page-container .ant-pro-card {
20 background-color: transparent; 27 background-color: transparent;
21 } 28 }
  29 +
22 #main-table .ant-table-tbody .ant-table-cell { 30 #main-table .ant-table-tbody .ant-table-cell {
23 padding: 10px 0 0; 31 padding: 10px 0 0;
24 } 32 }
  33 +
25 .order-page-container .ant-pagination { 34 .order-page-container .ant-pagination {
26 background-color: #fff !important; 35 background-color: #fff !important;
27 padding: 10px; 36 padding: 10px;
28 border-radius: 8px; 37 border-radius: 8px;
29 } 38 }
  39 +
30 .order-page-container .ant-pro-table .ant-form { 40 .order-page-container .ant-pro-table .ant-form {
31 background-color: #fff; 41 background-color: #fff;
32 border-radius: 8px; 42 border-radius: 8px;
33 } 43 }
  44 +
34 #main-table .ant-table-tbody { 45 #main-table .ant-table-tbody {
35 background-color: #f5f5f5; 46 background-color: #f5f5f5;
36 } 47 }
  48 +
37 .order-page-container .ant-pro-card-body { 49 .order-page-container .ant-pro-card-body {
38 padding: 0 !important; 50 padding: 0 !important;
39 } 51 }
  52 +
40 .order-page-container .ant-table-thead .ant-table-cell { 53 .order-page-container .ant-table-thead .ant-table-cell {
41 background-color: #fff !important; 54 background-color: #fff !important;
42 border-radius: 8px !important; 55 border-radius: 8px !important;
43 } 56 }
  57 +
44 #sub-table tbody td { 58 #sub-table tbody td {
45 padding: 10px 0 !important; 59 padding: 10px 0 !important;
46 } 60 }
  61 +
47 #sub-table tbody tr:first-child td:first-child { 62 #sub-table tbody tr:first-child td:first-child {
48 border-top-left-radius: 8px; 63 border-top-left-radius: 8px;
49 } 64 }
  65 +
50 #sub-table tbody tr:first-child td:nth-child(2) { 66 #sub-table tbody tr:first-child td:nth-child(2) {
51 border-top-right-radius: 8px; 67 border-top-right-radius: 8px;
52 } 68 }
  69 +
53 #sub-table tbody tr:last-child td:first-child { 70 #sub-table tbody tr:last-child td:first-child {
54 border-bottom-left-radius: 8px; 71 border-bottom-left-radius: 8px;
55 } 72 }
  73 +
56 #sub-table tbody tr:last-child td:nth-child(2) { 74 #sub-table tbody tr:last-child td:nth-child(2) {
57 border-bottom-right-radius: 8px; 75 border-bottom-right-radius: 8px;
58 } 76 }
  77 +
59 #sub-table tbody tr td:first-child { 78 #sub-table tbody tr td:first-child {
60 border-top: 1px solid #d7d6d6; 79 border-top: 1px solid #d7d6d6;
  80 +
61 /* 设置行与行之间分割线的颜色 */ 81 /* 设置行与行之间分割线的颜色 */
62 border-bottom: 1px solid #d7d6d6; 82 border-bottom: 1px solid #d7d6d6;
  83 +
63 /* 设置行与行之间分割线的颜色 */ 84 /* 设置行与行之间分割线的颜色 */
64 border-left: 1px solid #d7d6d6; 85 border-left: 1px solid #d7d6d6;
  86 +
65 /* 设置行与行之间分割线的颜色 */ 87 /* 设置行与行之间分割线的颜色 */
66 } 88 }
  89 +
67 #sub-table tbody tr td:nth-child(2) { 90 #sub-table tbody tr td:nth-child(2) {
68 border-top: 1px solid #d7d6d6; 91 border-top: 1px solid #d7d6d6;
  92 +
69 /* 设置行与行之间分割线的颜色 */ 93 /* 设置行与行之间分割线的颜色 */
70 border-bottom: 1px solid #d7d6d6; 94 border-bottom: 1px solid #d7d6d6;
  95 +
71 /* 设置行与行之间分割线的颜色 */ 96 /* 设置行与行之间分割线的颜色 */
72 border-right: 1px solid #d7d6d6; 97 border-right: 1px solid #d7d6d6;
  98 +
73 /* 设置行与行之间分割线的颜色 */ 99 /* 设置行与行之间分割线的颜色 */
74 } 100 }
src/pages/Order/Order/index.tsx
@@ -111,6 +111,7 @@ import CheckModal from &#39;./components/CheckModal&#39;; @@ -111,6 +111,7 @@ import CheckModal from &#39;./components/CheckModal&#39;;
111 import ConfirmReceiptModal from './components/ConfirmReceiptModal'; 111 import ConfirmReceiptModal from './components/ConfirmReceiptModal';
112 import DeliverInfoDrawer from './components/DeliverInfoDrawer'; 112 import DeliverInfoDrawer from './components/DeliverInfoDrawer';
113 import DeliverModal from './components/DeliverModal'; 113 import DeliverModal from './components/DeliverModal';
  114 +import FeedbackRegistrationModal from './components/FeedbackRegistrationModal';
114 import FinancialDrawer from './components/FinancialDrawer'; 115 import FinancialDrawer from './components/FinancialDrawer';
115 import FinancialEditDrawer from './components/FinancialEditDrawer'; 116 import FinancialEditDrawer from './components/FinancialEditDrawer';
116 import FinancialMergeDrawer from './components/FinancialMergeDrawer'; 117 import FinancialMergeDrawer from './components/FinancialMergeDrawer';
@@ -146,6 +147,10 @@ const OrderPage = () =&gt; { @@ -146,6 +147,10 @@ const OrderPage = () =&gt; {
146 useState<boolean>(false); 147 useState<boolean>(false);
147 const [uploadPayBillModalVisible, setUploadPayBillModalVisible] = 148 const [uploadPayBillModalVisible, setUploadPayBillModalVisible] =
148 useState<boolean>(false); 149 useState<boolean>(false);
  150 + const [
  151 + feedbackRegistrationModalVisible,
  152 + setFeedbackRegistrationModalVisible,
  153 + ] = useState<boolean>(false);
149 const [modifiedDiffModalVisible, setModifiedDiffModalVisible] = 154 const [modifiedDiffModalVisible, setModifiedDiffModalVisible] =
150 useState<boolean>(false); 155 useState<boolean>(false);
151 const [financialReceiptsModalVisible, setFinancialReceiptsModalVisible] = 156 const [financialReceiptsModalVisible, setFinancialReceiptsModalVisible] =
@@ -690,7 +695,7 @@ const OrderPage = () =&gt; { @@ -690,7 +695,7 @@ const OrderPage = () =&gt; {
690 * @param optRecord 695 * @param optRecord
691 */ 696 */
692 function getOrderStatusTag(optRecord: any): import('react').ReactNode { 697 function getOrderStatusTag(optRecord: any): import('react').ReactNode {
693 - console.log(optRecord); 698 + console.log(optRecord, '5656optRecord');
694 699
695 const orderStatus = optRecord.orderStatus; 700 const orderStatus = optRecord.orderStatus;
696 const paymentMethod = optRecord.paymentMethod; 701 const paymentMethod = optRecord.paymentMethod;
@@ -2095,6 +2100,20 @@ const OrderPage = () =&gt; { @@ -2095,6 +2100,20 @@ const OrderPage = () =&gt; {
2095 ) : ( 2100 ) : (
2096 '' 2101 ''
2097 )} 2102 )}
  2103 + {optRecord.paths?.includes('feedbackRegistration') ? (
  2104 + <Button
  2105 + className="p-0"
  2106 + type="link"
  2107 + onClick={() => {
  2108 + createOptObject(optRecord.id, record.id);
  2109 + setFeedbackRegistrationModalVisible(true);
  2110 + }}
  2111 + >
  2112 + 回访登记
  2113 + </Button>
  2114 + ) : (
  2115 + ''
  2116 + )}
2098 2117
2099 {optRecord.paths?.includes('confirmInvoice') ? ( 2118 {optRecord.paths?.includes('confirmInvoice') ? (
2100 <ButtonConfirm 2119 <ButtonConfirm
@@ -2316,6 +2335,31 @@ const OrderPage = () =&gt; { @@ -2316,6 +2335,31 @@ const OrderPage = () =&gt; {
2316 ) : ( 2335 ) : (
2317 '' 2336 ''
2318 )} 2337 )}
  2338 +
  2339 + {isAdmin() || isSales() ? (
  2340 + <Flex title={optRecord.notes} className="pt-2">
  2341 + <div className="flex items-center">
  2342 + <div className="flex items-center max-w-[500px]">
  2343 + <div className="max-w-md overflow-hidden whitespace-no-wrap overflow-ellipsis">
  2344 + <Tooltip
  2345 + title={optRecord.feedbackRegistrationContent}
  2346 + placement="topLeft"
  2347 + >
  2348 + <span className="text-[#8C8C8C] mr-3">
  2349 + 产品回访登记:
  2350 + {optRecord.feedbackRegistrationContent === undefined ||
  2351 + optRecord.feedbackRegistrationContent === null
  2352 + ? '暂无'
  2353 + : optRecord.feedbackRegistrationContent}
  2354 + </span>
  2355 + </Tooltip>
  2356 + </div>
  2357 + </div>
  2358 + </div>
  2359 + </Flex>
  2360 + ) : (
  2361 + ''
  2362 + )}
2319 </> 2363 </>
2320 ); 2364 );
2321 }; 2365 };
@@ -5285,6 +5329,24 @@ const OrderPage = () =&gt; { @@ -5285,6 +5329,24 @@ const OrderPage = () =&gt; {
5285 }} 5329 }}
5286 /> 5330 />
5287 )} 5331 )}
  5332 + {feedbackRegistrationModalVisible && (
  5333 + <FeedbackRegistrationModal
  5334 + setVisible={(val: boolean) => {
  5335 + setFeedbackRegistrationModalVisible(val);
  5336 + if (!val) {
  5337 + clearOptObject();
  5338 + }
  5339 + }}
  5340 + subOrders={buildSubOrders()}
  5341 + mainOrder={buildMainOrder()}
  5342 + onClose={() => {
  5343 + setFeedbackRegistrationModalVisible(false);
  5344 + clearOptObject();
  5345 + refreshTable();
  5346 + }}
  5347 + />
  5348 + )}
  5349 +
5288 {invoicingDrawerFormVisible && ( 5350 {invoicingDrawerFormVisible && (
5289 <InvoicingDrawerForm 5351 <InvoicingDrawerForm
5290 dataList={ 5352 dataList={
src/pages/Order/OrderWarning/components/CheckModal.tsx
@@ -235,8 +235,8 @@ export default ({ @@ -235,8 +235,8 @@ export default ({
235 setPreviewOpen(true); 235 setPreviewOpen(true);
236 setPreviewTitle( 236 setPreviewTitle(
237 file.name || 237 file.name ||
238 - file.originFileObj?.name ||  
239 - file.url!.substring(file.url!.lastIndexOf('/') + 1), 238 + file.originFileObj?.name ||
  239 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
240 ); 240 );
241 }; 241 };
242 242
src/pages/Order/OrderWarning/components/ConfirmReceiptModal.tsx
@@ -107,8 +107,8 @@ export default ({ data, onClose }) =&gt; { @@ -107,8 +107,8 @@ export default ({ data, onClose }) =&gt; {
107 setPreviewOpen(true); 107 setPreviewOpen(true);
108 setPreviewTitle( 108 setPreviewTitle(
109 file.name || 109 file.name ||
110 - file.originFileObj?.name ||  
111 - file.url!.substring(file.url!.lastIndexOf('/') + 1), 110 + file.originFileObj?.name ||
  111 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
112 ); 112 );
113 }; 113 };
114 114
src/pages/Order/OrderWarning/components/DeliverModal.tsx
@@ -260,7 +260,7 @@ const DeliverModal = ({ @@ -260,7 +260,7 @@ const DeliverModal = ({
260 serialNumber: item.serialNumber, 260 serialNumber: item.serialNumber,
261 packageNumber: 261 packageNumber:
262 item.packageNumber === null || 262 item.packageNumber === null ||
263 - item.packageNumber === undefined 263 + item.packageNumber === undefined
264 ? 1 264 ? 1
265 : item.packageNumber, 265 : item.packageNumber,
266 logisticsNotes: item.logisticsNotes, 266 logisticsNotes: item.logisticsNotes,
src/pages/Order/OrderWarning/components/FeedbackRegistrationModal.tsx 0 → 100644
  1 +import { postServiceOrderFeedbackRegistration } from '@/services/request';
  2 +import { Input, Modal } from 'antd';
  3 +import { useState } from 'react';
  4 +
  5 +// import { cloneDeep } from 'lodash';
  6 +export default ({ subOrders, onClose }) => {
  7 + const [isModalOpen] = useState(true);
  8 + const { TextArea } = Input;
  9 + const [textValue, setTextValue] = useState('');
  10 +
  11 + const handleOk = async () => {
  12 + console.log(textValue); // 处理输入的文本
  13 + console.log(subOrders, '5656subOrders');
  14 + let res = await postServiceOrderFeedbackRegistration({
  15 + data: {
  16 + id: subOrders[0].id,
  17 + feedbackRegistrationContent: textValue,
  18 + },
  19 + });
  20 + console.log(res, '5656res');
  21 + onClose();
  22 + // setIsModalOpen(false);
  23 + // onClose();
  24 + };
  25 + const handleCancel = () => {
  26 + onClose();
  27 + // setIsModalOpen(false);
  28 + // onClose();
  29 + };
  30 + const handleChange = (e) => {
  31 + setTextValue(e.target.value);
  32 + };
  33 + return (
  34 + <>
  35 + {/* <ModalForm<{
  36 + filePaths: any;
  37 + }>
  38 + width={500}
  39 + open
  40 + title="回访登记"
  41 + form={form}
  42 + autoFocusFirstInput
  43 + modalProps={{
  44 + okText: '提交',
  45 + cancelText: '取消',
  46 + destroyOnClose: true,
  47 + onCancel: () => {
  48 + setVisible(false);
  49 + },
  50 + }}
  51 + onFinish={async () => {
  52 + onClose();
  53 + }}
  54 + onOpenChange={setVisible}
  55 + >
  56 + <TextArea rows={6} placeholder="请输入" />
  57 + </ModalForm> */}
  58 + <Modal
  59 + title="回访登记"
  60 + open={isModalOpen}
  61 + onOk={handleOk}
  62 + onCancel={handleCancel}
  63 + >
  64 + <TextArea
  65 + rows={6}
  66 + placeholder="请输入"
  67 + onChange={handleChange}
  68 + value={textValue}
  69 + />
  70 + </Modal>
  71 + </>
  72 + );
  73 +};
src/pages/Order/OrderWarning/components/FinancialDrawer.tsx
@@ -144,107 +144,107 @@ export default ({ @@ -144,107 +144,107 @@ export default ({
144 144
145 {invoicingStatus !== 'UN_INVOICE' 145 {invoicingStatus !== 'UN_INVOICE'
146 ? [ 146 ? [
147 - <ProFormDatePicker  
148 - key="invoicingTime"  
149 - width="lg"  
150 - name="invoicingTime"  
151 - label="开票时间"  
152 - disabled={isEdit}  
153 - rules={[  
154 - { required: !isEdit ? true : false, message: '这是必填项' },  
155 - ]}  
156 - initialValue={subOrders[0]?.invoicingTime}  
157 - />,  
158 - <ProFormText  
159 - key="purchaser"  
160 - width="lg"  
161 - name="purchaser"  
162 - label="抬头名称"  
163 - disabled={isEdit}  
164 - rules={[  
165 - { required: !isEdit ? true : false, message: '这是必填项' },  
166 - ]}  
167 - initialValue={subOrders[0]?.purchaser}  
168 - />,  
169 - <ProFormDatePicker  
170 - key="financialReceiptIssuanceTime"  
171 - width="lg"  
172 - name="financialReceiptIssuanceTime"  
173 - label="开收据时间"  
174 - initialValue={subOrders[0]?.financialReceiptIssuanceTime}  
175 - />,  
176 - <ProFormDatePicker  
177 - key="collectMoneyTime"  
178 - width="lg"  
179 - name="collectMoneyTime"  
180 - label="收款时间"  
181 - initialValue={subOrders[0]?.collectMoneyTime}  
182 - />,  
183 - <ProFormText  
184 - width="lg"  
185 - key="invoiceNumber"  
186 - name="invoiceNumber"  
187 - label="发票号码"  
188 - initialValue={subOrders[0]?.invoiceNumber}  
189 - rules={[{ required: true, message: '发票号码必填' }]}  
190 - />,  
191 - <div  
192 - key="salesChooseReceivingCompany"  
193 - hidden={subOrders[0].receivingCompany === null}  
194 - >  
195 - <span className={'pl-2 text-xs text-gray-400'}>  
196 - 销售申请开票时选择了:  
197 - {enumValueToLabel(  
198 - subOrders[0].receivingCompany,  
199 - getReceivingCompanyOptions(PAYEE_OPTIONS),  
200 - )}  
201 - </span>  
202 - <span  
203 - hidden={subOrders[0].receivingCompany === 'ANY'}  
204 - className={  
205 - 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'  
206 - }  
207 - onClick={() => {  
208 - chooseReceivingCompany(subOrders[0].receivingCompany);  
209 - }} 147 + <ProFormDatePicker
  148 + key="invoicingTime"
  149 + width="lg"
  150 + name="invoicingTime"
  151 + label="开票时间"
  152 + disabled={isEdit}
  153 + rules={[
  154 + { required: !isEdit ? true : false, message: '这是必填项' },
  155 + ]}
  156 + initialValue={subOrders[0]?.invoicingTime}
  157 + />,
  158 + <ProFormText
  159 + key="purchaser"
  160 + width="lg"
  161 + name="purchaser"
  162 + label="抬头名称"
  163 + disabled={isEdit}
  164 + rules={[
  165 + { required: !isEdit ? true : false, message: '这是必填项' },
  166 + ]}
  167 + initialValue={subOrders[0]?.purchaser}
  168 + />,
  169 + <ProFormDatePicker
  170 + key="financialReceiptIssuanceTime"
  171 + width="lg"
  172 + name="financialReceiptIssuanceTime"
  173 + label="开收据时间"
  174 + initialValue={subOrders[0]?.financialReceiptIssuanceTime}
  175 + />,
  176 + <ProFormDatePicker
  177 + key="collectMoneyTime"
  178 + width="lg"
  179 + name="collectMoneyTime"
  180 + label="收款时间"
  181 + initialValue={subOrders[0]?.collectMoneyTime}
  182 + />,
  183 + <ProFormText
  184 + width="lg"
  185 + key="invoiceNumber"
  186 + name="invoiceNumber"
  187 + label="发票号码"
  188 + initialValue={subOrders[0]?.invoiceNumber}
  189 + rules={[{ required: true, message: '发票号码必填' }]}
  190 + />,
  191 + <div
  192 + key="salesChooseReceivingCompany"
  193 + hidden={subOrders[0].receivingCompany === null}
210 > 194 >
211 - 选择  
212 - </span>  
213 - </div>,  
214 - <ProFormSelect  
215 - key="payee"  
216 - placeholder="选择收款单位"  
217 - name="payee"  
218 - width="lg"  
219 - showSearch  
220 - label="收款单位"  
221 - options={enumToSelect(PAYEE_OPTIONS)}  
222 - initialValue={subOrders[0]?.payee}  
223 - rules={[{ required: true, message: '收款单位必填' }]}  
224 - />,  
225 -  
226 - <div id="total-payment" key="money">  
227 - <ProFormDigit  
228 - key="money"  
229 - name="money" 195 + <span className={'pl-2 text-xs text-gray-400'}>
  196 + 销售申请开票时选择了:
  197 + {enumValueToLabel(
  198 + subOrders[0].receivingCompany,
  199 + getReceivingCompanyOptions(PAYEE_OPTIONS),
  200 + )}
  201 + </span>
  202 + <span
  203 + hidden={subOrders[0].receivingCompany === 'ANY'}
  204 + className={
  205 + 'pl-2 text-xs text-[#1677ff] cursor-pointer hover:text-[#64abf7]'
  206 + }
  207 + onClick={() => {
  208 + chooseReceivingCompany(subOrders[0].receivingCompany);
  209 + }}
  210 + >
  211 + 选择
  212 + </span>
  213 + </div>,
  214 + <ProFormSelect
  215 + key="payee"
  216 + placeholder="选择收款单位"
  217 + name="payee"
230 width="lg" 218 width="lg"
231 - label="金额"  
232 - rules={[{ required: true, message: '金额必填' }]}  
233 - tooltip="点击计算,合计所有子订单对应主订单总额"  
234 - fieldProps={{  
235 - addonAfter: (  
236 - <Button  
237 - className="rounded-l-none"  
238 - type="primary"  
239 - onClick={computeTotalPayment}  
240 - >  
241 - 计算  
242 - </Button>  
243 - ),  
244 - }}  
245 - />  
246 - </div>,  
247 - ] 219 + showSearch
  220 + label="收款单位"
  221 + options={enumToSelect(PAYEE_OPTIONS)}
  222 + initialValue={subOrders[0]?.payee}
  223 + rules={[{ required: true, message: '收款单位必填' }]}
  224 + />,
  225 +
  226 + <div id="total-payment" key="money">
  227 + <ProFormDigit
  228 + key="money"
  229 + name="money"
  230 + width="lg"
  231 + label="金额"
  232 + rules={[{ required: true, message: '金额必填' }]}
  233 + tooltip="点击计算,合计所有子订单对应主订单总额"
  234 + fieldProps={{
  235 + addonAfter: (
  236 + <Button
  237 + className="rounded-l-none"
  238 + type="primary"
  239 + onClick={computeTotalPayment}
  240 + >
  241 + 计算
  242 + </Button>
  243 + ),
  244 + }}
  245 + />
  246 + </div>,
  247 + ]
248 : ''} 248 : ''}
249 249
250 <ProFormSelect 250 <ProFormSelect
src/pages/Order/OrderWarning/components/FinancialEditDrawer.tsx
@@ -130,24 +130,24 @@ export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) =&gt; { @@ -130,24 +130,24 @@ export default ({ mainOrder, subOrders, setVisible, isMainOrder, onClose }) =&gt; {
130 width="lg" 130 width="lg"
131 name="financialReceiptIssuanceTime" 131 name="financialReceiptIssuanceTime"
132 label="开收据时间" 132 label="开收据时间"
133 - // rules={[  
134 - // {  
135 - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',  
136 - // message: '开收据时间必填',  
137 - // },  
138 - // ]} 133 + // rules={[
  134 + // {
  135 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  136 + // message: '开收据时间必填',
  137 + // },
  138 + // ]}
139 /> 139 />
140 <ProFormDatePicker 140 <ProFormDatePicker
141 key="collectMoneyTime" 141 key="collectMoneyTime"
142 width="lg" 142 width="lg"
143 name="collectMoneyTime" 143 name="collectMoneyTime"
144 label="收款时间" 144 label="收款时间"
145 - // rules={[  
146 - // {  
147 - // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',  
148 - // message: '收款时间必填',  
149 - // },  
150 - // ]} 145 + // rules={[
  146 + // {
  147 + // required: !isMainOrder && invoicingStatus === 'UN_INVOICE',
  148 + // message: '收款时间必填',
  149 + // },
  150 + // ]}
151 /> 151 />
152 </DrawerForm> 152 </DrawerForm>
153 ); 153 );
src/pages/Order/OrderWarning/components/ImagesViewerModal.tsx
@@ -3,7 +3,7 @@ import { Button, Divider, Image, Modal } from &#39;antd&#39;; @@ -3,7 +3,7 @@ import { Button, Divider, Image, Modal } from &#39;antd&#39;;
3 import { useEffect, useState } from 'react'; 3 import { useEffect, useState } from 'react';
4 export default ({ setVisible, optType, onClose, orderRow }) => { 4 export default ({ setVisible, optType, onClose, orderRow }) => {
5 const [images, setImages] = useState<any[]>([]); 5 const [images, setImages] = useState<any[]>([]);
6 - const [title, setTitle] = useState("收货凭证"); 6 + const [title, setTitle] = useState('收货凭证');
7 const handleOk = () => { 7 const handleOk = () => {
8 onClose(); 8 onClose();
9 setVisible(false); 9 setVisible(false);
@@ -23,7 +23,7 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; { @@ -23,7 +23,7 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; {
23 } 23 }
24 useEffect(() => { 24 useEffect(() => {
25 if (optType === 'shippingReceipt') { 25 if (optType === 'shippingReceipt') {
26 - setTitle("收货凭证"); 26 + setTitle('收货凭证');
27 getImages(); 27 getImages();
28 } else if (optType === 'paymentReceipt') { 28 } else if (optType === 'paymentReceipt') {
29 let paymentReceiptsImagesList: any[] = []; 29 let paymentReceiptsImagesList: any[] = [];
@@ -34,7 +34,6 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; { @@ -34,7 +34,6 @@ export default ({ setVisible, optType, onClose, orderRow }) =&gt; {
34 paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)]; 34 paymentReceiptsImagesList = [...new Set(paymentReceiptsImagesList)];
35 setImages(paymentReceiptsImagesList); 35 setImages(paymentReceiptsImagesList);
36 } 36 }
37 -  
38 }, []); 37 }, []);
39 38
40 return ( 39 return (
src/pages/Order/OrderWarning/components/ModifiedDiffModal.tsx
@@ -106,7 +106,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -106,7 +106,7 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
106 onClick={() => { 106 onClick={() => {
107 window.open( 107 window.open(
108 '/previewApi/onlinePreview?url=' + 108 '/previewApi/onlinePreview?url=' +
109 - encodeURIComponent(Base64.encode(item)), 109 + encodeURIComponent(Base64.encode(item)),
110 ); 110 );
111 }} 111 }}
112 > 112 >
src/pages/Order/OrderWarning/components/OrderDrawer.tsx
@@ -556,9 +556,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -556,9 +556,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
556 form.setFieldValue( 556 form.setFieldValue(
557 'customerShippingAddress', 557 'customerShippingAddress',
558 getDefaultString(option.province) + 558 getDefaultString(option.province) +
559 - getDefaultString(option.city) +  
560 - getDefaultString(option.district) +  
561 - getDefaultString(option.detail), 559 + getDefaultString(option.city) +
  560 + getDefaultString(option.district) +
  561 + getDefaultString(option.detail),
562 ); 562 );
563 form.setFieldValue('customerNameString', option.realName); 563 form.setFieldValue('customerNameString', option.realName);
564 564
@@ -641,11 +641,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -641,11 +641,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
641 641
642 message.error( 642 message.error(
643 '用户余额不足,当前预减的金额为:' + 643 '用户余额不足,当前预减的金额为:' +
644 - data.subPrice +  
645 - ',当前账号余额为:' +  
646 - data.nowMoney +  
647 - ',当前账号可赊账额度为:' +  
648 - data.creditLimit, 644 + data.subPrice +
  645 + ',当前账号余额为:' +
  646 + data.nowMoney +
  647 + ',当前账号可赊账额度为:' +
  648 + data.creditLimit,
649 ); 649 );
650 return false; 650 return false;
651 } 651 }
@@ -1110,7 +1110,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1110,7 +1110,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1110 }, 1110 },
1111 }} 1111 }}
1112 debounceTime={1000} 1112 debounceTime={1000}
1113 - request={async (value, { }) => { 1113 + request={async (value, {}) => {
1114 const keywords = value.keyWords; 1114 const keywords = value.keyWords;
1115 if (keywords === '') { 1115 if (keywords === '') {
1116 return []; 1116 return [];
@@ -1865,7 +1865,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1865,7 +1865,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1865 placeholder="请输入商品参数" 1865 placeholder="请输入商品参数"
1866 disabled={ 1866 disabled={
1867 productParametersDisabledFlagList[listMeta.index] !== 1867 productParametersDisabledFlagList[listMeta.index] !==
1868 - false || optType('after-sales-check') 1868 + false || optType('after-sales-check')
1869 } 1869 }
1870 />, 1870 />,
1871 <ProFormDigit 1871 <ProFormDigit
@@ -1918,7 +1918,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; { @@ -1918,7 +1918,7 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1918 placeholder="请输入商品单位" 1918 placeholder="请输入商品单位"
1919 disabled={ 1919 disabled={
1920 productParametersDisabledFlagList[listMeta.index] !== 1920 productParametersDisabledFlagList[listMeta.index] !==
1921 - false || optType('after-sales-check') 1921 + false || optType('after-sales-check')
1922 } 1922 }
1923 rules={[{ required: true, message: '商品单位必填' }]} 1923 rules={[{ required: true, message: '商品单位必填' }]}
1924 />, 1924 />,
src/pages/Order/OrderWarning/components/UploadPayBillModal.tsx
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postServiceOrderFileProcess,
  4 + postServiceOrderUploadPaymentReceipt,
  5 +} from '@/services';
  6 +import { transImageFile } from '@/utils';
  7 +import { PlusOutlined } from '@ant-design/icons';
1 import { ModalForm } from '@ant-design/pro-components'; 8 import { ModalForm } from '@ant-design/pro-components';
2 import { Form, Modal, Upload, UploadFile, UploadProps, message } from 'antd'; 9 import { Form, Modal, Upload, UploadFile, UploadProps, message } from 'antd';
3 import { RcFile } from 'antd/lib/upload'; 10 import { RcFile } from 'antd/lib/upload';
4 import { cloneDeep } from 'lodash'; 11 import { cloneDeep } from 'lodash';
5 import { useEffect, useRef, useState } from 'react'; 12 import { useEffect, useRef, useState } from 'react';
6 import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant'; 13 import { COMFIR_RECEIPT_IMAGES_NUMBER } from '../../constant';
7 -import { PlusOutlined } from '@ant-design/icons';  
8 -import { transImageFile } from '@/utils';  
9 -import { postServiceOrderFileProcess, postServiceOrderUploadPaymentReceipt } from '@/services';  
10 -import { RESPONSE_CODE } from '@/constants/enum';  
11 14
12 // import { cloneDeep } from 'lodash'; 15 // import { cloneDeep } from 'lodash';
13 export default ({ setVisible, subOrders, mainOrder, onClose }) => { 16 export default ({ setVisible, subOrders, mainOrder, onClose }) => {
@@ -25,7 +28,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -25,7 +28,9 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
25 reader.onerror = (error) => reject(error); 28 reader.onerror = (error) => reject(error);
26 }); 29 });
27 30
28 - const subOrderIds = subOrders?.map((item: any) => { return item.id }); 31 + const subOrderIds = subOrders?.map((item: any) => {
  32 + return item.id;
  33 + });
29 const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致 34 const fileListObj = useRef<UploadFile[]>([]); //使用引用类型,使得在useEffect里面设置监听事件后,不用更新监听事件也能保持obj与外界一致
30 const handleBeforeUpload = (file: any) => { 35 const handleBeforeUpload = (file: any) => {
31 setFileList([...fileList, file]); 36 setFileList([...fileList, file]);
@@ -105,8 +110,8 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -105,8 +110,8 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
105 setPreviewOpen(true); 110 setPreviewOpen(true);
106 setPreviewTitle( 111 setPreviewTitle(
107 file.name || 112 file.name ||
108 - file.originFileObj?.name ||  
109 - file.url!.substring(file.url!.lastIndexOf('/') + 1), 113 + file.originFileObj?.name ||
  114 + file.url!.substring(file.url!.lastIndexOf('/') + 1),
110 ); 115 );
111 }; 116 };
112 const props: UploadProps = { 117 const props: UploadProps = {
@@ -128,7 +133,6 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -128,7 +133,6 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
128 }; 133 };
129 134
130 useEffect(() => { 135 useEffect(() => {
131 -  
132 document.addEventListener('paste', onPaste); 136 document.addEventListener('paste', onPaste);
133 return () => { 137 return () => {
134 document.removeEventListener('paste', onPaste); 138 document.removeEventListener('paste', onPaste);
@@ -206,19 +210,15 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; { @@ -206,19 +210,15 @@ export default ({ setVisible, subOrders, mainOrder, onClose }) =&gt; {
206 } 210 }
207 } else { 211 } else {
208 message.success('上传失败'); 212 message.success('上传失败');
  213 + console.log(mainOrder);
209 } 214 }
210 onClose(); 215 onClose();
211 }} 216 }}
212 onOpenChange={setVisible} 217 onOpenChange={setVisible}
213 > 218 >
214 -  
215 - <div className="pb-4 text-xs decoration-gray-50">  
216 - 可复制照片粘贴  
217 - </div> 219 + <div className="pb-4 text-xs decoration-gray-50">可复制照片粘贴</div>
218 <Upload {...props}> 220 <Upload {...props}>
219 - {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER  
220 - ? uploadButton  
221 - : ''} 221 + {fileList.length < COMFIR_RECEIPT_IMAGES_NUMBER ? uploadButton : ''}
222 </Upload> 222 </Upload>
223 </ModalForm> 223 </ModalForm>
224 224
src/pages/Order/OrderWarning/index.tsx
@@ -103,6 +103,7 @@ import CheckModal from &#39;./components/CheckModal&#39;; @@ -103,6 +103,7 @@ import CheckModal from &#39;./components/CheckModal&#39;;
103 import ConfirmReceiptModal from './components/ConfirmReceiptModal'; 103 import ConfirmReceiptModal from './components/ConfirmReceiptModal';
104 import DeliverInfoDrawer from './components/DeliverInfoDrawer'; 104 import DeliverInfoDrawer from './components/DeliverInfoDrawer';
105 import DeliverModal from './components/DeliverModal'; 105 import DeliverModal from './components/DeliverModal';
  106 +import FeedbackRegistrationModal from './components/FeedbackRegistrationModal';
106 import FinancialDrawer from './components/FinancialDrawer'; 107 import FinancialDrawer from './components/FinancialDrawer';
107 import FinancialEditDrawer from './components/FinancialEditDrawer'; 108 import FinancialEditDrawer from './components/FinancialEditDrawer';
108 import FinancialMergeDrawer from './components/FinancialMergeDrawer'; 109 import FinancialMergeDrawer from './components/FinancialMergeDrawer';
@@ -136,6 +137,10 @@ const OrderPage = () =&gt; { @@ -136,6 +137,10 @@ const OrderPage = () =&gt; {
136 useState<boolean>(false); 137 useState<boolean>(false);
137 const [uploadPayBillModalVisible, setUploadPayBillModalVisible] = 138 const [uploadPayBillModalVisible, setUploadPayBillModalVisible] =
138 useState<boolean>(false); 139 useState<boolean>(false);
  140 + const [
  141 + feedbackRegistrationModalVisible,
  142 + setFeedbackRegistrationModalVisible,
  143 + ] = useState<boolean>(false);
139 const [modifiedDiffModalVisible, setModifiedDiffModalVisible] = 144 const [modifiedDiffModalVisible, setModifiedDiffModalVisible] =
140 useState<boolean>(false); 145 useState<boolean>(false);
141 const [financialReceiptsModalVisible, setFinancialReceiptsModalVisible] = 146 const [financialReceiptsModalVisible, setFinancialReceiptsModalVisible] =
@@ -2255,6 +2260,30 @@ const OrderPage = () =&gt; { @@ -2255,6 +2260,30 @@ const OrderPage = () =&gt; {
2255 ) : ( 2260 ) : (
2256 '' 2261 ''
2257 )} 2262 )}
  2263 + {isAdmin() || isSales() ? (
  2264 + <Flex title={optRecord.notes} className="pt-2">
  2265 + <div className="flex items-center">
  2266 + <div className="flex items-center max-w-[500px]">
  2267 + <div className="max-w-md overflow-hidden whitespace-no-wrap overflow-ellipsis">
  2268 + <Tooltip
  2269 + title={optRecord.feedbackRegistrationContent}
  2270 + placement="topLeft"
  2271 + >
  2272 + <span className="text-[#8C8C8C] mr-3">
  2273 + 产品回访登记:
  2274 + {optRecord.feedbackRegistrationContent === undefined ||
  2275 + optRecord.feedbackRegistrationContent === null
  2276 + ? '暂无'
  2277 + : optRecord.feedbackRegistrationContent}
  2278 + </span>
  2279 + </Tooltip>
  2280 + </div>
  2281 + </div>
  2282 + </div>
  2283 + </Flex>
  2284 + ) : (
  2285 + ''
  2286 + )}
2258 </> 2287 </>
2259 ); 2288 );
2260 }; 2289 };
@@ -4980,6 +5009,23 @@ const OrderPage = () =&gt; { @@ -4980,6 +5009,23 @@ const OrderPage = () =&gt; {
4980 }} 5009 }}
4981 /> 5010 />
4982 )} 5011 )}
  5012 + {feedbackRegistrationModalVisible && (
  5013 + <FeedbackRegistrationModal
  5014 + setVisible={(val: boolean) => {
  5015 + setFeedbackRegistrationModalVisible(val);
  5016 + if (!val) {
  5017 + clearOptObject();
  5018 + }
  5019 + }}
  5020 + subOrders={buildSubOrders()}
  5021 + mainOrder={buildMainOrder()}
  5022 + onClose={() => {
  5023 + setFeedbackRegistrationModalVisible(false);
  5024 + clearOptObject();
  5025 + refreshTable();
  5026 + }}
  5027 + />
  5028 + )}
4983 {invoicingDrawerFormVisible && ( 5029 {invoicingDrawerFormVisible && (
4984 <InvoicingDrawerForm 5030 <InvoicingDrawerForm
4985 dataList={ 5031 dataList={
@@ -5552,6 +5598,23 @@ const OrderPage = () =&gt; { @@ -5552,6 +5598,23 @@ const OrderPage = () =&gt; {
5552 }} 5598 }}
5553 /> 5599 />
5554 )} 5600 )}
  5601 + {feedbackRegistrationModalVisible && (
  5602 + <FeedbackRegistrationModal
  5603 + setVisible={(val: boolean) => {
  5604 + setFeedbackRegistrationModalVisible(val);
  5605 + if (!val) {
  5606 + clearOptObject();
  5607 + }
  5608 + }}
  5609 + subOrders={buildSubOrders()}
  5610 + mainOrder={buildMainOrder()}
  5611 + onClose={() => {
  5612 + setFeedbackRegistrationModalVisible(false);
  5613 + clearOptObject();
  5614 + refreshTable2();
  5615 + }}
  5616 + />
  5617 + )}
5555 {invoicingDrawerFormVisible && ( 5618 {invoicingDrawerFormVisible && (
5556 <InvoicingDrawerForm 5619 <InvoicingDrawerForm
5557 dataList={ 5620 dataList={
src/pages/Order/WarningWhitelist/index.css deleted 100644 → 0
src/pages/Order/WarningWhitelist/index.less deleted 100644 → 0
src/pages/Order/WarningWhitelist/index.tsx
1 -import {  
2 - ActionType,  
3 - ModalForm,  
4 - ProColumns,  
5 - ProFormText,  
6 - ProTable,  
7 -} from '@ant-design/pro-components';  
8 -import {  
9 - Button,  
10 - Checkbox,  
11 - Divider,  
12 - Dropdown,  
13 - Flex,  
14 - FloatButton,  
15 - Image,  
16 - MenuProps,  
17 - Modal,  
18 - Popconfirm,  
19 - Radio,  
20 - Space,  
21 - Spin,  
22 - Tag,  
23 - Tooltip,  
24 - message,  
25 - Tabs,  
26 -} from 'antd';  
27 import ButtonConfirm from '@/components/ButtomConfirm'; 1 import ButtonConfirm from '@/components/ButtomConfirm';
28 import { RESPONSE_CODE } from '@/constants/enum'; 2 import { RESPONSE_CODE } from '@/constants/enum';
29 import { 3 import {
30 - postOldInvoicingWhiteListBatchAdd,  
31 - postOldInvoicingWhiteListPage,  
32 - postOldInvoicingWhiteListRemove,  
33 - postServiceOrderWarningUserWhiteLists, 4 + postServiceOrderAddWarningOrderWhiteList,
34 postServiceOrderAddWarningUserWhiteList, 5 postServiceOrderAddWarningUserWhiteList,
  6 + postServiceOrderDeleteWarningOrderWhiteList,
35 postServiceOrderDeleteWarningUserWhiteList, 7 postServiceOrderDeleteWarningUserWhiteList,
36 postServiceOrderWarningOrderWhiteLists, 8 postServiceOrderWarningOrderWhiteLists,
37 - postServiceOrderAddWarningOrderWhiteList,  
38 - postServiceOrderDeleteWarningOrderWhiteList, 9 + postServiceOrderWarningUserWhiteLists,
39 } from '@/services'; 10 } from '@/services';
40 import { PlusOutlined } from '@ant-design/icons'; 11 import { PlusOutlined } from '@ant-design/icons';
  12 +import {
  13 + ActionType,
  14 + ModalForm,
  15 + ProColumns,
  16 + ProFormText,
  17 + ProTable,
  18 +} from '@ant-design/pro-components';
  19 +import { Button, Tabs, message } from 'antd';
41 import { useRef } from 'react'; 20 import { useRef } from 'react';
42 export const waitTimePromise = async (time: number = 100) => { 21 export const waitTimePromise = async (time: number = 100) => {
43 return new Promise((resolve) => { 22 return new Promise((resolve) => {
@@ -134,9 +113,9 @@ const WarningWhitelist = () =&gt; { @@ -134,9 +113,9 @@ const WarningWhitelist = () =&gt; {
134 search: { 113 search: {
135 transform: (value) => { 114 transform: (value) => {
136 if (value) { 115 if (value) {
137 - console.log(value, '5656valueid') 116 + console.log(value, '5656valueid');
138 return { 117 return {
139 - orderId: Number(value) 118 + orderId: Number(value),
140 }; 119 };
141 } 120 }
142 }, 121 },
@@ -186,7 +165,7 @@ const WarningWhitelist = () =&gt; { @@ -186,7 +165,7 @@ const WarningWhitelist = () =&gt; {
186 title={'确认删除此项吗?'} 165 title={'确认删除此项吗?'}
187 text="删除" 166 text="删除"
188 onConfirm={async () => { 167 onConfirm={async () => {
189 - console.log(record.orderId, '5656idoreder') 168 + console.log(record.orderId, '5656idoreder');
190 await postServiceOrderDeleteWarningOrderWhiteList({ 169 await postServiceOrderDeleteWarningOrderWhiteList({
191 query: { 170 query: {
192 orderId: record.orderId, 171 orderId: record.orderId,
@@ -213,7 +192,7 @@ const WarningWhitelist = () =&gt; { @@ -213,7 +192,7 @@ const WarningWhitelist = () =&gt; {
213 const res = await postServiceOrderWarningUserWhiteLists({ 192 const res = await postServiceOrderWarningUserWhiteLists({
214 data: { ...params }, 193 data: { ...params },
215 }); 194 });
216 - console.log(res.data, '5656res.data') 195 + console.log(res.data, '5656res.data');
217 return res.data; 196 return res.data;
218 }} 197 }}
219 rowKey="id" 198 rowKey="id"
@@ -281,7 +260,7 @@ const WarningWhitelist = () =&gt; { @@ -281,7 +260,7 @@ const WarningWhitelist = () =&gt; {
281 ]} 260 ]}
282 /> 261 />
283 </div> 262 </div>
284 - ) 263 + ),
285 }, 264 },
286 { 265 {
287 key: 2, 266 key: 2,
@@ -334,7 +313,7 @@ const WarningWhitelist = () =&gt; { @@ -334,7 +313,7 @@ const WarningWhitelist = () =&gt; {
334 console.log(values, '5656values'); 313 console.log(values, '5656values');
335 const res = await postServiceOrderAddWarningOrderWhiteList({ 314 const res = await postServiceOrderAddWarningOrderWhiteList({
336 data: { 315 data: {
337 - orderId: values.orderIdsText 316 + orderId: values.orderIdsText,
338 }, 317 },
339 }); 318 });
340 if (res.result === RESPONSE_CODE.SUCCESS) { 319 if (res.result === RESPONSE_CODE.SUCCESS) {
@@ -361,9 +340,9 @@ const WarningWhitelist = () =&gt; { @@ -361,9 +340,9 @@ const WarningWhitelist = () =&gt; {
361 ]} 340 ]}
362 /> 341 />
363 </div> 342 </div>
364 - )  
365 - }  
366 - ] 343 + ),
  344 + },
  345 + ];
367 return ( 346 return (
368 <div> 347 <div>
369 <Tabs 348 <Tabs
@@ -374,6 +353,6 @@ const WarningWhitelist = () =&gt; { @@ -374,6 +353,6 @@ const WarningWhitelist = () =&gt; {
374 }} 353 }}
375 /> 354 />
376 </div> 355 </div>
377 - )  
378 -}  
379 -export default WarningWhitelist 356 + );
  357 +};
  358 +export default WarningWhitelist;
src/pages/OrderReport/components/OrderStatisticCard.tsx
@@ -310,59 +310,44 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; { @@ -310,59 +310,44 @@ export default ({ data, statisticsMethod, reFreshData }) =&gt; {
310 <ProCard 310 <ProCard
311 className="order-statictis-card" 311 className="order-statictis-card"
312 bordered 312 bordered
313 - title={<CardTitle title='待开票订单' />} 313 + title={<CardTitle title="待开票订单" />}
314 > 314 >
315 - <CardContent  
316 - content={data?.waitInvoicingCount}  
317 - /> 315 + <CardContent content={data?.waitInvoicingCount} />
318 </ProCard> 316 </ProCard>
319 <ProCard 317 <ProCard
320 className="order-statictis-card" 318 className="order-statictis-card"
321 bordered 319 bordered
322 - title={<CardTitle title='待开票订单总金额' />} 320 + title={<CardTitle title="待开票订单总金额" />}
323 > 321 >
324 - <CardContent  
325 - unit="¥"  
326 - content={data?.waitInvoicingPriceSum}  
327 - /> 322 + <CardContent unit="¥" content={data?.waitInvoicingPriceSum} />
328 </ProCard> 323 </ProCard>
329 <ProCard 324 <ProCard
330 className="order-statictis-card" 325 className="order-statictis-card"
331 bordered 326 bordered
332 - title={<CardTitle title='已开票未回款订单' />} 327 + title={<CardTitle title="已开票未回款订单" />}
333 > 328 >
334 - <CardContent  
335 - content={data?.invoicedNotReiceptCount}  
336 - /> 329 + <CardContent content={data?.invoicedNotReiceptCount} />
337 </ProCard> 330 </ProCard>
338 <ProCard 331 <ProCard
339 className="order-statictis-card" 332 className="order-statictis-card"
340 bordered 333 bordered
341 - title={<CardTitle title='已开票未回款订单总金额' />} 334 + title={<CardTitle title="已开票未回款订单总金额" />}
342 > 335 >
343 - <CardContent  
344 - unit="¥"  
345 - content={data?.invoicedNotReiceptPriceSum}  
346 - /> 336 + <CardContent unit="¥" content={data?.invoicedNotReiceptPriceSum} />
347 </ProCard> 337 </ProCard>
348 <ProCard 338 <ProCard
349 className="order-statictis-card" 339 className="order-statictis-card"
350 bordered 340 bordered
351 - title={<CardTitle title='已开票已回款订单' />} 341 + title={<CardTitle title="已开票已回款订单" />}
352 > 342 >
353 - <CardContent  
354 - content={data?.invoicedAndReiceptedCount}  
355 - /> 343 + <CardContent content={data?.invoicedAndReiceptedCount} />
356 </ProCard> 344 </ProCard>
357 <ProCard 345 <ProCard
358 className="order-statictis-card" 346 className="order-statictis-card"
359 bordered 347 bordered
360 - title={<CardTitle title='已开票已回款订单总金额' />} 348 + title={<CardTitle title="已开票已回款订单总金额" />}
361 > 349 >
362 - <CardContent  
363 - unit="¥"  
364 - content={data?.invoicedAndReiceptedPriceSum}  
365 - /> 350 + <CardContent unit="¥" content={data?.invoicedAndReiceptedPriceSum} />
366 </ProCard> 351 </ProCard>
367 </ProCard> 352 </ProCard>
368 353
src/pages/Prepaid/index.tsx
1 import ButtonConfirm from '@/components/ButtomConfirm'; 1 import ButtonConfirm from '@/components/ButtomConfirm';
2 import EllipsisDiv from '@/components/Div/EllipsisDiv'; 2 import EllipsisDiv from '@/components/Div/EllipsisDiv';
3 import { RESPONSE_CODE } from '@/constants/enum'; 3 import { RESPONSE_CODE } from '@/constants/enum';
4 -import { } from '@/pages/Invoice/constant'; 4 +import {} from '@/pages/Invoice/constant';
5 import { 5 import {
6 postCanrdApiUserList, 6 postCanrdApiUserList,
7 postPrepaidDelete, 7 postPrepaidDelete,
src/services/definition.ts
@@ -94,36 +94,33 @@ export interface AdminAuthUserVO { @@ -94,36 +94,33 @@ export interface AdminAuthUserVO {
94 export interface AdminClientDto { 94 export interface AdminClientDto {
95 /** 95 /**
96 * @description 96 * @description
97 - * 市  
98 - */  
99 - city?: string;  
100 - /**  
101 - * @description  
102 - * 单位地址 97 + * 客户地址
103 */ 98 */
104 - companyAddress?: string; 99 + address?: string;
105 /** 100 /**
106 * @description 101 * @description
107 - * 单位地址 102 + *
108 */ 103 */
109 - companyAddressText?: string; 104 + city?: string;
110 companyId?: string; 105 companyId?: string;
111 /** 106 /**
112 * @description 107 * @description
113 - * 单位名称 108 + * 联系人
114 */ 109 */
115 - companyName?: string;  
116 contacts?: string; 110 contacts?: string;
117 - createBy?: string; 111 + createByName?: string;
118 /** @format date-time */ 112 /** @format date-time */
119 createTime?: string; 113 createTime?: string;
120 /** 114 /**
121 * @description 115 * @description
  116 + * 详细地址
  117 + */
  118 + detailAddress?: string;
  119 + /**
  120 + * @description
122 * 区 121 * 区
123 */ 122 */
124 district?: string; 123 district?: string;
125 - /** @format int32 */  
126 - enableFlag?: number;  
127 /** 124 /**
128 * @description 125 * @description
129 * 是否已报方案 126 * 是否已报方案
@@ -144,9 +141,7 @@ export interface AdminClientDto { @@ -144,9 +141,7 @@ export interface AdminClientDto {
144 * 客户等级 141 * 客户等级
145 */ 142 */
146 levelText?: string; 143 levelText?: string;
147 - modifyBy?: string;  
148 - /** @format date-time */  
149 - modifyTime?: string; 144 + logicDelete?: boolean;
150 /** 145 /**
151 * @description 146 * @description
152 * 名称 147 * 名称
@@ -157,6 +152,7 @@ export interface AdminClientDto { @@ -157,6 +152,7 @@ export interface AdminClientDto {
157 * 备注 152 * 备注
158 */ 153 */
159 notes?: string; 154 notes?: string;
  155 + paths?: Array<string>;
160 /** 156 /**
161 * @description 157 * @description
162 * 电话号码 158 * 电话号码
@@ -180,16 +176,26 @@ export interface AdminClientDto { @@ -180,16 +176,26 @@ export interface AdminClientDto {
180 referrers?: string; 176 referrers?: string;
181 /** 177 /**
182 * @description 178 * @description
183 - * 需求 179 + * 客户需求
184 */ 180 */
185 requirements?: string; 181 requirements?: string;
186 /** 182 /**
187 * @description 183 * @description
  184 + * 客户需求
  185 + */
  186 + requirementsText?: string;
  187 + /**
  188 + * @description
188 * 来源 189 * 来源
189 */ 190 */
190 source?: string; 191 source?: string;
191 /** 192 /**
192 * @description 193 * @description
  194 + * 来源
  195 + */
  196 + sourceText?: string;
  197 + /**
  198 + * @description
193 * 跟进状态 199 * 跟进状态
194 */ 200 */
195 tradeStatus?: string; 201 tradeStatus?: string;
@@ -198,8 +204,9 @@ export interface AdminClientDto { @@ -198,8 +204,9 @@ export interface AdminClientDto {
198 * 跟进状态 204 * 跟进状态
199 */ 205 */
200 tradeStatusText?: string; 206 tradeStatusText?: string;
201 - /** @format int32 */  
202 - version?: number; 207 + updateByName?: string;
  208 + /** @format date-time */
  209 + updateTime?: string;
203 } 210 }
204 211
205 export interface AdminDeptQueryVO { 212 export interface AdminDeptQueryVO {
@@ -2818,6 +2825,7 @@ export interface QueryBankStatementDto { @@ -2818,6 +2825,7 @@ export interface QueryBankStatementDto {
2818 } 2825 }
2819 2826
2820 export interface QueryClientDto { 2827 export interface QueryClientDto {
  2828 + address?: string;
2821 companyAddressLike?: string; 2829 companyAddressLike?: string;
2822 companyIds?: Array<number>; 2830 companyIds?: Array<number>;
2823 companyNameLike?: string; 2831 companyNameLike?: string;
@@ -2829,6 +2837,7 @@ export interface QueryClientDto { @@ -2829,6 +2837,7 @@ export interface QueryClientDto {
2829 createTimeLe?: string; 2837 createTimeLe?: string;
2830 /** @format int32 */ 2838 /** @format int32 */
2831 current?: number; 2839 current?: number;
  2840 + detailAddress?: string;
2832 /** @format int32 */ 2841 /** @format int32 */
2833 end?: number; 2842 end?: number;
2834 groupFilter?: string; 2843 groupFilter?: string;
@@ -2838,6 +2847,8 @@ export interface QueryClientDto { @@ -2838,6 +2847,8 @@ export interface QueryClientDto {
2838 /** @format int32 */ 2847 /** @format int32 */
2839 pageSize?: number; 2848 pageSize?: number;
2840 phoneNumber?: string; 2849 phoneNumber?: string;
  2850 + requirements?: string;
  2851 + source?: string;
2841 /** @format int32 */ 2852 /** @format int32 */
2842 start?: number; 2853 start?: number;
2843 /** @format int32 */ 2854 /** @format int32 */
@@ -2846,10 +2857,18 @@ export interface QueryClientDto { @@ -2846,10 +2857,18 @@ export interface QueryClientDto {
2846 } 2857 }
2847 2858
2848 export interface QueryCommunicationInfoDto { 2859 export interface QueryCommunicationInfoDto {
  2860 + clientAddressLike?: string;
2849 /** @format int64 */ 2861 /** @format int64 */
2850 clientId?: number; 2862 clientId?: number;
  2863 + clientIdIn?: Array<number>;
  2864 + clientNameLike?: string;
2851 content?: string; 2865 content?: string;
2852 createByName?: string; 2866 createByName?: string;
  2867 + createByNameIn?: Array<string>;
  2868 + /** @format date-time */
  2869 + createTimeGe?: string;
  2870 + /** @format date-time */
  2871 + createTimeLe?: string;
2853 /** @format int32 */ 2872 /** @format int32 */
2854 current?: number; 2873 current?: number;
2855 /** @format date-time */ 2874 /** @format date-time */
@@ -2864,6 +2883,7 @@ export interface QueryCommunicationInfoDto { @@ -2864,6 +2883,7 @@ export interface QueryCommunicationInfoDto {
2864 start?: number; 2883 start?: number;
2865 /** @format int32 */ 2884 /** @format int32 */
2866 total?: number; 2885 total?: number;
  2886 + tradeStatusLike?: string;
2867 way?: string; 2887 way?: string;
2868 } 2888 }
2869 2889
@@ -3201,10 +3221,16 @@ export interface QueryUseOldInvoicingDto { @@ -3201,10 +3221,16 @@ export interface QueryUseOldInvoicingDto {
3201 3221
3202 export interface QueryWarningOrderWhiteListDto { 3222 export interface QueryWarningOrderWhiteListDto {
3203 createByName?: string; 3223 createByName?: string;
  3224 + /** @format date-time */
  3225 + createTimeGe?: string;
  3226 + /** @format date-time */
  3227 + createTimeLe?: string;
3204 /** @format int32 */ 3228 /** @format int32 */
3205 current?: number; 3229 current?: number;
3206 /** @format int32 */ 3230 /** @format int32 */
3207 end?: number; 3231 end?: number;
  3232 + /** @format int64 */
  3233 + orderId?: number;
3208 /** @format int32 */ 3234 /** @format int32 */
3209 pageSize?: number; 3235 pageSize?: number;
3210 /** @format int32 */ 3236 /** @format int32 */
@@ -3683,6 +3709,7 @@ export interface SubOrder { @@ -3683,6 +3709,7 @@ export interface SubOrder {
3683 deadline?: string; 3709 deadline?: string;
3684 ext?: string; 3710 ext?: string;
3685 extendField?: string; 3711 extendField?: string;
  3712 + feedbackRegistrationContent?: string;
3686 /** @format date-time */ 3713 /** @format date-time */
3687 financialReceiptIssuanceTime?: string; 3714 financialReceiptIssuanceTime?: string;
3688 fullPaymentStatus?: string; 3715 fullPaymentStatus?: string;
@@ -4103,14 +4130,30 @@ export interface View { @@ -4103,14 +4130,30 @@ export interface View {
4103 } 4130 }
4104 4131
4105 export interface WarningOrderWhiteListDto { 4132 export interface WarningOrderWhiteListDto {
  4133 + createByName?: string;
  4134 + /** @format date-time */
  4135 + createTime?: string;
  4136 + logicDelete?: boolean;
4106 /** @format int64 */ 4137 /** @format int64 */
4107 orderId?: number; 4138 orderId?: number;
  4139 + paths?: Array<string>;
4108 salesCode?: string; 4140 salesCode?: string;
  4141 + updateByName?: string;
  4142 + /** @format date-time */
  4143 + updateTime?: string;
4109 } 4144 }
4110 4145
4111 export interface WarningUserWhiteListDto { 4146 export interface WarningUserWhiteListDto {
  4147 + createByName?: string;
  4148 + /** @format date-time */
  4149 + createTime?: string;
4112 /** @format int64 */ 4150 /** @format int64 */
4113 id?: number; 4151 id?: number;
  4152 + logicDelete?: boolean;
  4153 + paths?: Array<string>;
  4154 + updateByName?: string;
  4155 + /** @format date-time */
  4156 + updateTime?: string;
4114 userName?: string; 4157 userName?: string;
4115 } 4158 }
4116 4159
@@ -4133,16 +4176,29 @@ export interface ApiOrderConfirmReceiveRequest { @@ -4133,16 +4176,29 @@ export interface ApiOrderConfirmReceiveRequest {
4133 } 4176 }
4134 4177
4135 export interface ClientCommunicationInfo { 4178 export interface ClientCommunicationInfo {
  4179 + attachments?: string;
  4180 + /**
  4181 + * @description
  4182 + * 客户地址
  4183 + */
  4184 + clientAddress?: string;
4136 /** @format int64 */ 4185 /** @format int64 */
4137 clientId?: number; 4186 clientId?: number;
4138 /** 4187 /**
4139 * @description 4188 * @description
  4189 + * 客户名称
  4190 + */
  4191 + clientName?: string;
  4192 + /**
  4193 + * @description
4140 * 内容 4194 * 内容
4141 */ 4195 */
4142 content?: string; 4196 content?: string;
4143 createByName?: string; 4197 createByName?: string;
4144 /** @format date-time */ 4198 /** @format date-time */
4145 createTime?: string; 4199 createTime?: string;
  4200 + /** @format int64 */
  4201 + dateRange?: number;
4146 /** 4202 /**
4147 * @description 4203 * @description
4148 * 跟进时间 4204 * 跟进时间
@@ -4152,6 +4208,11 @@ export interface ClientCommunicationInfo { @@ -4152,6 +4208,11 @@ export interface ClientCommunicationInfo {
4152 /** @format int64 */ 4208 /** @format int64 */
4153 id?: number; 4209 id?: number;
4154 logicDelete?: boolean; 4210 logicDelete?: boolean;
  4211 + /**
  4212 + * @description
  4213 + * 客户状态
  4214 + */
  4215 + tradeStatus?: string;
4155 updateByName?: string; 4216 updateByName?: string;
4156 /** @format date-time */ 4217 /** @format date-time */
4157 updateTime?: string; 4218 updateTime?: string;
@@ -4160,6 +4221,11 @@ export interface ClientCommunicationInfo { @@ -4160,6 +4221,11 @@ export interface ClientCommunicationInfo {
4160 * 方式 4221 * 方式
4161 */ 4222 */
4162 way?: string; 4223 way?: string;
  4224 + /**
  4225 + * @description
  4226 + * 方式
  4227 + */
  4228 + wayText?: string;
4163 } 4229 }
4164 4230
4165 export interface CompanyInfo { 4231 export interface CompanyInfo {
@@ -4718,6 +4784,20 @@ export interface UserAddressSaveRequest { @@ -4718,6 +4784,20 @@ export interface UserAddressSaveRequest {
4718 institutionContactName?: string; 4784 institutionContactName?: string;
4719 } 4785 }
4720 4786
  4787 +export interface FeedbackRegistrationDTO {
  4788 + /**
  4789 + * @description
  4790 + * 回访登记内容
  4791 + */
  4792 + feedbackRegistrationContent?: string;
  4793 + /**
  4794 + * @description
  4795 + * 子订单id
  4796 + * @format int64
  4797 + */
  4798 + id?: number;
  4799 +}
  4800 +
4721 export interface UploadPaymentReceiptDTO { 4801 export interface UploadPaymentReceiptDTO {
4722 /** 4802 /**
4723 * @description 4803 * @description
src/services/request.ts
@@ -53,6 +53,7 @@ import type { @@ -53,6 +53,7 @@ import type {
53 DistrictDo, 53 DistrictDo,
54 DistrictSearchDo, 54 DistrictSearchDo,
55 Dto, 55 Dto,
  56 + FeedbackRegistrationDTO,
56 InventoryMaterialStockReq, 57 InventoryMaterialStockReq,
57 InvoiceDto, 58 InvoiceDto,
58 InvoiceRecordDTO, 59 InvoiceRecordDTO,
@@ -64,6 +65,7 @@ import type { @@ -64,6 +65,7 @@ import type {
64 MaterialUnitListRes, 65 MaterialUnitListRes,
65 MeasureUnitListRes, 66 MeasureUnitListRes,
66 MessageQueryDTO, 67 MessageQueryDTO,
  68 + ModelAndView,
67 OrderAddVO, 69 OrderAddVO,
68 OrderAuditLogQueryVO, 70 OrderAuditLogQueryVO,
69 OrderBaseInfoQueryVO, 71 OrderBaseInfoQueryVO,
@@ -360,6 +362,79 @@ export const postAdminClientAddOrModifyClientComunicationInfo = @@ -360,6 +362,79 @@ export const postAdminClientAddOrModifyClientComunicationInfo =
360 return request; 362 return request;
361 })(); 363 })();
362 364
  365 +/** @description request parameter type for postAdminClientDeleteAdminClient */
  366 +export interface PostAdminClientDeleteAdminClientOption {
  367 + /**
  368 + * @description
  369 + * id
  370 + * @format int64
  371 + */
  372 + query?: {
  373 + /**
  374 + @description
  375 + id
  376 + @format int64 */
  377 + id?: number;
  378 + };
  379 +}
  380 +
  381 +/** @description response type for postAdminClientDeleteAdminClient */
  382 +export interface PostAdminClientDeleteAdminClientResponse {
  383 + /**
  384 + * @description
  385 + * OK
  386 + */
  387 + 200: ServerResult;
  388 + /**
  389 + * @description
  390 + * Created
  391 + */
  392 + 201: any;
  393 + /**
  394 + * @description
  395 + * Unauthorized
  396 + */
  397 + 401: any;
  398 + /**
  399 + * @description
  400 + * Forbidden
  401 + */
  402 + 403: any;
  403 + /**
  404 + * @description
  405 + * Not Found
  406 + */
  407 + 404: any;
  408 +}
  409 +
  410 +export type PostAdminClientDeleteAdminClientResponseSuccess =
  411 + PostAdminClientDeleteAdminClientResponse[200];
  412 +/**
  413 + * @description
  414 + * 删除客户
  415 + * @tags 客户管理
  416 + * @produces *
  417 + * @consumes application/json
  418 + */
  419 +export const postAdminClientDeleteAdminClient = /* #__PURE__ */ (() => {
  420 + const method = 'post';
  421 + const url = '/admin/client/deleteAdminClient';
  422 + function request(
  423 + option?: PostAdminClientDeleteAdminClientOption,
  424 + ): Promise<PostAdminClientDeleteAdminClientResponseSuccess> {
  425 + return requester(request.url, {
  426 + method: request.method,
  427 + ...option,
  428 + }) as unknown as Promise<PostAdminClientDeleteAdminClientResponseSuccess>;
  429 + }
  430 +
  431 + /** http method */
  432 + request.method = method;
  433 + /** request url */
  434 + request.url = url;
  435 + return request;
  436 +})();
  437 +
363 /** @description response type for postAdminClientDownloadImportTemplate */ 438 /** @description response type for postAdminClientDownloadImportTemplate */
364 export interface PostAdminClientDownloadImportTemplateResponse { 439 export interface PostAdminClientDownloadImportTemplateResponse {
365 /** 440 /**
@@ -518,7 +593,7 @@ export type PostAdminClientGetStatisticalDataResponseSuccess = @@ -518,7 +593,7 @@ export type PostAdminClientGetStatisticalDataResponseSuccess =
518 PostAdminClientGetStatisticalDataResponse[200]; 593 PostAdminClientGetStatisticalDataResponse[200];
519 /** 594 /**
520 * @description 595 * @description
521 - * 修改跟进信息 596 + * 全部与预警客户个数
522 * @tags 客户管理 597 * @tags 客户管理
523 * @produces * 598 * @produces *
524 * @consumes application/json 599 * @consumes application/json
@@ -3237,9 +3312,7 @@ export interface GetErrorResponse { @@ -3237,9 +3312,7 @@ export interface GetErrorResponse {
3237 * @description 3312 * @description
3238 * OK 3313 * OK
3239 */ 3314 */
3240 - 200: {  
3241 - [propertyName: string]: any;  
3242 - }; 3315 + 200: ModelAndView;
3243 /** 3316 /**
3244 * @description 3317 * @description
3245 * Unauthorized 3318 * Unauthorized
@@ -3260,9 +3333,9 @@ export interface GetErrorResponse { @@ -3260,9 +3333,9 @@ export interface GetErrorResponse {
3260 export type GetErrorResponseSuccess = GetErrorResponse[200]; 3333 export type GetErrorResponseSuccess = GetErrorResponse[200];
3261 /** 3334 /**
3262 * @description 3335 * @description
3263 - * error 3336 + * errorHtml
3264 * @tags basic-error-controller 3337 * @tags basic-error-controller
3265 - * @produces * 3338 + * @produces text/html
3266 */ 3339 */
3267 export const getError = /* #__PURE__ */ (() => { 3340 export const getError = /* #__PURE__ */ (() => {
3268 const method = 'get'; 3341 const method = 'get';
@@ -3286,9 +3359,7 @@ export interface PutErrorResponse { @@ -3286,9 +3359,7 @@ export interface PutErrorResponse {
3286 * @description 3359 * @description
3287 * OK 3360 * OK
3288 */ 3361 */
3289 - 200: {  
3290 - [propertyName: string]: any;  
3291 - }; 3362 + 200: ModelAndView;
3292 /** 3363 /**
3293 * @description 3364 * @description
3294 * Created 3365 * Created
@@ -3314,9 +3385,9 @@ export interface PutErrorResponse { @@ -3314,9 +3385,9 @@ export interface PutErrorResponse {
3314 export type PutErrorResponseSuccess = PutErrorResponse[200]; 3385 export type PutErrorResponseSuccess = PutErrorResponse[200];
3315 /** 3386 /**
3316 * @description 3387 * @description
3317 - * error 3388 + * errorHtml
3318 * @tags basic-error-controller 3389 * @tags basic-error-controller
3319 - * @produces * 3390 + * @produces text/html
3320 * @consumes application/json 3391 * @consumes application/json
3321 */ 3392 */
3322 export const putError = /* #__PURE__ */ (() => { 3393 export const putError = /* #__PURE__ */ (() => {
@@ -3341,9 +3412,7 @@ export interface PostErrorResponse { @@ -3341,9 +3412,7 @@ export interface PostErrorResponse {
3341 * @description 3412 * @description
3342 * OK 3413 * OK
3343 */ 3414 */
3344 - 200: {  
3345 - [propertyName: string]: any;  
3346 - }; 3415 + 200: ModelAndView;
3347 /** 3416 /**
3348 * @description 3417 * @description
3349 * Created 3418 * Created
@@ -3369,9 +3438,9 @@ export interface PostErrorResponse { @@ -3369,9 +3438,9 @@ export interface PostErrorResponse {
3369 export type PostErrorResponseSuccess = PostErrorResponse[200]; 3438 export type PostErrorResponseSuccess = PostErrorResponse[200];
3370 /** 3439 /**
3371 * @description 3440 * @description
3372 - * error 3441 + * errorHtml
3373 * @tags basic-error-controller 3442 * @tags basic-error-controller
3374 - * @produces * 3443 + * @produces text/html
3375 * @consumes application/json 3444 * @consumes application/json
3376 */ 3445 */
3377 export const postError = /* #__PURE__ */ (() => { 3446 export const postError = /* #__PURE__ */ (() => {
@@ -3396,9 +3465,7 @@ export interface DeleteErrorResponse { @@ -3396,9 +3465,7 @@ export interface DeleteErrorResponse {
3396 * @description 3465 * @description
3397 * OK 3466 * OK
3398 */ 3467 */
3399 - 200: {  
3400 - [propertyName: string]: any;  
3401 - }; 3468 + 200: ModelAndView;
3402 /** 3469 /**
3403 * @description 3470 * @description
3404 * No Content 3471 * No Content
@@ -3419,9 +3486,9 @@ export interface DeleteErrorResponse { @@ -3419,9 +3486,9 @@ export interface DeleteErrorResponse {
3419 export type DeleteErrorResponseSuccess = DeleteErrorResponse[200]; 3486 export type DeleteErrorResponseSuccess = DeleteErrorResponse[200];
3420 /** 3487 /**
3421 * @description 3488 * @description
3422 - * error 3489 + * errorHtml
3423 * @tags basic-error-controller 3490 * @tags basic-error-controller
3424 - * @produces * 3491 + * @produces text/html
3425 */ 3492 */
3426 export const deleteError = /* #__PURE__ */ (() => { 3493 export const deleteError = /* #__PURE__ */ (() => {
3427 const method = 'delete'; 3494 const method = 'delete';
@@ -3445,9 +3512,7 @@ export interface OptionsErrorResponse { @@ -3445,9 +3512,7 @@ export interface OptionsErrorResponse {
3445 * @description 3512 * @description
3446 * OK 3513 * OK
3447 */ 3514 */
3448 - 200: {  
3449 - [propertyName: string]: any;  
3450 - }; 3515 + 200: ModelAndView;
3451 /** 3516 /**
3452 * @description 3517 * @description
3453 * No Content 3518 * No Content
@@ -3468,9 +3533,9 @@ export interface OptionsErrorResponse { @@ -3468,9 +3533,9 @@ export interface OptionsErrorResponse {
3468 export type OptionsErrorResponseSuccess = OptionsErrorResponse[200]; 3533 export type OptionsErrorResponseSuccess = OptionsErrorResponse[200];
3469 /** 3534 /**
3470 * @description 3535 * @description
3471 - * error 3536 + * errorHtml
3472 * @tags basic-error-controller 3537 * @tags basic-error-controller
3473 - * @produces * 3538 + * @produces text/html
3474 * @consumes application/json 3539 * @consumes application/json
3475 */ 3540 */
3476 export const optionsError = /* #__PURE__ */ (() => { 3541 export const optionsError = /* #__PURE__ */ (() => {
@@ -3495,9 +3560,7 @@ export interface HeadErrorResponse { @@ -3495,9 +3560,7 @@ export interface HeadErrorResponse {
3495 * @description 3560 * @description
3496 * OK 3561 * OK
3497 */ 3562 */
3498 - 200: {  
3499 - [propertyName: string]: any;  
3500 - }; 3563 + 200: ModelAndView;
3501 /** 3564 /**
3502 * @description 3565 * @description
3503 * No Content 3566 * No Content
@@ -3518,9 +3581,9 @@ export interface HeadErrorResponse { @@ -3518,9 +3581,9 @@ export interface HeadErrorResponse {
3518 export type HeadErrorResponseSuccess = HeadErrorResponse[200]; 3581 export type HeadErrorResponseSuccess = HeadErrorResponse[200];
3519 /** 3582 /**
3520 * @description 3583 * @description
3521 - * error 3584 + * errorHtml
3522 * @tags basic-error-controller 3585 * @tags basic-error-controller
3523 - * @produces * 3586 + * @produces text/html
3524 * @consumes application/json 3587 * @consumes application/json
3525 */ 3588 */
3526 export const headError = /* #__PURE__ */ (() => { 3589 export const headError = /* #__PURE__ */ (() => {
@@ -3545,9 +3608,7 @@ export interface PatchErrorResponse { @@ -3545,9 +3608,7 @@ export interface PatchErrorResponse {
3545 * @description 3608 * @description
3546 * OK 3609 * OK
3547 */ 3610 */
3548 - 200: {  
3549 - [propertyName: string]: any;  
3550 - }; 3611 + 200: ModelAndView;
3551 /** 3612 /**
3552 * @description 3613 * @description
3553 * No Content 3614 * No Content
@@ -3568,9 +3629,9 @@ export interface PatchErrorResponse { @@ -3568,9 +3629,9 @@ export interface PatchErrorResponse {
3568 export type PatchErrorResponseSuccess = PatchErrorResponse[200]; 3629 export type PatchErrorResponseSuccess = PatchErrorResponse[200];
3569 /** 3630 /**
3570 * @description 3631 * @description
3571 - * error 3632 + * errorHtml
3572 * @tags basic-error-controller 3633 * @tags basic-error-controller
3573 - * @produces * 3634 + * @produces text/html
3574 * @consumes application/json 3635 * @consumes application/json
3575 */ 3636 */
3576 export const patchError = /* #__PURE__ */ (() => { 3637 export const patchError = /* #__PURE__ */ (() => {
@@ -13049,6 +13110,168 @@ export const postServiceConstClientLevels = /* #__PURE__ */ (() =&gt; { @@ -13049,6 +13110,168 @@ export const postServiceConstClientLevels = /* #__PURE__ */ (() =&gt; {
13049 return request; 13110 return request;
13050 })(); 13111 })();
13051 13112
  13113 +/** @description response type for postServiceConstClientRequirements */
  13114 +export interface PostServiceConstClientRequirementsResponse {
  13115 + /**
  13116 + * @description
  13117 + * OK
  13118 + */
  13119 + 200: ServerResult;
  13120 + /**
  13121 + * @description
  13122 + * Created
  13123 + */
  13124 + 201: any;
  13125 + /**
  13126 + * @description
  13127 + * Unauthorized
  13128 + */
  13129 + 401: any;
  13130 + /**
  13131 + * @description
  13132 + * Forbidden
  13133 + */
  13134 + 403: any;
  13135 + /**
  13136 + * @description
  13137 + * Not Found
  13138 + */
  13139 + 404: any;
  13140 +}
  13141 +
  13142 +export type PostServiceConstClientRequirementsResponseSuccess =
  13143 + PostServiceConstClientRequirementsResponse[200];
  13144 +/**
  13145 + * @description
  13146 + * 客户需求
  13147 + * @tags front-const-controller
  13148 + * @produces *
  13149 + * @consumes application/json
  13150 + */
  13151 +export const postServiceConstClientRequirements = /* #__PURE__ */ (() => {
  13152 + const method = 'post';
  13153 + const url = '/service/const/clientRequirements';
  13154 + function request(): Promise<PostServiceConstClientRequirementsResponseSuccess> {
  13155 + return requester(request.url, {
  13156 + method: request.method,
  13157 + }) as unknown as Promise<PostServiceConstClientRequirementsResponseSuccess>;
  13158 + }
  13159 +
  13160 + /** http method */
  13161 + request.method = method;
  13162 + /** request url */
  13163 + request.url = url;
  13164 + return request;
  13165 +})();
  13166 +
  13167 +/** @description response type for postServiceConstClientSource */
  13168 +export interface PostServiceConstClientSourceResponse {
  13169 + /**
  13170 + * @description
  13171 + * OK
  13172 + */
  13173 + 200: ServerResult;
  13174 + /**
  13175 + * @description
  13176 + * Created
  13177 + */
  13178 + 201: any;
  13179 + /**
  13180 + * @description
  13181 + * Unauthorized
  13182 + */
  13183 + 401: any;
  13184 + /**
  13185 + * @description
  13186 + * Forbidden
  13187 + */
  13188 + 403: any;
  13189 + /**
  13190 + * @description
  13191 + * Not Found
  13192 + */
  13193 + 404: any;
  13194 +}
  13195 +
  13196 +export type PostServiceConstClientSourceResponseSuccess =
  13197 + PostServiceConstClientSourceResponse[200];
  13198 +/**
  13199 + * @description
  13200 + * 客户来源
  13201 + * @tags front-const-controller
  13202 + * @produces *
  13203 + * @consumes application/json
  13204 + */
  13205 +export const postServiceConstClientSource = /* #__PURE__ */ (() => {
  13206 + const method = 'post';
  13207 + const url = '/service/const/clientSource';
  13208 + function request(): Promise<PostServiceConstClientSourceResponseSuccess> {
  13209 + return requester(request.url, {
  13210 + method: request.method,
  13211 + }) as unknown as Promise<PostServiceConstClientSourceResponseSuccess>;
  13212 + }
  13213 +
  13214 + /** http method */
  13215 + request.method = method;
  13216 + /** request url */
  13217 + request.url = url;
  13218 + return request;
  13219 +})();
  13220 +
  13221 +/** @description response type for postServiceConstClientWay */
  13222 +export interface PostServiceConstClientWayResponse {
  13223 + /**
  13224 + * @description
  13225 + * OK
  13226 + */
  13227 + 200: ServerResult;
  13228 + /**
  13229 + * @description
  13230 + * Created
  13231 + */
  13232 + 201: any;
  13233 + /**
  13234 + * @description
  13235 + * Unauthorized
  13236 + */
  13237 + 401: any;
  13238 + /**
  13239 + * @description
  13240 + * Forbidden
  13241 + */
  13242 + 403: any;
  13243 + /**
  13244 + * @description
  13245 + * Not Found
  13246 + */
  13247 + 404: any;
  13248 +}
  13249 +
  13250 +export type PostServiceConstClientWayResponseSuccess =
  13251 + PostServiceConstClientWayResponse[200];
  13252 +/**
  13253 + * @description
  13254 + * 类型
  13255 + * @tags front-const-controller
  13256 + * @produces *
  13257 + * @consumes application/json
  13258 + */
  13259 +export const postServiceConstClientWay = /* #__PURE__ */ (() => {
  13260 + const method = 'post';
  13261 + const url = '/service/const/clientWay';
  13262 + function request(): Promise<PostServiceConstClientWayResponseSuccess> {
  13263 + return requester(request.url, {
  13264 + method: request.method,
  13265 + }) as unknown as Promise<PostServiceConstClientWayResponseSuccess>;
  13266 + }
  13267 +
  13268 + /** http method */
  13269 + request.method = method;
  13270 + /** request url */
  13271 + request.url = url;
  13272 + return request;
  13273 +})();
  13274 +
13052 /** @description response type for postServiceConstGetPayeeEnum */ 13275 /** @description response type for postServiceConstGetPayeeEnum */
13053 export interface PostServiceConstGetPayeeEnumResponse { 13276 export interface PostServiceConstGetPayeeEnumResponse {
13054 /** 13277 /**
@@ -17062,13 +17285,13 @@ export const postServiceOrderConfirmReceipt = /* #__PURE__ */ (() =&gt; { @@ -17062,13 +17285,13 @@ export const postServiceOrderConfirmReceipt = /* #__PURE__ */ (() =&gt; {
17062 export interface PostServiceOrderDeleteWarningOrderWhiteListOption { 17285 export interface PostServiceOrderDeleteWarningOrderWhiteListOption {
17063 /** 17286 /**
17064 * @description 17287 * @description
17065 - * id 17288 + * orderId
17066 */ 17289 */
17067 body?: { 17290 body?: {
17068 /** 17291 /**
17069 @description 17292 @description
17070 - id */  
17071 - id?: number; 17293 + orderId */
  17294 + orderId?: number;
17072 }; 17295 };
17073 } 17296 }
17074 17297
@@ -17540,6 +17763,77 @@ export const postServiceOrderExportTemplate = /* #__PURE__ */ (() =&gt; { @@ -17540,6 +17763,77 @@ export const postServiceOrderExportTemplate = /* #__PURE__ */ (() =&gt; {
17540 return request; 17763 return request;
17541 })(); 17764 })();
17542 17765
  17766 +/** @description request parameter type for postServiceOrderFeedbackRegistration */
  17767 +export interface PostServiceOrderFeedbackRegistrationOption {
  17768 + /**
  17769 + * @description
  17770 + * dto
  17771 + */
  17772 + body: {
  17773 + /**
  17774 + @description
  17775 + dto */
  17776 + dto: FeedbackRegistrationDTO;
  17777 + };
  17778 +}
  17779 +
  17780 +/** @description response type for postServiceOrderFeedbackRegistration */
  17781 +export interface PostServiceOrderFeedbackRegistrationResponse {
  17782 + /**
  17783 + * @description
  17784 + * OK
  17785 + */
  17786 + 200: ServerResult;
  17787 + /**
  17788 + * @description
  17789 + * Created
  17790 + */
  17791 + 201: any;
  17792 + /**
  17793 + * @description
  17794 + * Unauthorized
  17795 + */
  17796 + 401: any;
  17797 + /**
  17798 + * @description
  17799 + * Forbidden
  17800 + */
  17801 + 403: any;
  17802 + /**
  17803 + * @description
  17804 + * Not Found
  17805 + */
  17806 + 404: any;
  17807 +}
  17808 +
  17809 +export type PostServiceOrderFeedbackRegistrationResponseSuccess =
  17810 + PostServiceOrderFeedbackRegistrationResponse[200];
  17811 +/**
  17812 + * @description
  17813 + * 回访登记
  17814 + * @tags 内部订单
  17815 + * @produces *
  17816 + * @consumes application/json
  17817 + */
  17818 +export const postServiceOrderFeedbackRegistration = /* #__PURE__ */ (() => {
  17819 + const method = 'post';
  17820 + const url = '/service/order/feedbackRegistration';
  17821 + function request(
  17822 + option: PostServiceOrderFeedbackRegistrationOption,
  17823 + ): Promise<PostServiceOrderFeedbackRegistrationResponseSuccess> {
  17824 + return requester(request.url, {
  17825 + method: request.method,
  17826 + ...option,
  17827 + }) as unknown as Promise<PostServiceOrderFeedbackRegistrationResponseSuccess>;
  17828 + }
  17829 +
  17830 + /** http method */
  17831 + request.method = method;
  17832 + /** request url */
  17833 + request.url = url;
  17834 + return request;
  17835 +})();
  17836 +
17543 /** @description request parameter type for postServiceOrderFileProcess */ 17837 /** @description request parameter type for postServiceOrderFileProcess */
17544 export interface PostServiceOrderFileProcessOption { 17838 export interface PostServiceOrderFileProcessOption {
17545 /** 17839 /**