| 
@@ -22,15 +22,34 @@ | 
 | 
@@ -22,15 +22,34 @@ | 
| 
22
 | 
           ><p style="font-size: 17px; margin-top: 7px; margin-left: 10px">个人信息</p></div
 | 
22
 | 
           ><p style="font-size: 17px; margin-top: 7px; margin-left: 10px">个人信息</p></div
 | 
| 
23
 | 
         >
 | 
23
 | 
         >
 | 
| 
24
 | 
         <div class="change-avatar" style="text-align: center">
 | 
24
 | 
         <div class="change-avatar" style="text-align: center">
 | 
| 
25
 | 
-          <div class="mb-2">头像</div>
 | 
 | 
   | 
| 
26
 | 
-          <CropperAvatar
 | 
 | 
   | 
| 
27
 | 
-            :uploadApi="uploadApi"
 | 
 | 
   | 
| 
28
 | 
-            :value="avatar"
 | 
 | 
   | 
| 
29
 | 
-            btnText="更换头像"
 | 
 | 
   | 
| 
30
 | 
-            :btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
 | 
 | 
   | 
| 
31
 | 
-            @change="updateAvatar"
 | 
 | 
   | 
| 
32
 | 
-            width="150"
 | 
 | 
   | 
| 
33
 | 
-          />
 | 
25
 | 
+          <div class="mb-2" style="font-weight: 700">个人头像</div>
 | 
| 
 | 
   | 
26
 | 
+          <Upload
 | 
| 
 | 
   | 
27
 | 
+            style="width: 20vw"
 | 
| 
 | 
   | 
28
 | 
+            name="avatar"
 | 
| 
 | 
   | 
29
 | 
+            list-type="picture-card"
 | 
| 
 | 
   | 
30
 | 
+            class="avatar-uploader"
 | 
| 
 | 
   | 
31
 | 
+            :show-upload-list="false"
 | 
| 
 | 
   | 
32
 | 
+            :customRequest="customUploadqrcodePic"
 | 
| 
 | 
   | 
33
 | 
+            :before-upload="beforeUploadqrcodePic"
 | 
| 
 | 
   | 
34
 | 
+          >
 | 
| 
 | 
   | 
35
 | 
+            <img
 | 
| 
 | 
   | 
36
 | 
+              style="text-align: center; border-radius: 50%; width: 10vw; height: 15vh"
 | 
| 
 | 
   | 
37
 | 
+              v-if="peresonalPic"
 | 
| 
 | 
   | 
38
 | 
+              :src="peresonalPic"
 | 
| 
 | 
   | 
39
 | 
+              alt="avatar"
 | 
| 
 | 
   | 
40
 | 
+            />
 | 
| 
 | 
   | 
41
 | 
+            <div v-else>
 | 
| 
 | 
   | 
42
 | 
+              <div style="margin-top: 30px">
 | 
| 
 | 
   | 
43
 | 
+                <PlusOutlined style="font-size: 30px" />
 | 
| 
 | 
   | 
44
 | 
+              </div>
 | 
| 
 | 
   | 
45
 | 
+              <div
 | 
| 
 | 
   | 
46
 | 
+                class="ant-upload-text flex"
 | 
| 
 | 
   | 
47
 | 
+                style="width: 280px; height: 130px; align-items: center"
 | 
| 
 | 
   | 
48
 | 
+              >
 | 
| 
 | 
   | 
49
 | 
+                支持.PNG、.JPG、.SVG格式,建议尺寸为300px × 300px(及以上),大小不超过2M。</div
 | 
| 
 | 
   | 
50
 | 
+              >
 | 
| 
 | 
   | 
51
 | 
+            </div>
 | 
| 
 | 
   | 
52
 | 
+          </Upload>
 | 
| 
34
 | 
         </div>
 | 
53
 | 
         </div>
 | 
| 
35
 | 
         <Description
 | 
54
 | 
         <Description
 | 
| 
36
 | 
           class="mt-8"
 | 
55
 | 
           class="mt-8"
 | 
 | 
@@ -66,13 +85,13 @@ | 
 | 
@@ -66,13 +85,13 @@ | 
| 
66
 | 
   import { BasicForm, useForm } from '/@/components/Form/index';
 | 
85
 | 
   import { BasicForm, useForm } from '/@/components/Form/index';
 | 
| 
67
 | 
   import { formSchema } from './config';
 | 
86
 | 
   import { formSchema } from './config';
 | 
| 
68
 | 
   import { Description, DescItem, useDescription } from '/@/components/Description/index';
 | 
87
 | 
   import { Description, DescItem, useDescription } from '/@/components/Description/index';
 | 
| 
69
 | 
-  import { CropperAvatar } from '/@/components/Cropper';
 | 
 | 
   | 
| 
70
 | 
