提交 ff14ceb5 编写于 作者: 查尔斯-BUG万象集's avatar 查尔斯-BUG万象集

feat: 新增公共上传接口,完善系统配置 Logo、favicon 上传

上级 adf7ec5d
......@@ -38,3 +38,7 @@ export function listRoleDict(params: RoleParam) {
export function listDict(code: string) {
return axios.get<LabelValueState[]>(`${BASE_URL}/dict/${code}`);
}
export function upload(data: FormData) {
return axios.post(`${BASE_URL}/file`, data);
}
export default function getFile(file: string | undefined) {
if (file) {
const baseUrl = import.meta.env.VITE_API_BASE_URL;
if (
!file.startsWith('http://') &&
!file.startsWith('https://') &&
!file.startsWith('blob:')
) {
return `${baseUrl}/file/${file}`;
}
}
return file;
}
......@@ -16,6 +16,7 @@
<br />
<a-upload
:file-list="faviconFile ? [faviconFile] : []"
accept="image/*"
:show-file-list="false"
:custom-request="handleUploadFavicon"
@change="handleChangeFavicon"
......@@ -32,7 +33,7 @@
v-if="faviconFile && faviconFile.url"
class="arco-upload-list-picture custom-upload-avatar favicon"
>
<img :src="faviconFile.url" />
<img :src="getFile(faviconFile.url)" />
<div
v-if="isEdit"
class="arco-upload-list-picture-mask favicon"
......@@ -59,6 +60,7 @@
<br />
<a-upload
:file-list="logoFile ? [logoFile] : []"
accept="image/*"
:show-file-list="false"
:custom-request="handleUploadLogo"
@change="handleChangeLogo"
......@@ -75,7 +77,7 @@
v-if="logoFile && logoFile.url"
class="arco-upload-list-picture custom-upload-avatar logo"
>
<img :src="logoFile.url" />
<img :src="getFile(logoFile.url)" />
<div
v-if="isEdit"
class="arco-upload-list-picture-mask logo"
......@@ -109,22 +111,22 @@
>
<a-input v-model="form.site_copyright" placeholder="请输入版权信息" />
</a-form-item>
<div>
<div style="margin-top: 20px">
<a-space>
<a-button
v-if="!isEdit"
v-permission="['system:config:update']"
type="primary"
@click="toEdit"
v-permission="['system:config:reset']"
@click="toResetValue"
>
<template #icon><icon-edit /></template>修改
<template #icon><icon-redo /></template>恢复默认
</a-button>
<a-button
v-if="!isEdit"
v-permission="['system:config:reset']"
@click="toResetValue"
v-permission="['system:config:update']"
type="primary"
@click="toEdit"
>
<template #icon><icon-redo /></template>恢复默认
<template #icon><icon-edit /></template>修改
</a-button>
<a-button
v-if="isEdit"
......@@ -166,6 +168,8 @@
save,
resetValue,
} from '@/api/system/config';
import { upload } from '@/api/common';
import getFile from '@/utils/file';
const { proxy } = getCurrentInstance() as any;
const dataList = ref<DataRecord[]>([]);
......@@ -189,6 +193,20 @@
});
const { queryParams, form, rules } = toRefs(data);
/**
* 重置表单
*/
const reset = () => {
form.value = {
site_title: siteTitle.value?.value,
site_copyright: siteCopyright.value?.value,
site_logo: siteLogo.value?.value,
site_favicon: siteFavicon.value?.value,
};
logoFile.value.url = siteLogo.value?.value;
faviconFile.value.url = siteFavicon.value?.value;
};
/**
* 查询配置
*/
......@@ -207,14 +225,7 @@
siteFavicon.value = dataList.value.find(
(option) => option.code === 'site_favicon'
);
form.value = {
site_title: siteTitle.value?.value,
site_copyright: siteCopyright.value?.value,
site_logo: siteLogo.value?.value,
site_favicon: siteFavicon.value?.value,
};
logoFile.value.url = siteLogo.value?.value;
faviconFile.value.url = siteFavicon.value?.value;
reset();
};
getConfig();
......@@ -254,8 +265,28 @@
* @param options /
*/
const handleUploadLogo = (options: RequestOption) => {
console.log(options);
const controller = new AbortController();
(async function requestWrap() {
const {
onProgress,
onError,
onSuccess,
fileItem,
name = 'file',
} = options;
onProgress(20);
const formData = new FormData();
formData.append(name as string, fileItem.file as Blob);
upload(formData)
.then((res) => {
onSuccess(res);
form.value.site_logo = res.data;
proxy.$message.success(res.msg);
})
.catch((error) => {
onError(error);
});
})();
return {
abort() {
controller.abort();
......@@ -269,8 +300,28 @@
* @param options /
*/
const handleUploadFavicon = (options: RequestOption) => {
console.log(options);
const controller = new AbortController();
(async function requestWrap() {
const {
onProgress,
onError,
onSuccess,
fileItem,
name = 'file',
} = options;
onProgress(20);
const formData = new FormData();
formData.append(name as string, fileItem.file as Blob);
upload(formData)
.then((res) => {
onSuccess(res);
form.value.site_favicon = res.data;
proxy.$message.success(res.msg);
})
.catch((error) => {
onError(error);
});
})();
return {
abort() {
controller.abort();
......@@ -287,7 +338,6 @@
const handleChangeLogo = (_: any, currentFile: any) => {
logoFile.value = {
...currentFile,
// url: URL.createObjectURL(currentFile.file),
};
};
......@@ -300,7 +350,6 @@
const handleChangeFavicon = (_: any, currentFile: any) => {
faviconFile.value = {
...currentFile,
// url: URL.createObjectURL(currentFile.file),
};
};
......@@ -335,13 +384,6 @@
const toEdit = () => {
isEdit.value = true;
};
/**
* 重置表单
*/
const reset = () => {
proxy.$refs.formRef?.resetFields();
};
</script>
<style scoped lang="less">
......@@ -359,7 +401,8 @@
line-height: 16px;
}
.arco-form .image-item {
.arco-form .image-item,
.input-item {
margin-bottom: 0;
}
......
export default {
'menu.system.config': '系统配置(开发中)',
'menu.system.config': '系统配置',
};
......@@ -3,6 +3,7 @@
<a-space :size="54">
<a-upload
:file-list="avatarList"
accept="image/*"
:show-file-list="false"
list-type="picture-card"
:show-upload-button="true"
......
......@@ -16,12 +16,15 @@
package top.charles7c.cnadmin.webapi.controller.common;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import io.swagger.v3.oas.annotations.Operation;
......@@ -31,21 +34,23 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import top.charles7c.cnadmin.common.base.BaseEnum;
import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties;
import top.charles7c.cnadmin.common.config.properties.ProjectProperties;
import top.charles7c.cnadmin.common.constant.CacheConsts;
import top.charles7c.cnadmin.common.model.query.SortQuery;
import top.charles7c.cnadmin.common.model.vo.LabelValueVO;
import top.charles7c.cnadmin.common.model.vo.R;
import top.charles7c.cnadmin.common.util.FileUtils;
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
import top.charles7c.cnadmin.common.util.validate.ValidationUtils;
import top.charles7c.cnadmin.monitor.annotation.Log;
import top.charles7c.cnadmin.system.model.query.DeptQuery;
import top.charles7c.cnadmin.system.model.query.MenuQuery;
......@@ -72,6 +77,20 @@ public class CommonController {
private final RoleService roleService;
private final DictItemService dictItemService;
private final ProjectProperties projectProperties;
private final LocalStorageProperties localStorageProperties;
@Operation(summary = "上传文件", description = "上传文件")
@PostMapping("/file")
public R<String> upload(@NotNull(message = "文件不能为空") MultipartFile file) {
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
Long maxSizeInMb = localStorageProperties.getMaxSizeInMb();
CheckUtils.throwIf(file.getSize() > maxSizeInMb * 1024 * 1024, "请上传小于 {}MB 的文件", maxSizeInMb);
String filePath = localStorageProperties.getPath().getFile();
File newFile = FileUtils.upload(file, filePath, false);
CheckUtils.throwIfNull(newFile, "上传文件失败");
assert null != newFile;
return R.ok("上传成功", newFile.getName());
}
@Operation(summary = "查询部门树", description = "查询树结构的部门列表")
@GetMapping("/tree/dept")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册