Commit a8cff0ec45a73190c0df28758e828c8cdb6580f1

Authored by zhongnanhuang
2 parents 18b4faea 0f671707

feat: update

.umirc.ts
... ... @@ -86,12 +86,13 @@ export default defineConfig({
86 86 icon: 'BookOutlined',
87 87 access: 'canReadAdmin',
88 88 },
89   - /*{
  89 + {
90 90 name: '客户管理',
91 91 path: '/client',
92 92 component: './Client',
93 93 icon: 'BookOutlined',
94   - },*/
  94 + access: 'canReadAdmin',
  95 + },
95 96 {
96 97 name: '打印',
97 98 path: '/print',
... ...
src/pages/Client/Components/ClientDrawer.tsx 0 → 100644
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postAdminClientAddAdminClient,
  4 + postAdminClientModifyClientInfo,
  5 + postDistrictSelectByLevel,
  6 + postDistrictSelectByNameAndLevel,
  7 + postDistrictSelOrderProvince,
  8 + postServiceConstClientLevels,
  9 + postServiceConstTradeStatus,
  10 +} from '@/services';
  11 +import { enumToSelect } from '@/utils';
  12 +import {
  13 + DrawerForm,
  14 + ProFormDateTimePicker,
  15 + ProFormSelect,
  16 + ProFormText,
  17 +} from '@ant-design/pro-components';
  18 +import { Button, Form, message } from 'antd';
  19 +import { useState } from 'react';
  20 +
  21 +export default ({ optType, record }) => {
  22 + const [form] = Form.useForm<{ name: string; company: string }>();
  23 + //省市区
  24 + const [province, setProvince] = useState('');
  25 + const [city, setCity] = useState('');
  26 + const [setDistrict] = useState('');
  27 + const optTypeEnum = {
  28 + add: {
  29 + text: '新增',
  30 + button: <Button type="primary">新增</Button>,
  31 + readonly: false,
  32 + onFinish: async (values) => {
  33 + const res = await postAdminClientAddAdminClient({
  34 + data: values,
  35 + });
  36 + if (res.result === RESPONSE_CODE.SUCCESS) {
  37 + message.success('新增成功');
  38 + // 不返回不会关闭弹框
  39 + return true;
  40 + }
  41 + },
  42 + },
  43 + edit: {
  44 + text: '编辑',
  45 + button: <a type="primary">编辑</a>,
  46 + readonly: false,
  47 + onFinish: async (values) => {
  48 + const res = await postAdminClientModifyClientInfo({
  49 + data: values,
  50 + });
  51 + if (res.result === RESPONSE_CODE.SUCCESS) {
  52 + message.success('编辑成功');
  53 + // 不返回不会关闭弹框
  54 + return true;
  55 + }
  56 + },
  57 + },
  58 + detail: {
  59 + text: '详情',
  60 + button: <a type="primary">详情</a>,
  61 + readonly: true,
  62 + },
  63 + };
  64 +
  65 + return (
  66 + <DrawerForm
  67 + title={optTypeEnum[optType].text}
  68 + resize={{
  69 + onResize() {
  70 + console.log('resize!');
  71 + },
  72 + maxWidth: window.innerWidth * 0.8,
  73 + minWidth: 300,
  74 + }}
  75 + initialValues={record}
  76 + form={form}
  77 + trigger={optTypeEnum[optType].button}
  78 + autoFocusFirstInput
  79 + drawerProps={{
  80 + destroyOnClose: true,
  81 + }}
  82 + submitTimeout={2000}
  83 + width={500}
  84 + readonly={optTypeEnum[optType].readonly}
  85 + onFinish={optTypeEnum[optType].onFinish}
  86 + >
  87 + <ProFormText name="id" label="id" hidden={true} />
  88 +
  89 + <ProFormText
  90 + name="name"
  91 + label="客户名称"
  92 + placeholder="请输入名称"
  93 + rules={[
  94 + {
  95 + required: true,
  96 + message: '请输入客户名称',
  97 + },
  98 + ]}
  99 + />
  100 + <ProFormText
  101 + name="companyName"
  102 + label="单位名称"
  103 + placeholder="请输入单位名称"
  104 + rules={[
  105 + {
  106 + required: true,
  107 + message: '请输入单位名称',
  108 + },
  109 + ]}
  110 + />
  111 + <div
  112 + style={{
  113 + display: 'flex',
  114 + justifyContent: 'space-between',
  115 + width: 340,
  116 + }}
  117 + >
  118 + <ProFormSelect
  119 + name="province"
  120 + key="province"
  121 + width={100}
  122 + label="省"
  123 + allowClear={false}
  124 + onChange={(value) => {
  125 + console.log(value);
  126 +
  127 + if (value !== undefined || value !== null) {
  128 + console.log('setProvince');
  129 +
  130 + setProvince(value);
  131 + }
  132 + }}
  133 + placeholder="请选择"
  134 + rules={[
  135 + {
  136 + required: true,
  137 + message: '请选择!',
  138 + },
  139 + ]}
  140 + request={async () => {
  141 + let province = [];
  142 + let res = await postDistrictSelectByLevel({ data: 1 });
  143 + if (res) {
  144 + res.data.forEach((item) => {
  145 + province.push({ value: item.district, label: item.district });
  146 + });
  147 + }
  148 + return province;
  149 + }}
  150 + />
  151 + <ProFormSelect
  152 + key={province}
  153 + name="city"
  154 + width={100}
  155 + label="市"
  156 + allowClear={false}
  157 + disabled={province === ''}
  158 + placeholder="请选择"
  159 + onChange={(value) => {
  160 + if (value !== undefined || value !== null) {
  161 + setCity(value);
  162 + }
  163 + }}
  164 + rules={[
  165 + {
  166 + required: true,
  167 + message: '请选择!',
  168 + },
  169 + ]}
  170 + request={async () => {
  171 + let cityOptions = [];
  172 + console.log(form.getFieldValue('id'));
  173 + if (form.getFieldValue('id')) {
  174 + const resp = await postDistrictSelOrderProvince({
  175 + data: form.getFieldValue('id'),
  176 + });
  177 + if (
  178 + resp.data.province !== null &&
  179 + resp.data.province !== undefined
  180 + ) {
  181 + console.log('province is ok');
  182 + let res = await postDistrictSelectByNameAndLevel({
  183 + data: { district: resp.data.province, level: 1 },
  184 + });
  185 + if (res && res.data) {
  186 + cityOptions = res.data.map((item) => ({
  187 + value: item.district,
  188 + label: item.district,
  189 + }));
  190 + }
  191 + }
  192 + }
  193 + if (province !== '') {
  194 + console.log(province);
  195 + console.log('province is okk');
  196 + let res = await postDistrictSelectByNameAndLevel({
  197 + data: { district: province, level: 1 },
  198 + });
  199 + if (res && res.data) {
  200 + cityOptions = res.data.map((item) => ({
  201 + value: item.district,
  202 + label: item.district,
  203 + }));
  204 + }
  205 + }
  206 + return cityOptions;
  207 + }}
  208 + />
  209 + <ProFormSelect
  210 + key={city ? city.toString() : 'district'}
  211 + name="district"
  212 + width={100}
  213 + label="区"
  214 + allowClear={false}
  215 + onChange={(value) => {
  216 + if (value !== undefined || value !== null) {
  217 + setDistrict(value);
  218 + }
  219 + }}
  220 + disabled={city === ''}
  221 + placeholder="请选择"
  222 + rules={[
  223 + {
  224 + required: true,
  225 + message: '请选择!',
  226 + },
  227 + ]}
  228 + request={async () => {
  229 + let districtOptions = [];
  230 + if (form.getFieldValue('id')) {
  231 + const resp = await postDistrictSelOrderProvince({
  232 + data: form.getFieldValue('id'),
  233 + });
  234 + if (resp.data.city !== null && resp.data.city !== undefined) {
  235 + let res = await postDistrictSelectByNameAndLevel({
  236 + data: { district: resp.data.city, level: 2 },
  237 + });
  238 + if (res && res.data) {
  239 + districtOptions = res.data.map((item) => ({
  240 + value: item.district,
  241 + label: item.district,
  242 + }));
  243 + }
  244 + }
  245 + }
  246 + if (city !== '') {
  247 + let res = await postDistrictSelectByNameAndLevel({
  248 + data: { district: city, level: 2 },
  249 + });
  250 + if (res && res.data) {
  251 + districtOptions = res.data.map((item) => ({
  252 + value: item.district,
  253 + label: item.district,
  254 + }));
  255 + }
  256 + }
  257 + return districtOptions;
  258 + }}
  259 + />
  260 + </div>
  261 + <ProFormText
  262 + name="companyAddress"
  263 + label="详细地址"
  264 + placeholder="请输入单位地址"
  265 + rules={[
  266 + {
  267 + required: true,
  268 + message: '请输入单位地址',
  269 + },
  270 + ]}
  271 + />
  272 + <ProFormText
  273 + name="phoneNumber"
  274 + label="联系电话"
  275 + placeholder="请输入联系电话"
  276 + rules={[
  277 + {
  278 + required: true,
  279 + message: '请输入联系电话',
  280 + },
  281 + ]}
  282 + />
  283 + <ProFormText
  284 + name="source"
  285 + label="客户来源"
  286 + placeholder="请输入客户来源"
  287 + />
  288 + <ProFormText
  289 + name="requirements"
  290 + label="客户需求"
  291 + placeholder="请输入客户需求"
  292 + rules={[
  293 + {
  294 + required: true,
  295 + message: '请输入客户需求',
  296 + },
  297 + ]}
  298 + />
  299 + <ProFormText name="referrers" label="推荐人" placeholder="请输入推荐人" />
  300 + <ProFormSelect
  301 + name="hasScheme"
  302 + label="是否已报方案"
  303 + placeholder="请选择是否已报方案"
  304 + options={[
  305 + {
  306 + label: '是',
  307 + value: true,
  308 + },
  309 + {
  310 + label: '否',
  311 + value: false,
  312 + },
  313 + ]}
  314 + rules={[
  315 + {
  316 + required: true,
  317 + message: '请选择是否已报方案',
  318 + },
  319 + ]}
  320 + />
  321 + <ProFormDateTimePicker
  322 + name="quoteDatetime"
  323 + label="报价时间"
  324 + placeholder="请输入报价时间"
  325 + />
  326 + <ProFormSelect
  327 + name="level"
  328 + label="客户等级"
  329 + placeholder="请输入客户等级"
  330 + rules={[
  331 + {
  332 + required: true,
  333 + message: '请输入客户等级',
  334 + },
  335 + ]}
  336 + request={async () => {
  337 + const res = await postServiceConstClientLevels();
  338 + return enumToSelect(res.data);
  339 + }}
  340 + />
  341 + <ProFormSelect
  342 + name="tradeStatus"
  343 + label="跟进状态"
  344 + placeholder="请输入跟进状态"
  345 + rules={[
  346 + {
  347 + required: true,
  348 + message: '请输入跟进状态',
  349 + },
  350 + ]}
  351 + request={async () => {
  352 + const res = await postServiceConstTradeStatus();
  353 + return enumToSelect(res.data);
  354 + }}
  355 + />
  356 + <ProFormText name="notes" label="备注" placeholder="请输入备注" />
  357 + </DrawerForm>
  358 + );
  359 +};
