zjk
2026-09-18 e429c291995f3f20184079e480031533ae5c03e6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import RegionCascader from '@/components/RegionCascader';
import { PlusOutlined } from '@ant-design/icons';
import { history, useAccess, useParams } from '@umijs/max';
import { Button, Form, Image, Input, Radio, Select, Upload, message } from 'antd';
import React, { useEffect, useState } from 'react';
import './manage.less';
import {
  getClinicDetail,
  getProvincialAgentOptions,
  updateClinic,
  uploadClinicImage,
} from './service';
 
type FormValues = {
  avatar?: string;
  name?: string;
  loginAccount?: string;
  regionCodes?: string[];
  address?: string;
  businessLicenseUrl?: string;
  status?: number;
  agentId?: number;
  bankName?: string;
  accountHolder?: string;
  accountNumber?: string;
  branchName?: string;
};
const ClinicManagePage: React.FC = () => {
  const access = useAccess();
  const params = useParams<{ id: string }>();
  const [form] = Form.useForm<FormValues>();
  const [loading, setLoading] = useState(false);
  const [agentOptions, setAgentOptions] = useState<{ label: string; value: number }[]>([]);
  const [avatar, setAvatar] = useState('');
  const [businessLicenseUrl, setBusinessLicenseUrl] = useState('');
  const [uploadingAvatar, setUploadingAvatar] = useState(false);
  const [uploadingLicense, setUploadingLicense] = useState(false);
  useEffect(() => {
    if (!access['member:clinic:edit']) {
      history.replace('/Welcome');
      return;
    }
    getProvincialAgentOptions().then((response) =>
      setAgentOptions(
        (response.data?.list || []).map((item: any) => ({ label: item.agentName, value: item.id })),
      ),
    );
    if (params.id)
      getClinicDetail(params.id).then((response) => {
        const data = response.data || {};
        const regionCodes = [data.provinceCode, data.cityCode, data.districtCode].filter(Boolean);
        form.setFieldsValue({ ...data, regionCodes });
        setAvatar(data.avatar || '');
        setBusinessLicenseUrl(data.businessLicenseUrl || '');
      });
  }, [params.id]);
  const submit = async () => {
    const values = await form.validateFields();
    if (!params.id) return;
    setLoading(true);
    try {
      const [provinceCode, cityCode, districtCode] = values.regionCodes || [];
      await updateClinic(params.id, { ...values, provinceCode, cityCode, districtCode });
      message.success('保存成功');
      history.push(`/member/user/clinic/${params.id}`);
    } finally {
      setLoading(false);
    }
  };
  return (
    <div className="clinic-edit-page">
      <div className="clinic-edit-panel">
        <h2>编辑诊所</h2>
        <Form form={form} layout="vertical" className="clinic-edit-form">
          <Form.Item label="头像" className="clinic-edit-upload-item">
            <Form.Item name="avatar" hidden>
              <Input />
            </Form.Item>
            <Upload
              accept="image/*"
              showUploadList={false}
              customRequest={async (options) => {
                setUploadingAvatar(true);
                try {
                  const response = await uploadClinicImage(options.file as File);
                  const url = response.data?.url || response.data;
                  if (!url) throw new Error('upload failed');
                  setAvatar(url);
                  form.setFieldsValue({ avatar: url });
                  options.onSuccess?.(response);
                } catch (error) {
                  message.error('头像上传失败');
                  options.onError?.(error as Error);
                } finally {
                  setUploadingAvatar(false);
                }
              }}
            >
              <div className="clinic-edit-upload clinic-edit-upload--avatar">
                {uploadingAvatar ? (
                  <span>上传中...</span>
                ) : avatar ? (
                  <Image src={avatar} width={104} height={104} preview={false} />
                ) : (
                  <div>
                    <PlusOutlined />
                    <span>上传头像</span>
                  </div>
                )}
              </div>
            </Upload>
          </Form.Item>
 
          <div className="clinic-edit-form__grid">
            <Form.Item
              name="name"
              label="诊所名称"
              rules={[{ required: true, message: '请输入诊所名称' }]}
            >
              <Input maxLength={100} placeholder="请输入诊所名称" />
            </Form.Item>
            <Form.Item
              name="loginAccount"
              label="登录账号"
              rules={[{ required: true, message: '请输入登录账号' }]}
            >
              <Input maxLength={50} placeholder="请输入登录账号" />
            </Form.Item>
            <Form.Item
              name="regionCodes"
              label="诊所地址"
              rules={[{ required: true, message: '请选择诊所地址' }]}
            >
              <RegionCascader placeholder="请选择省/市/区" />
            </Form.Item>
            <Form.Item
              name="address"
              label="详细地址"
              rules={[{ required: true, message: '请输入详细地址' }]}
            >
              <Input maxLength={255} placeholder="请输入详细地址" />
            </Form.Item>
            <Form.Item label="营业执照" className="clinic-edit-upload-item">
              <Form.Item name="businessLicenseUrl" hidden>
                <Input />
              </Form.Item>
              <Upload
                accept="image/*"
                showUploadList={false}
                customRequest={async (options) => {
                  setUploadingLicense(true);
                  try {
                    const response = await uploadClinicImage(options.file as File);
                    const url = response.data?.url || response.data;
                    if (!url) throw new Error('upload failed');
                    setBusinessLicenseUrl(url);
                    form.setFieldsValue({ businessLicenseUrl: url });
                    options.onSuccess?.(response);
                  } catch (error) {
                    message.error('营业执照上传失败');
                    options.onError?.(error as Error);
                  } finally {
                    setUploadingLicense(false);
                  }
                }}
              >
                <div className="clinic-edit-upload clinic-edit-upload--license">
                  {uploadingLicense ? (
                    <span>上传中...</span>
                  ) : businessLicenseUrl ? (
                    <Image src={businessLicenseUrl} width={208} height={128} preview={false} />
                  ) : (
                    <div>
                      <PlusOutlined />
                      <span>上传营业执照</span>
                    </div>
                  )}
                </div>
              </Upload>
            </Form.Item>
            <Form.Item name="status" label="状态">
              <Radio.Group
                options={[
                  { label: '启用', value: 1 },
                  { label: '禁用', value: 0 },
                ]}
              />
            </Form.Item>
 
            <Form.Item name="bankName" label="银行名称">
              <Input maxLength={100} placeholder="请输入银行名称" />
            </Form.Item>
            <Form.Item name="accountHolder" label="账户名称">
              <Input maxLength={50} placeholder="请输入账户名称" />
            </Form.Item>
            <Form.Item name="accountNumber" label="账号">
              <Input maxLength={30} placeholder="请输入账号" />
            </Form.Item>
            <Form.Item name="branchName" label="支行名称">
              <Input maxLength={100} placeholder="请输入支行名称" />
            </Form.Item>
          </div>
          <Form.Item name="agentId" label="所属区域代理" className="clinic-edit-form__single">
            <Select
              allowClear
              showSearch
              optionFilterProp="label"
              options={agentOptions}
              placeholder="请选择所属区域代理"
            />
          </Form.Item>
 
          <div className="clinic-edit-form__footer">
            <Button onClick={() => history.back()}>取消</Button>
            <Button type="primary" loading={loading} onClick={submit}>
              保存
            </Button>
          </div>
        </Form>
      </div>
    </div>
  );
};
export default ClinicManagePage;