This commit is contained in:
Chuck1sn
2025-06-16 11:26:20 +08:00
parent ea10b156e3
commit 621170b347
5 changed files with 1906 additions and 1896 deletions

View File

@@ -18,9 +18,12 @@ import io.minio.PutObjectArgs;
import jakarta.validation.Valid;
import java.awt.image.BufferedImage;
import java.security.Principal;
import java.time.Instant;
import java.util.List;
import javax.imageio.ImageIO;
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.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -41,13 +44,29 @@ public class IdentityAccessController {
private final MinioClient minioClient;
private final MinIoConfig minIoConfig;
@PreAuthorize("hasAuthority(T(com.zl.mjga.model.urp.EPermission).WRITE_USER_ROLE_PERMISSION)")
@PostMapping(
value = "/avatar/upload",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.TEXT_PLAIN_VALUE)
public String uploadAvatar(Principal principal, @RequestPart("file") MultipartFile multipartFile)
throws Exception {
String objectName = String.format("/avatar/%s/avatar.jpg", principal.getName());
public String uploadAvatar(@RequestPart("file") MultipartFile multipartFile) throws Exception {
String originalFilename = multipartFile.getOriginalFilename();
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()) {
throw new BusinessException("上传的文件不能为空");
}

View File

@@ -1,6 +1,5 @@
package com.zl.mjga.dto.urp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@AllArgsConstructor
@@ -9,15 +8,8 @@ import lombok.*;
@Builder
public class PermissionRespDto {
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private Long id;
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String code;
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean isBound;
}

View File

@@ -1718,12 +1718,6 @@
}
},
"PermissionRespDto": {
"required": [
"code",
"id",
"isBound",
"name"
],
"type": "object",
"properties": {
"id": {

File diff suppressed because it is too large Load Diff

View File

@@ -54,8 +54,8 @@
</select>
</div>
</div>
<button type="submit" @click.prevent="handleSubmit"
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">
<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 disabled:opacity-50 disabled:cursor-not-allowed">
保存
</button>
</form>
@@ -84,6 +84,8 @@ const { user, onSubmit } = defineProps<{
const formData = ref();
const { uploadUserAvatar } = useUserUpsert();
const { showAlert } = useAlertStore();
const uploadLoading = ref(false);
const updateFormData = (newUser: typeof user) => {
formData.value = {
@@ -104,7 +106,7 @@ const validateFile = (file?: File) => {
if (!file) {
throw new ValidationError("您未选择文件");
}
const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
const allowedTypes = ["image/jpeg", "image/png"];
if (!allowedTypes.includes(file.type)) {
throw new ValidationError("不支持的文件类型");
}
@@ -116,6 +118,7 @@ const validateFile = (file?: File) => {
const handleFileChange = (event: Event) => {
const file = (event.target as HTMLInputElement).files?.[0];
uploadLoading.value = true;
try {
validateFile(file);
new Compressor(file!, {
@@ -125,6 +128,7 @@ const handleFileChange = (event: Event) => {
mimeType: "auto", // 自动选择最佳格式
success: async (compressedFile: File) => {
formData.value.avatar = await uploadUserAvatar(compressedFile);
uploadLoading.value = false;
showAlert({
content: "上传成功",
level: "success",
@@ -136,6 +140,7 @@ const handleFileChange = (event: Event) => {
});
} catch (error) {
(event.target as HTMLInputElement).value = "";
uploadLoading.value = false;
throw error;
}
};