... ...
src/pages/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 () => {
  10 + const [form] = Form.useForm();
  11 + const [messageApi, contextHolder] = message.useMessage();
  12 + const downloadImportTemplate = () => {
  13 + messageApi.open({
  14 + type: 'loading',
  15 + content: '正在导入...',
  16 + duration: 0,
  17 + });
  18 + orderExport(
  19 + '/api/admin/client/downloadImportTemplate',
  20 + '客户导入模板.xlsx',
  21 + 'post',
  22 + {},
  23 + () => {
  24 + messageApi.destroy();
  25 + },
  26 + );
  27 + };
  28 +
  29 + return (
  30 + <ModalForm
  31 + title="导入客户信息"
  32 + trigger={<Button type="primary">导入客户信息</Button>}
  33 + form={form}
  34 + autoFocusFirstInput
  35 + modalProps={{
  36 + destroyOnClose: true,
  37 + onCancel: () => console.log('run'),
  38 + }}
  39 + submitTimeout={2000}
  40 + onFinish={async (values) => {
  41 + const formData = new FormData();
  42 + values.file.forEach((file) => {
  43 + formData.append('file', file.originFileObj as RcFile);
  44 + });
  45 + axios({
  46 + url: '/api/admin/client/importClient',
  47 + method: 'post',
  48 + responseType: 'blob',
  49 + headers: {
  50 + Authorization: localStorage.getItem('token'),
  51 + 'Content-Type':
  52 + 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq',
  53 + },
  54 + data: formData,
  55 + })
  56 + .then((response) => {
  57 + let data = response.data;
  58 + if (data.type === 'application/json') {
  59 + blobToJson(data).then((dataJson) => {
  60 + if (dataJson?.result === RESPONSE_CODE.SUCCESS) {
  61 + message.success(dataJson?.message);
  62 + } else {
  63 + message.error(dataJson?.message);
  64 + }
  65 + });
  66 + } else {
  67 + message.error('上传失败,已下载错误信息表格');
  68 + // 创建一个新的 Blob 对象,它包含了服务器响应的数据(即你的 Excel 文件)
  69 + const blob = new Blob([response.data]); // Excel 的 MIME 类型
  70 + const downloadUrl = window.URL.createObjectURL(blob);
  71 + const a = document.createElement('a');
  72 + a.href = downloadUrl;
  73 + a.download = '银行流水导入模板.xlsx'; // 你可以为文件命名
  74 + document.body.appendChild(a);
  75 + a.click(); // 模拟点击操作来下载文件
  76 + URL.revokeObjectURL(downloadUrl); // 释放掉 blob 对象所占用的内存
  77 + document.body.removeChild(a);
  78 + }
  79 + })
  80 + .catch((error) => {
  81 + // 处理错误
  82 + message.error('系统出现异常了,请联系管理员', error);
  83 + })
  84 + .finally(() => {});
  85 + return true;
  86 + }}
  87 + >
  88 + <ProFormUploadDragger max={1} label="上传" name="file" />
  89 + <Button type="link" onClick={downloadImportTemplate}>
  90 + 下载导入模板
  91 + </Button>
  92 + {contextHolder}
  93 + </ModalForm>
  94 + );
  95 +};