-  import defaultImage from '/@/assets/images/logo.png';
 | 
 | 
   | 
| 
71
 | 
   import { uploadApi, personalPut } from '/@/api/personal/index';
 | 
88
 | 
   import { uploadApi, personalPut } from '/@/api/personal/index';
 | 
| 
72
 | 
   import { useMessage } from '/@/hooks/web/useMessage';
 | 
89
 | 
   import { useMessage } from '/@/hooks/web/useMessage';
 | 
| 
73
 | 
   import { USER_INFO_KEY } from '/@/enums/cacheEnum';
 | 
90
 | 
   import { USER_INFO_KEY } from '/@/enums/cacheEnum';
 | 
| 
74
 | 
   import { getAuthCache } from '/@/utils/auth';
 | 
91
 | 
   import { getAuthCache } from '/@/utils/auth';
 | 
| 
75
 | 
-  import { useUserStore } from '/@/store/modules/user';
 | 
92
 | 
+  import { Upload } from 'ant-design-vue';
 | 
| 
 | 
   | 
93
 | 
+  import { PlusOutlined } from '@ant-design/icons-vue';
 | 
| 
 | 
   | 
94
 | 
+  import type { FileItem } from '/@/components/Upload/src/typing';
 | 
| 
76
 | 
 
 | 
95
 | 
 
 | 
