mirror of
https://github.com/ccmjga/zhilu-admin
synced 2026-04-14 13:23:39 +00:00
fix bugs
This commit is contained in:
@@ -18,9 +18,12 @@ import io.minio.PutObjectArgs;
|
|||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jooq.generated.mjga.tables.pojos.User;
|
import org.jooq.generated.mjga.tables.pojos.User;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@@ -41,13 +44,29 @@ public class IdentityAccessController {
|
|||||||
private final MinioClient minioClient;
|
private final MinioClient minioClient;
|
||||||
private final MinIoConfig minIoConfig;
|
private final MinIoConfig minIoConfig;
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)")
|
||||||
@PostMapping(
|
@PostMapping(
|
||||||
value = "/avatar/upload",
|
value = "/avatar/upload",
|
||||||
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
|
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
|
||||||
produces = MediaType.TEXT_PLAIN_VALUE)
|
produces = MediaType.TEXT_PLAIN_VALUE)
|
||||||
public String uploadAvatar(Principal principal, @RequestPart("file") MultipartFile multipartFile)
|
public String uploadAvatar(@RequestPart("file") MultipartFile multipartFile) throws Exception {
|
||||||
throws Exception {
|
String originalFilename = multipartFile.getOriginalFilename();
|
||||||
String objectName = String.format("/avatar/%s/avatar.jpg", principal.getName());
|
if (StringUtils.isEmpty(originalFilename)) {
|
||||||
|
throw new BusinessException("文件名不能为空");
|
||||||
|
}
|
||||||
|
String contentType = multipartFile.getContentType();
|
||||||
|
String extension = "";
|
||||||
|
if ("image/jpeg".equals(contentType)) {
|
||||||
|
extension = ".jpg";
|
||||||
|
} else if ("image/png".equals(contentType)) {
|
||||||
|
extension = ".png";
|
||||||
|
}
|
||||||
|
String objectName =
|
||||||
|
String.format(
|
||||||
|
"/avatar/%d%s%s",
|
||||||
|
Instant.now().toEpochMilli(),
|
||||||
|
RandomStringUtils.insecure().nextAlphabetic(6),
|
||||||
|
extension);
|
||||||
if (multipartFile.isEmpty()) {
|
if (multipartFile.isEmpty()) {
|
||||||
throw new BusinessException("上传的文件不能为空");
|
throw new BusinessException("上传的文件不能为空");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.zl.mjga.dto.urp;
|
package com.zl.mjga.dto.urp;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -9,15 +8,8 @@ import lombok.*;
|
|||||||
@Builder
|
@Builder
|
||||||
public class PermissionRespDto {
|
public class PermissionRespDto {
|
||||||
|
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
private Boolean isBound;
|
private Boolean isBound;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1718,12 +1718,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PermissionRespDto": {
|
"PermissionRespDto": {
|
||||||
"required": [
|
|
||||||
"code",
|
|
||||||
"id",
|
|
||||||
"isBound",
|
|
||||||
"name"
|
|
||||||
],
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
|
|||||||
3752
frontend/src/api/types/schema.d.ts
vendored
3752
frontend/src/api/types/schema.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@@ -54,8 +54,8 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" @click.prevent="handleSubmit"
|
<button type="submit" @click.prevent="handleSubmit" :disabled="uploadLoading"
|
||||||
class="mt-5 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center">
|
class="mt-5 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@@ -84,6 +84,8 @@ const { user, onSubmit } = defineProps<{
|
|||||||
const formData = ref();
|
const formData = ref();
|
||||||
const { uploadUserAvatar } = useUserUpsert();
|
const { uploadUserAvatar } = useUserUpsert();
|
||||||
const { showAlert } = useAlertStore();
|
const { showAlert } = useAlertStore();
|
||||||
|
const uploadLoading = ref(false);
|
||||||
|
|
||||||
|
|
||||||
const updateFormData = (newUser: typeof user) => {
|
const updateFormData = (newUser: typeof user) => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
@@ -104,7 +106,7 @@ const validateFile = (file?: File) => {
|
|||||||
if (!file) {
|
if (!file) {
|
||||||
throw new ValidationError("您未选择文件");
|
throw new ValidationError("您未选择文件");
|
||||||
}
|
}
|
||||||
const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
|
const allowedTypes = ["image/jpeg", "image/png"];
|
||||||
if (!allowedTypes.includes(file.type)) {
|
if (!allowedTypes.includes(file.type)) {
|
||||||
throw new ValidationError("不支持的文件类型");
|
throw new ValidationError("不支持的文件类型");
|
||||||
}
|
}
|
||||||
@@ -116,6 +118,7 @@ const validateFile = (file?: File) => {
|
|||||||
|
|
||||||
const handleFileChange = (event: Event) => {
|
const handleFileChange = (event: Event) => {
|
||||||
const file = (event.target as HTMLInputElement).files?.[0];
|
const file = (event.target as HTMLInputElement).files?.[0];
|
||||||
|
uploadLoading.value = true;
|
||||||
try {
|
try {
|
||||||
validateFile(file);
|
validateFile(file);
|
||||||
new Compressor(file!, {
|
new Compressor(file!, {
|
||||||
@@ -125,6 +128,7 @@ const handleFileChange = (event: Event) => {
|
|||||||
mimeType: "auto", // 自动选择最佳格式
|
mimeType: "auto", // 自动选择最佳格式
|
||||||
success: async (compressedFile: File) => {
|
success: async (compressedFile: File) => {
|
||||||
formData.value.avatar = await uploadUserAvatar(compressedFile);
|
formData.value.avatar = await uploadUserAvatar(compressedFile);
|
||||||
|
uploadLoading.value = false;
|
||||||
showAlert({
|
showAlert({
|
||||||
content: "上传成功",
|
content: "上传成功",
|
||||||
level: "success",
|
level: "success",
|
||||||
@@ -136,6 +140,7 @@ const handleFileChange = (event: Event) => {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
(event.target as HTMLInputElement).value = "";
|
(event.target as HTMLInputElement).value = "";
|
||||||
|
uploadLoading.value = false;
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user