... ...
src/pages/Client/Components/CommunicationHistoryModal.tsx 0 → 100644
  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/index.tsx
1   -import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
2   -import type { ActionType, ProColumns } from '@ant-design/pro-components';
3   -import { ProTable, TableDropdown } from '@ant-design/pro-components';
4   -import { request } from '@umijs/max';
5   -import { Button, Dropdown, Space, Tag } from 'antd';
  1 +import ClientDrawer from '@/pages/Client/Components/ClientDrawer';
  2 +import ClientImportModal from '@/pages/Client/Components/ClientImportModal';
  3 +import CommunicationHistoryModal from '@/pages/Client/Components/CommunicationHistoryModal';
  4 +import {
  5 + postAdminClientQueryClientPage,
  6 + postServiceConstClientLevels,
  7 + postServiceConstTradeStatus,
  8 +} from '@/services';
  9 +import { orderExport } from '@/services/order';
  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, message } from 'antd';
6 14 import { useRef } from 'react';
7 15  
8   -export const waitTimePromise = async (time: number = 100) => {
9   - return new Promise((resolve) => {
10   - setTimeout(() => {
11   - resolve(true);
12   - }, time);
13   - });
14   -};
15   -
16   -export const waitTime = async (time: number = 100) => {
17   - await waitTimePromise(time);
18   -};
19   -
20   -type GithubIssueItem = {
21   - url: string;
22   - id: number;
23   - number: number;
24   - title: string;
25   - labels: {
26   - name: string;
27   - color: string;
28   - }[];
29   - state: string;
30   - comments: number;
31   - created_at: string;
32   - updated_at: string;
33   - closed_at?: string;
34   -};
35   -
36   -const columns: ProColumns<GithubIssueItem>[] = [
  16 +const columns = [
37 17 {
38 18 dataIndex: 'index',
39 19 valueType: 'indexBorder',
40 20 width: 48,
41 21 },
42 22 {
43   - title: '标题',
44   - dataIndex: 'title',
45   - copyable: true,
46   - ellipsis: true,
47   - tooltip: '标题过长会自动收缩',
48   - formItemProps: {
49   - rules: [
50   - {
51   - required: true,
52   - message: '此项为必填项',
53   - },
54   - ],
55   - },
  23 + title: '客户名称',
  24 + dataIndex: 'name',
  25 + width: 100,
  26 + hideInSearch: true,
  27 + },
  28 + {
  29 + title: '单位名称',
  30 + width: 150,
  31 + dataIndex: 'companyName',
  32 + hideInSearch: true,
  33 + },
  34 + {
  35 + title: '单位地址',
  36 + width: 250,
  37 + dataIndex: 'companyName',
  38 + hideInSearch: true,
  39 + },
  40 + {
  41 + title: '联系电话',
  42 + width: 150,
  43 + dataIndex: 'phoneNumber',
  44 + hideInSearch: true,
  45 + },
  46 + {
  47 + title: '客户来源',
  48 + width: 150,
  49 + dataIndex: 'source',
  50 + hideInSearch: true,
  51 + },
  52 + {
  53 + title: '推荐人',
  54 + dataIndex: 'referrers',
  55 + width: 150,
  56 + hideInSearch: true,
  57 + },
  58 + {
  59 + title: '客户需求',
  60 + dataIndex: 'requirements',
  61 + width: 150,
  62 + hideInSearch: true,
  63 + },
  64 + {
  65 + title: '是否已报方案',
  66 + width: 150,
  67 + dataIndex: 'hasSchemeText',
  68 + hideInSearch: true,
  69 + },
  70 + {
  71 + title: '报价时间',
  72 + key: 'since',
  73 + width: 150,
  74 + dataIndex: 'quoteDatetime',
  75 + valueType: 'dateTime',
  76 + hideInSearch: true,
  77 + },
  78 + {
  79 + title: '跟进状态',
  80 + width: 150,
  81 + dataIndex: 'tradeStatusText',
  82 + hideInSearch: true,
  83 + },
  84 + {
  85 + title: '客户等级',
  86 + width: 150,
  87 + dataIndex: 'levelText',
  88 + hideInSearch: true,
56 89 },
57 90 {
58   - disable: true,
59   - title: '状态',
60   - dataIndex: 'state',
61   - filters: true,
62   - onFilter: true,
63   - ellipsis: true,
  91 + title: '创建时间',
  92 + key: 'since',
  93 + width: 150,
  94 + dataIndex: 'createTime',
  95 + valueType: 'dateTime',
  96 + hideInSearch: true,
  97 + },
  98 + {
  99 + title: '最新跟进时间',
  100 + key: 'since',
  101 + width: 150,
  102 + dataIndex: 'latestCommunicationTime',
  103 + valueType: 'dateTime',
  104 + hideInSearch: true,
  105 + },
  106 + {
  107 + title: '客户名称',
  108 + dataIndex: 'nameLike',
  109 + valueType: 'Text',
  110 + hideInTable: true,
  111 + },
  112 + {
  113 + title: '单位名称',
  114 + dataIndex: 'companyNameLike',
  115 + valueType: 'Text',
  116 + hideInTable: true,
  117 + },
  118 + {
  119 + title: '联系电话',
  120 + dataIndex: 'phoneNumberLike',
  121 + valueType: 'Text',
  122 + hideInTable: true,
  123 + },
  124 + {
  125 + title: '是否已报方案',
  126 + dataIndex: 'hasScheme',
64 127 valueType: 'select',
65 128 valueEnum: {
66   - all: { text: '超长'.repeat(50) },
67   - open: {
68   - text: '未解决',
69   - status: 'Error',
70   - },
71   - closed: {
72   - text: '已解决',
73   - status: 'Success',
74   - disabled: true,
  129 + true: {
  130 + text: '是',
  131 + value: true,
75 132 },
76   - processing: {
77   - text: '解决中',
78   - status: 'Processing',
  133 + false: {
  134 + text: '否',
  135 + value: false,
79 136 },
80 137 },
  138 + hideInTable: true,
81 139 },
82 140 {
83   - disable: true,
84   - title: '标签',
85   - dataIndex: 'labels',
86   - search: false,
87   - renderFormItem: (_, { defaultRender }) => {
88   - return defaultRender(_);
  141 + title: '客户等级',
  142 + dataIndex: 'level',
  143 + valueType: 'select',
  144 + hideInTable: true,
  145 + request: async () => {
  146 + const res = await postServiceConstClientLevels();
  147 + return enumToSelect(res.data);
89 148 },
90   - render: (_, record) => (
91   - <Space>
92   - {record.labels.map(({ name, color }) => (
93   - <Tag color={color} key={name}>
94   - {name}
95   - </Tag>
96   - ))}
97   - </Space>
98   - ),
99 149 },
100 150 {
101   - title: '创建时间',
102   - key: 'showTime',
103   - dataIndex: 'created_at',
104   - valueType: 'date',
105   - sorter: true,
106   - hideInSearch: true,
  151 + title: '跟进状态',
  152 + dataIndex: 'tradeStatus',
  153 + valueType: 'select',
  154 + hideInTable: true,
  155 + request: async () => {
  156 + const res = await postServiceConstTradeStatus();
  157 + return enumToSelect(res.data);
  158 + },
107 159 },
108 160 {
109 161 title: '创建时间',
110   - dataIndex: 'created_at',
111 162 valueType: 'dateRange',
112 163 hideInTable: true,
113 164 search: {
114 165 transform: (value) => {
115   - return {
116   - startTime: value[0],
117   - endTime: value[1],
118   - };
  166 + if (value) {
  167 + return {
  168 + createTimeGe: value[0],
  169 + createTimeLe: value[1],
  170 + };
  171 + }
119 172 },
120 173 },
121 174 },
... ... @@ -123,121 +176,121 @@ const columns: ProColumns&lt;GithubIssueItem&gt;[] = [
123 176 title: '操作',
124 177 valueType: 'option',
125 178 key: 'option',
126   - render: (text, record, _, action) => [
127   - <a
128   - key="editable"
129   - onClick={() => {
130   - action?.startEditable?.(record.id);
131   - }}
132   - >
133   - 编辑
134   - </a>,
135   - <a href={record.url} target="_blank" rel="noopener noreferrer" key="view">
136   - 查看
137   - </a>,
138   - <TableDropdown
139   - key="actionGroup"
140   - onSelect={() => action?.reload()}
141   - menus={[
142   - { key: 'copy', name: '复制' },
143   - { key: 'delete', name: '删除' },
144   - ]}
145   - />,
146   - ],
  179 + width: 150,
  180 + render: (text, record) => {
  181 + console.log(JSON.stringify(record));
  182 + return [
  183 + <CommunicationHistoryModal
  184 + key={'communicationHistory'}
  185 + clientId={record.id}
  186 + />,
  187 + <ClientDrawer
  188 + key={'detail'}
  189 + record={record}
  190 + optType={'detail'}
  191 + ></ClientDrawer>,
  192 + <ClientDrawer
  193 + key={'edit'}
  194 + record={record}
  195 + optType={'edit'}
  196 + ></ClientDrawer>,
  197 + ];
  198 + },
147 199 },
148 200 ];
149 201  
150 202 export default () => {
  203 + const [messageApi, contextHolder] = message.useMessage();
151 204 const actionRef = useRef<ActionType>();
152 205 return (
153   - <ProTable<GithubIssueItem>
154   - columns={columns}
155   - actionRef={actionRef}
156   - cardBordered
157   - request={async (params, sort, filter) => {
158   - console.log(sort, filter);
159   - await waitTime(2000);
160   - return request<{
161   - data: GithubIssueItem[];
162   - }>('https://proapi.azurewebsites.net/github/issues', {
163   - params,
164   - });
165   - }}
166   - editable={{
167   - type: 'multiple',
168   - }}
169   - columnsState={{
170   - persistenceKey: 'pro-table-singe-demos',
171   - persistenceType: 'localStorage',
172   - defaultValue: {
173   - option: { fixed: 'right', disable: true },
174   - },
175   - onChange(value) {
176   - console.log('value: ', value);
177   - },
178   - }}
179   - rowKey="id"
180   - search={{
181   - labelWidth: 'auto',
182   - }}
183   - options={{
184   - setting: {
185   - listsHeight: 400,
186   - },
187   - }}
188   - form={{
189   - // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
190   - syncToUrl: (values, type) => {
191   - if (type === 'get') {
192   - return {
193   - ...values,
194   - created_at: [values.startTime, values.endTime],
195   - };
196   - }
197   - return values;
198   - },
199   - }}
200   - pagination={{
201   - pageSize: 5,
202   - onChange: (page) => console.log(page),
203   - }}
204   - dateFormatter="string"
205   - headerTitle="高级表格"
206   - toolBarRender={() => [
207   - <Button
208   - key="button"
209   - icon={<PlusOutlined />}
210   - onClick={() => {
211   - actionRef.current?.reload();
212   - }}
213   - type="primary"
214   - >
215   - 新建
216   - </Button>,
217   - <Dropdown
218   - key="menu"
219   - menu={{
220   - items: [
221   - {
222   - label: '1st item',
223   - key: '1',
224   - },
225   - {
226   - label: '2nd item',
227   - key: '1',
228   - },
229   - {
230   - label: '3rd item',
231   - key: '1',
232   - },
233   - ],
234   - }}
235   - >
236   - <Button>
237   - <EllipsisOutlined />
238   - </Button>
239   - </Dropdown>,
240   - ]}
241   - />
  206 + <>
  207 + <ProTable
  208 + columns={columns}
  209 + actionRef={actionRef}
  210 + cardBordered
  211 + request={async (params) => {
  212 + const res = await postAdminClientQueryClientPage({
  213 + data: {
  214 + ...params,
  215 + },
  216 + });
  217 + const data = res.data;
  218 + return data;
  219 + }}
  220 + search={{
  221 + defaultCollapsed: false,
  222 + optionRender: (searchConfig, formProps, dom) => [
  223 + ...dom.reverse(),
  224 + <Button
  225 + key="out"
  226 + onClick={() => {
  227 + const values = searchConfig?.form?.getFieldsValue();
  228 + messageApi.open({
  229 + type: 'loading',
  230 + content: '导出中...',
  231 + duration: 0,
  232 + });
  233 + orderExport(
  234 + '/api/admin/client/exportClients',
  235 + '客户信息.xlsx',
  236 + 'POST',
  237 + values,
  238 + () => {
  239 + messageApi.destroy();
  240 + },
  241 + );
  242 + }}
  243 + >
  244 + 导出
  245 + </Button>,
  246 + ],
  247 + }}
  248 + scroll={{
  249 + x: 1400,
  250 + }}
  251 + editable={{
  252 + type: 'multiple',
  253 + }}
  254 + columnsState={{
  255 + persistenceKey: 'pro-table-singe-demos',
  256 + persistenceType: 'localStorage',
  257 + defaultValue: {
  258 + option: { fixed: 'right', disable: true },
  259 + },
  260 + onChange(value) {
  261 + console.log('value: ', value);
  262 + },
  263 + }}
  264 + rowKey="id"
  265 + options={{
  266 + setting: {
  267 + listsHeight: 400,
  268 + },
  269 + }}
  270 + form={{
  271 + // 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
  272 + syncToUrl: (values, type) => {
  273 + if (type === 'get') {
  274 + return {
  275 + ...values,
  276 + created_at: [values.startTime, values.endTime],
  277 + };
  278 + }
  279 + return values;
  280 + },
  281 + }}
  282 + pagination={{
  283 + pageSize: 5,
  284 + onChange: (page) => console.log(page),
  285 + }}
  286 + dateFormatter="string"
  287 + headerTitle="高级表格"
  288 + toolBarRender={() => [
  289 + <ClientDrawer optType={'add'} key="button"></ClientDrawer>,
  290 + <ClientImportModal key="import" />,
  291 + ]}
  292 + />
  293 + {contextHolder}
  294 + </>
242 295 );
243 296 };
... ...
src/pages/Order/components/OrderDrawer.tsx
... ... @@ -3,7 +3,6 @@ import {
3 3 postCanrdApiUserAddressList,
4 4 postCanrdApiUserDetail,
5 5 postCanrdApiUserNowMoneyCheck,
6   - postDistrictAddOrderAndProvince,
7 6 postDistrictSelectByLevel,
8 7 postDistrictSelectByNameAndLevel,
9 8 postDistrictSelOrderProvince,
... ... @@ -877,21 +876,12 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
877 876 if (typeof values.erpCustomerId !== 'string') {
878 877 values.erpCustomerId = values.erpCustomerId?.id;
879 878 }
880   -
  879 + values.province = province;
  880 + values.city = city;
  881 + values.district = district;
881 882 //新增
882 883 if (optType('add') || optType('copy')) {
883 884 res = await postServiceOrderAddOrder({ data: values });
884   - if (res && res.data.length === 2) {
885   - const orderMainProDo = {
886   - oId: res.data[0],
887   - province: province,
888   - city: city,
889   - district: district,
890   - };
891   - await postDistrictAddOrderAndProvince({
892   - data: orderMainProDo,
893   - });
894   - }
895 885 }
896 886 //修改或者申请售后或者申请修改
897 887 if (
... ... @@ -915,6 +905,9 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
915 905 values.deleteSubOrderLists = diff;
916 906  
917 907 if (optType('edit')) {
  908 + values.province = province;
  909 + values.city = city;
  910 + values.district = district;
918 911 res = await postServiceOrderUpdateOrder({ data: values });
919 912 }
920 913  
... ... @@ -1134,14 +1127,20 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1134 1127 const resp = await postDistrictSelOrderProvince({
1135 1128 data: form.getFieldValue('id'),
1136 1129 });
1137   - console.log();
1138   -
1139   - setProvince(resp.data.province);
1140   - form.setFieldValue('province', resp.data.province);
1141   - setCity(resp.data.city);
1142   - form.setFieldValue('city', resp.data.city);
1143   - setDistrict(resp.data.district);
1144   - form.setFieldValue('district', resp.data.district);
  1130 + if (resp && resp.data) {
  1131 + if (resp.data.province) {
  1132 + setProvince(resp.data.province);
  1133 + form.setFieldValue('province', resp.data.province);
  1134 + }
  1135 + if (resp.data.city) {
  1136 + setCity(resp.data.city);
  1137 + form.setFieldValue('city', resp.data.city);
  1138 + }
  1139 + if (resp.data.district) {
  1140 + setDistrict(resp.data.district);
  1141 + form.setFieldValue('district', resp.data.district);
  1142 + }
  1143 + }
1145 1144 console.log(form.getFieldsValue());
1146 1145 }
1147 1146 //判断如果是在修改或者复制,那么第一次请求的时候,默认生成当前收货人信息的option
... ... @@ -1228,7 +1227,11 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1228 1227 labelInValue: true,
1229 1228 }}
1230 1229 onChange={(value) => {
  1230 + console.log(value);
  1231 +
1231 1232 if (value !== undefined || value !== null) {
  1233 + console.log('setProvince');
  1234 +
1232 1235 setProvince(value?.value);
1233 1236 }
1234 1237 }}
... ... @@ -1273,8 +1276,31 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1273 1276 },
1274 1277 ]}
1275 1278 request={async () => {
  1279 + let cityOptions = [];
  1280 + console.log(form.getFieldValue('id'));
  1281 + if (form.getFieldValue('id')) {
  1282 + const resp = await postDistrictSelOrderProvince({
  1283 + data: form.getFieldValue('id'),
  1284 + });
  1285 + if (
  1286 + resp.data.province !== null &&
  1287 + resp.data.province !== undefined
  1288 + ) {
  1289 + console.log('province is ok');
  1290 + let res = await postDistrictSelectByNameAndLevel({
  1291 + data: { district: resp.data.province, level: 1 },
  1292 + });
  1293 + if (res && res.data) {
  1294 + cityOptions = res.data.map((item) => ({
  1295 + value: item.district,
  1296 + label: item.district,
  1297 + }));
  1298 + }
  1299 + }
  1300 + }
1276 1301 if (province !== '') {
1277   - let cityOptions = [];
  1302 + console.log(province);
  1303 + console.log('province is okk');
1278 1304 let res = await postDistrictSelectByNameAndLevel({
1279 1305 data: { district: province, level: 1 },
1280 1306 });
... ... @@ -1284,9 +1310,8 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1284 1310 label: item.district,
1285 1311 }));
1286 1312 }
1287   - return cityOptions;
1288 1313 }
1289   - return [];
  1314 + return cityOptions;