| 
77
 | 
   const schema: DescItem[] = [
 | 
96
 | 
   const schema: DescItem[] = [
 | 
| 
78
 | 
     {
 | 
97
 | 
     {
 | 
 | 
@@ -102,59 +121,91 @@ | 
 | 
@@ -102,59 +121,91 @@ | 
| 
102
 | 
   ];
 | 
121
 | 
   ];
 | 
| 
103
 | 
   export default defineComponent({
 | 
122
 | 
   export default defineComponent({
 | 
| 
104
 | 
     name: 'index',
 | 
123
 | 
     name: 'index',
 | 
| 
105
 | 
-    components: { BasicModal, BasicForm, Description, CropperAvatar },
 | 
 | 
   | 
| 
106
 | 
-    setup() {
 | 
 | 
   | 
| 
107
 | 
-      const userStore = useUserStore();
 | 
124
 | 
+    components: { BasicModal, BasicForm, Description, Upload, PlusOutlined },
 | 
| 
 | 
   | 
125
 | 
+    emits: ['refreshPersonl'],
 | 
| 
 | 
   | 
126
 | 
+    setup(_, { emit }) {
 | 
| 
108
 | 
       const userInfo = getAuthCache(USER_INFO_KEY);
 | 
127
 | 
       const userInfo = getAuthCache(USER_INFO_KEY);
 | 
| 
109
 | 
       const { createMessage } = useMessage();
 | 
128
 | 
       const { createMessage } = useMessage();
 | 
| 
110
 | 
       const getPersonalValue: any = ref({});
 | 
129
 | 
       const getPersonalValue: any = ref({});
 | 
| 
111
 | 
       const getPersonalDetailValue: any = ref({});
 | 
130
 | 
       const getPersonalDetailValue: any = ref({});
 | 
| 
112
 | 
-      const avatarUrl: any = ref('');
 | 
131
 | 
+      const updatePersonalData: any = ref({});
 | 
| 
113
 | 
       const getBackendV: any = ref({});
 | 
132
 | 
       const getBackendV: any = ref({});
 | 
| 
114
 | 
       const [registerDesc] = useDescription({
 | 
133
 | 
       const [registerDesc] = useDescription({
 | 
| 
115
 | 
         title: '个人详情',
 | 
134
 | 
         title: '个人详情',
 | 
| 
116
 | 
         schema: schema,
 | 
135
 | 
         schema: schema,
 | 
| 
117
 | 
       });
 | 
136
 | 
       });
 | 
| 
118
 | 
 
 | 
137
 | 
 
 | 
| 
119
 | 
-      const avatar = computed(() => {
 | 
 | 
   | 
| 
120
 | 
-        const { avatar } = userStore.getUserInfo;
 | 
 | 
   | 
| 
121
 | 
-        return avatarUrl.value || avatar || defaultImage;
 | 
 | 
   | 
| 
122
 | 
-      });
 | 
 | 
   | 
| 
123
 | 
-      const updateAvatar = async (v) => {
 | 
 | 
   | 
| 
124
 | 
-        avatarUrl.value = v.data.fileStaticUri;
 | 
138
 | 
+      const peresonalPic = ref();
 | 
| 
 | 
   | 
139
 | 
+
 | 
| 
 | 
   | 
140
 | 
+      const customUploadqrcodePic = async ({ file }) => {
 | 
| 
 | 
   | 
141
 | 
+        if (beforeUploadqrcodePic(file)) {
 | 
| 
 | 
   | 
142
 | 
+          const formData = new FormData();
 | 
| 
 | 
   | 
143
 | 
+          formData.append('file', file);
 | 
| 
 | 
   | 
144
 | 
+          const response = await uploadApi(formData);
 | 
| 
 | 
   | 
145
 | 
+          if (response.fileStaticUri) {
 | 
| 
 | 
   | 
146
 | 
+            peresonalPic.value = response.fileStaticUri;
 | 
| 
 | 
   | 
147
 | 
+          }
 | 
| 
 | 
   | 
148
 | 
+        }
 | 
| 
125
 | 
       };
 | 
149
 | 
       };
 | 
| 
 | 
   | 
150
 | 
+
 | 
| 
 | 
   | 
151
 | 
+      const beforeUploadqrcodePic = (file: FileItem) => {
 | 
| 
 | 
   | 
152
 | 
+        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
 | 
| 
 | 
   | 
153
 | 
+        if (!isJpgOrPng) {
 | 
| 
 | 
   | 
154
 | 
+          createMessage.error('只能上传图片文件!');
 | 
| 
 | 
   | 
155
 | 
+        }
 | 
| 
 | 
   | 
156
 | 
+        const isLt2M = (file.size as number) / 1024 / 1024 < 2;
 | 
| 
 | 
   | 
157
 | 
+        if (!isLt2M) {
 | 
| 
 | 
   | 
158
 | 
+          createMessage.error('图片大小不能超过2MB!');
 | 
| 
 | 
   | 
159
 | 
+        }
 | 
| 
 | 
   | 
160
 | 
+        return isJpgOrPng && isLt2M;
 | 
| 
 | 
   | 
161
 | 
+      };
 | 
| 
 | 
   | 
162
 | 
+
 | 
| 
126
 | 
       const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
 | 
163
 | 
       const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
 | 
| 
127
 | 
         showActionButtonGroup: false,
 | 
164
 | 
         showActionButtonGroup: false,
 | 
| 
128
 | 
         schemas: formSchema,
 | 
165
 | 
         schemas: formSchema,
 | 
| 
129
 | 
       });
 | 
166
 | 
       });
 | 
| 
130
 | 
 
 | 
167
 | 
 
 | 
| 
131
 | 
       const [registerModal, { closeModal }] = useModalInner(async (data) => {
 | 
168
 | 
       const [registerModal, { closeModal }] = useModalInner(async (data) => {
 | 
| 
132
 | 
-        setFieldsValue({
 | 
 | 
   | 
| 
133
 | 
-          realName: data.userInfo.realName,
 | 
 | 
   | 
| 
134
 | 
-          phoneNumber: data.userInfo.phoneNumber,
 | 
 | 
   | 
| 
135
 | 
-          email: data.userInfo.email,
 | 
 | 
   | 
| 
136
 | 
-        });
 | 
 | 
   | 
| 
137
 | 
-        getPersonalDetailValue.value = data.userInfo;
 | 
169
 | 
+        (peresonalPic.value = data.userInfo.avatar),
 | 
| 
 | 
   | 
170
 | 
+          setFieldsValue({
 | 
| 
 | 
   | 
171
 | 
+            realName: data.userInfo.realName,
 | 
| 
 | 
   | 
172
 | 
+            phoneNumber: data.userInfo.phoneNumber,
 | 
| 
 | 
   | 
173
 | 
+            email: data.userInfo.email,
 | 
| 
 | 
   | 
174
 | 
+          });
 | 
| 
 | 
   | 
175
 | 
+        if (data.userInfo) {
 | 
| 
 | 
   | 
176
 | 
+          getPersonalDetailValue.value = data.userInfo;
 | 
| 
 | 
   | 
177
 | 
+        }
 | 
| 
 | 
   | 
178
 | 
+        if (Object.keys(updatePersonalData.value).length != 0) {
 | 
| 
 | 
   | 
179
 | 
+          getPersonalDetailValue.value = updatePersonalData.value;
 | 
| 
 | 
   | 
180
 | 
+          peresonalPic.value = updatePersonalData.value.avatar;
 | 
| 
 | 
   | 
181
 | 
+          setFieldsValue({
 | 
| 
 | 
   | 
182
 | 
+            realName: updatePersonalData.value.realName,
 | 
| 
 | 
   | 
183
 | 
+            phoneNumber: updatePersonalData.value.phoneNumber,
 | 
| 
 | 
   | 
184
 | 
+            email: updatePersonalData.value.email,
 | 
| 
 | 
   | 
185
 | 
+          });
 | 
| 
 | 
   | 
186
 | 
+        }
 | 
| 
138
 | 
       });
 | 
187
 | 
       });
 | 
| 
139
 | 
       const handleSubmit = async () => {
 | 
188
 | 
       const handleSubmit = async () => {
 | 
| 
140
 | 
         const getUserInfo = await userInfo;
 | 
189
 | 
         const getUserInfo = await userInfo;
 | 
| 
141
 | 
         getPersonalValue.value = await validate();
 | 
190
 | 
         getPersonalValue.value = await validate();
 | 
| 
142
 | 
         getPersonalValue.value.id = getUserInfo.userId;
 | 
191
 | 
         getPersonalValue.value.id = getUserInfo.userId;
 | 
| 
143
 | 
         getPersonalValue.value.username = getBackendV.value.username;
 | 
192
 | 
         getPersonalValue.value.username = getBackendV.value.username;
 | 
| 
144
 | 
-        getPersonalValue.value.avatar = avatarUrl.value;
 | 
 | 
   | 
| 
145
 | 
-        await personalPut(getPersonalValue.value);
 | 
193
 | 
+        getPersonalValue.value.avatar = peresonalPic.value;
 | 
| 
 | 
   | 
194
 | 
+        const data = await personalPut(getPersonalValue.value);
 | 
| 
 | 
   | 
195
 | 
+        updatePersonalData.value = data;
 | 
| 
146
 | 
         createMessage.success('修改成功');
 | 
196
 | 
         createMessage.success('修改成功');
 | 
| 
147
 | 
         closeModal();
 | 
197
 | 
         closeModal();
 | 
| 
148
 | 
         resetFields();
 | 
198
 | 
         resetFields();
 | 
| 
 | 
   | 
199
 | 
+        emit('refreshPersonl', updatePersonalData.value);
 | 
| 
149
 | 
       };
 | 
200
 | 
       };
 | 
| 
150
 | 
       const compHeight = computed(() => {
 | 
201
 | 
       const compHeight = computed(() => {
 | 
| 
151
 | 
         return 1000;
 | 
202
 | 
         return 1000;
 | 
| 
152
 | 
       });
 | 
203
 | 
       });
 | 
| 
153
 | 
       return {
 | 
204
 | 
       return {
 | 
| 
154
 | 
-        uploadApi,
 | 
205
 | 
+        peresonalPic,
 | 
| 
 | 
   | 
206
 | 
+        beforeUploadqrcodePic,
 | 
| 
 | 
   | 
207
 | 
+        customUploadqrcodePic,
 | 
| 
155
 | 
         compHeight,
 | 
208
 | 
         compHeight,
 | 
| 
156
 | 
-        updateAvatar,
 | 
 | 
   | 
| 
157
 | 
-        avatar,
 | 
 | 
   | 
| 
158
 | 
         handleSubmit,
 | 
209
 | 
         handleSubmit,
 | 
| 
159
 | 
         getPersonalDetailValue,
 | 
210
 | 
         getPersonalDetailValue,
 | 
| 
160
 | 
         registerDesc,
 | 
211
 | 
         registerDesc,
 | 
 | 
@@ -165,4 +216,22 @@ | 
 | 
@@ -165,4 +216,22 @@ | 
| 
165
 | 
     },
 | 
216
 | 
     },
 | 
| 
166
 | 
   });
 | 
217
 | 
   });
 | 