1290 1315 }}
1291 1316 />
1292 1317 <ProFormSelect
... ... @@ -1312,10 +1337,24 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1312 1337 },
1313 1338 ]}
1314 1339 request={async () => {
1315   - console.log(form.getFieldsValue());
1316   -
  1340 + let districtOptions = [];
  1341 + if (form.getFieldValue('id')) {
  1342 + const resp = await postDistrictSelOrderProvince({
  1343 + data: form.getFieldValue('id'),
  1344 + });
  1345 + if (resp.data.city !== null && resp.data.city !== undefined) {
  1346 + let res = await postDistrictSelectByNameAndLevel({
  1347 + data: { district: resp.data.city, level: 2 },
  1348 + });
  1349 + if (res && res.data) {
  1350 + districtOptions = res.data.map((item) => ({
  1351 + value: item.district,
  1352 + label: item.district,
  1353 + }));
  1354 + }
  1355 + }
  1356 + }
1317 1357 if (city !== '') {
1318   - let districtOptions = [];
1319 1358 let res = await postDistrictSelectByNameAndLevel({
1320 1359 data: { district: city, level: 2 },
1321 1360 });
... ... @@ -1325,9 +1364,8 @@ export default ({ onClose, data, subOrders, orderOptType }) =&gt; {
1325 1364 label: item.district,
1326 1365 }));
1327 1366 }
1328   - return districtOptions;
1329 1367 }
1330   - return [];
  1368 + return districtOptions;