| 
167
 | 
 </script>
 | 
218
 | 
 </script>
 | 
| 
168
 | 
-<style lang="less"></style> | 
219
 | 
+<style scoped lang="less">
 | 
| 
 | 
   | 
220
 | 
+  .change-avatar {
 | 
| 
 | 
   | 
221
 | 
+    /deep/ .ant-upload-select-picture-card {
 | 
| 
 | 
   | 
222
 | 
+      display: inherit;
 | 
| 
 | 
   | 
223
 | 
+      float: none;
 | 
| 
 | 
   | 
224
 | 
+      width: 10vw;
 | 
| 
 | 
   | 
225
 | 
+      height: 17vh;
 | 
| 
 | 
   | 
226
 | 
+      margin-right: 8px;
 | 
| 
 | 
   | 
227
 | 
+      margin-bottom: 8px;
 | 
| 
 | 
   | 
228
 | 
+      text-align: center;
 | 
| 
 | 
   | 
229
 | 
+      vertical-align: top;
 | 
| 
 | 
   | 
230
 | 
+      background-color: #fafafa;
 | 
| 
 | 
   | 
231
 | 
+      border: 1px dashed #d9d9d9;
 | 
| 
 | 
   | 
232
 | 
+      border-radius: 50%;
 | 
| 
 | 
   | 
233
 | 
+      cursor: pointer;
 | 
| 
 | 
   | 
234
 | 
+      transition: border-color 0.3s ease;
 | 
| 
 | 
   | 
235
 | 
+    }
 | 
| 
 | 
   | 
236
 | 
+  }
 | 
| 
 | 
   | 
237
 | 
+</style> |