1331 1369 }}
1332 1370 />
1333 1371 </div>
... ...
src/pages/OrderReport/index.tsx
1 1 import {
2 2 getOrderErpOrderZoNingSelectAll,
3   - getOrderErpOrderZoNingSelectUserAll,
4 3 postOrderErpOrderZoNingSelectSaleUserByProvince,
5 4 postServiceOrderQueryReportFormsInformation,
6 5 postServiceOrderQuerySalesCode,
... ... @@ -66,7 +65,7 @@ const OrderReportPage = () =&gt; {
66 65 setLoading(true);
67 66 let body = {
68 67 statisticsMethod: '',
69   - salesCode: [null],
  68 + // salesCode: [null],
70 69 productBelongBusiness: form.getFieldValue('productBelongBusiness'),
71 70 maxAccount: form.getFieldValue('maxAccount'),
72 71 includeExperimentalEquipment: form.getFieldValue(
... ... @@ -77,14 +76,14 @@ const OrderReportPage = () =&gt; {
77 76 };
78 77 // console.log(form.getFieldValue('zoning').value);
79 78  
80   - let res = await getOrderErpOrderZoNingSelectUserAll();
81   - if (res && res.data) {
82   - let safeUserList = [];
83   - res.data.forEach((element) => {
84   - safeUserList.push(element.userName);
85   - });
86   - body = { ...body, salesCode: safeUserList };
87   - }
  79 + // let res = await getOrderErpOrderZoNingSelectUserAll();
  80 + // if (res && res.data) {
  81 + // let safeUserList = [];
  82 + // res.data.forEach((element) => {
  83 + // safeUserList.push(element.userName);
  84 + // });
  85 + // body = { ...body, salesCode: safeUserList };
  86 + // }
88 87 if (form.getFieldValue('salesCode')) {
89 88 body = { ...body, salesCode: [form.getFieldValue('salesCode')] };
90 89 }
... ...
src/services/request.ts
... ... @@ -58,6 +58,7 @@ import type {
58 58 MaterialUnitListRes,
59 59 MeasureUnitListRes,
60 60 MessageQueryDTO,
  61 + ModelAndView,
61 62 OrderAddVO,
62 63 OrderAuditLogQueryVO,
63 64 OrderBaseInfoQueryVO,
... ... @@ -609,6 +610,77 @@ export const postAdminClientModifyClientComunicationInfo =
609 610 return request;
610 611 })();
611 612  
  613 +/** @description request parameter type for postAdminClientModifyClientInfo */
  614 +export interface PostAdminClientModifyClientInfoOption {
  615 + /**
  616 + * @description
  617 + * dto
  618 + */
  619 + body: {
  620 + /**
  621 + @description
  622 + dto */
  623 + dto: AdminClientDto;
  624 + };
  625 +}
  626 +
  627 +/** @description response type for postAdminClientModifyClientInfo */
  628 +export interface PostAdminClientModifyClientInfoResponse {
  629 + /**
  630 + * @description
  631 + * OK
  632 + */
  633 + 200: ServerResult;
  634 + /**
  635 + * @description
  636 + * Created
  637 + */
  638 + 201: any;
  639 + /**
  640 + * @description
  641 + * Unauthorized
  642 + */
  643 + 401: any;
  644 + /**
  645 + * @description
  646 + * Forbidden
  647 + */
  648 + 403: any;
  649 + /**
  650 + * @description
  651 + * Not Found
  652 + */
  653 + 404: any;
  654 +}
  655 +
  656 +export type PostAdminClientModifyClientInfoResponseSuccess =
  657 + PostAdminClientModifyClientInfoResponse[200];
  658 +/**
  659 + * @description
  660 + * 修改跟进信息
  661 + * @tags 客户管理
  662 + * @produces *
  663 + * @consumes application/json
  664 + */
  665 +export const postAdminClientModifyClientInfo = /* #__PURE__ */ (() => {
  666 + const method = 'post';
  667 + const url = '/admin/client/modifyClientInfo';
  668 + function request(
  669 + option: PostAdminClientModifyClientInfoOption,
  670 + ): Promise<PostAdminClientModifyClientInfoResponseSuccess> {
  671 + return requester(request.url, {
  672 + method: request.method,
  673 + ...option,
  674 + }) as unknown as Promise<PostAdminClientModifyClientInfoResponseSuccess>;
  675 + }
  676 +
  677 + /** http method */
  678 + request.method = method;
  679 + /** request url */
  680 + request.url = url;
  681 + return request;
  682 +})();
  683 +
612 684 /** @description request parameter type for postAdminClientQueryClientComunicationInfo */
613 685 export interface PostAdminClientQueryClientComunicationInfoOption {
614 686 /**
... ... @@ -3093,9 +3165,7 @@ export interface GetErrorResponse {
3093 3165 * @description
3094 3166 * OK
3095 3167 */
3096   - 200: {
3097   - [propertyName: string]: any;
3098   - };
  3168 + 200: ModelAndView;
3099 3169 /**
3100 3170 * @description
3101 3171 * Unauthorized
... ... @@ -3116,9 +3186,9 @@ export interface GetErrorResponse {
3116 3186 export type GetErrorResponseSuccess = GetErrorResponse[200];
3117 3187 /**
3118 3188 * @description
3119   - * error
  3189 + * errorHtml
3120 3190 * @tags basic-error-controller
3121   - * @produces *
  3191 + * @produces text/html
3122 3192 */
3123 3193 export const getError = /* #__PURE__ */ (() => {
3124 3194 const method = 'get';
... ... @@ -3142,9 +3212,7 @@ export interface PutErrorResponse {
3142 3212 * @description
3143 3213 * OK
3144 3214 */
3145   - 200: {
3146   - [propertyName: string]: any;
3147   - };
  3215 + 200: ModelAndView;
3148 3216 /**
3149 3217 * @description
3150 3218 * Created
... ... @@ -3170,9 +3238,9 @@ export interface PutErrorResponse {
3170 3238 export type PutErrorResponseSuccess = PutErrorResponse[200];
3171 3239 /**
3172 3240 * @description
3173   - * error
  3241 + * errorHtml
3174 3242 * @tags basic-error-controller
3175   - * @produces *
  3243 + * @produces text/html
3176 3244 * @consumes application/json
3177 3245 */
3178 3246 export const putError = /* #__PURE__ */ (() => {
... ... @@ -3197,9 +3265,7 @@ export interface PostErrorResponse {
3197 3265 * @description
3198 3266 * OK
3199 3267 */
3200   - 200: {
3201   - [propertyName: string]: any;
3202   - };
  3268 + 200: ModelAndView;
3203 3269 /**
3204 3270 * @description
3205 3271 * Created
... ... @@ -3225,9 +3291,9 @@ export interface PostErrorResponse {
3225 3291 export type PostErrorResponseSuccess = PostErrorResponse[200];
3226 3292 /**
3227 3293 * @description
3228   - * error
  3294 + * errorHtml
3229 3295 * @tags basic-error-controller
3230   - * @produces *
  3296 + * @produces text/html
3231 3297 * @consumes application/json
3232 3298 */
3233 3299 export const postError = /* #__PURE__ */ (() => {
... ... @@ -3252,9 +3318,7 @@ export interface DeleteErrorResponse {
3252 3318 * @description
3253 3319 * OK
3254 3320 */
3255   - 200: {
3256   - [propertyName: string]: any;
3257   - };
  3321 + 200: ModelAndView;
3258 3322 /**
3259 3323 * @description
3260 3324 * No Content
... ... @@ -3275,9 +3339,9 @@ export interface DeleteErrorResponse {
3275 3339 export type DeleteErrorResponseSuccess = DeleteErrorResponse[200];
3276 3340 /**
3277 3341 * @description
3278   - * error
  3342 + * errorHtml
3279 3343 * @tags basic-error-controller
3280   - * @produces *
  3344 + * @produces text/html
3281 3345 */
3282 3346 export const deleteError = /* #__PURE__ */ (() => {
3283 3347 const method = 'delete';
... ... @@ -3301,9 +3365,7 @@ export interface OptionsErrorResponse {
3301 3365 * @description
3302 3366 * OK
3303 3367 */
3304   - 200: {
3305   - [propertyName: string]: any;
3306   - };
  3368 + 200: ModelAndView;
3307 3369 /**
3308 3370 * @description
3309 3371 * No Content
... ... @@ -3324,9 +3386,9 @@ export interface OptionsErrorResponse {
3324 3386 export type OptionsErrorResponseSuccess = OptionsErrorResponse[200];
3325 3387 /**
3326 3388 * @description
3327   - * error
  3389 + * errorHtml
3328 3390 * @tags basic-error-controller
3329   - * @produces *
  3391 + * @produces text/html
3330 3392 * @consumes application/json
3331 3393 */
3332 3394 export const optionsError = /* #__PURE__ */ (() => {
... ... @@ -3351,9 +3413,7 @@ export interface HeadErrorResponse {
3351 3413 * @description
3352 3414 * OK
3353 3415 */
3354   - 200: {
3355   - [propertyName: string]: any;
3356   - };
  3416 + 200: ModelAndView;
3357 3417 /**
3358 3418 * @description
3359 3419 * No Content
... ... @@ -3374,9 +3434,9 @@ export interface HeadErrorResponse {
3374 3434 export type HeadErrorResponseSuccess = HeadErrorResponse[200];
3375 3435 /**
3376 3436 * @description
3377   - * error
  3437 + * errorHtml
3378 3438 * @tags basic-error-controller
3379   - * @produces *
  3439 + * @produces text/html
3380 3440 * @consumes application/json
3381 3441 */
3382 3442 export const headError = /* #__PURE__ */ (() => {
... ... @@ -3401,9 +3461,7 @@ export interface PatchErrorResponse {
3401 3461 * @description
3402 3462 * OK
3403 3463 */
3404   - 200: {
3405   - [propertyName: string]: any;
3406   - };
  3464 + 200: ModelAndView;
3407 3465 /**
3408 3466 * @description
3409 3467 * No Content
... ... @@ -3424,9 +3482,9 @@ export interface PatchErrorResponse {
3424 3482 export type PatchErrorResponseSuccess = PatchErrorResponse[200];
3425 3483 /**
3426 3484 * @description
3427   - * error
  3485 + * errorHtml
3428 3486 * @tags basic-error-controller
3429   - * @produces *
  3487 + * @produces text/html
3430 3488 * @consumes application/json
3431 3489 */
3432 3490 export const patchError = /* #__PURE__ */ (() => {
... ...