feat: 评论接口对接
This commit is contained in:
@@ -17,7 +17,7 @@ VITE_TITLE_NAME='五味子云存储'
|
|||||||
VITE_APP_TOKEN_KEY='schisandra'
|
VITE_APP_TOKEN_KEY='schisandra'
|
||||||
|
|
||||||
# the upload url
|
# the upload url
|
||||||
VITE_UPLOAD_URL='http://127.0.0.1:3000'
|
VITE_UPLOAD_URL='http://127.0.0.1:5050'
|
||||||
|
|
||||||
# the websocket url
|
# the websocket url
|
||||||
VITE_WEB_SOCKET_URL='ws://127.0.0.1:3010/wx/socket'
|
VITE_WEB_SOCKET_URL='ws://127.0.0.1:3010/wx/socket'
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.eslintrc.cjs
|
.eslintrc.cjs
|
||||||
dist
|
dist
|
||||||
/src/components/Main/Home/index.tsx
|
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
"antd": "^5.19.1",
|
"antd": "^5.19.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
|
"base-64": "^1.0.0",
|
||||||
"core-js": "^3.37.1",
|
"core-js": "^3.37.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"echarts-for-react": "^3.0.2",
|
"echarts-for-react": "^3.0.2",
|
||||||
|
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@@ -44,6 +44,9 @@ dependencies:
|
|||||||
axios:
|
axios:
|
||||||
specifier: ^1.7.2
|
specifier: ^1.7.2
|
||||||
version: 1.7.2
|
version: 1.7.2
|
||||||
|
base-64:
|
||||||
|
specifier: ^1.0.0
|
||||||
|
version: 1.0.0
|
||||||
core-js:
|
core-js:
|
||||||
specifier: ^3.37.1
|
specifier: ^3.37.1
|
||||||
version: 3.37.1
|
version: 3.37.1
|
||||||
@@ -4647,6 +4650,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
|
resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/base-64@1.0.0:
|
||||||
|
resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/base64-js@1.5.1:
|
/base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@@ -5,13 +5,15 @@ import web from "@/utils/axios/web.ts";
|
|||||||
/**
|
/**
|
||||||
* 初始化ali oss
|
* 初始化ali oss
|
||||||
* @param data 用户id
|
* @param data 用户id
|
||||||
|
* @param Id id
|
||||||
*/
|
*/
|
||||||
export const initAliOSS = (data: any) => {
|
export const initAliOSS = (data: any, Id: any) => {
|
||||||
return web.request({
|
return web.request({
|
||||||
url: "/oss/oss/ali/init",
|
url: "/oss/oss/ali/init",
|
||||||
method: "post",
|
method: "get",
|
||||||
params: {
|
params: {
|
||||||
userId: data,
|
userId: data,
|
||||||
|
Id: Id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -59,3 +61,74 @@ export const getAllAliOSSConfig = (userId: any) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 新增阿里云oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addAliOSSConfig = (data: API.AliOSSConfigRequest) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/ali/add`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 注销阿里云oss配置
|
||||||
|
* @param userId
|
||||||
|
* @param Id
|
||||||
|
*/
|
||||||
|
export const setAliShutdown = (userId: any, Id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/ali/shutdown`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
Id: Id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 删除阿里云oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const deleteAliConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/ali/delete`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改阿里云oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const updateAliConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/ali/update`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取阿里云oss配置详情
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getAliConfigDetailById = (id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/ali/one`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@@ -167,3 +167,191 @@ export const getUserRecentPreviewFile = (userId: any) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 获取存储桶
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
export const deleteBucket = (userId: any, bucket: any, type: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/deleteBucket`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取存储桶大小
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
export const getBucketSize = (userId: any, bucket: any, type: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/getBucketSize`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 创建存储桶
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
export const creatBucket = (userId: any, bucket: any, type: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/createBucket`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
* @param filePath
|
||||||
|
*/
|
||||||
|
export const deleteFile = (userId: any, bucket: any, type: any, filePath: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/deleteFile`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
filePath: filePath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
* @param listObjectsArgs
|
||||||
|
*/
|
||||||
|
export const downloadFiles = (userId: any, bucket: any, type: any, listObjectsArgs: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/downloadFile`,
|
||||||
|
method: "get",
|
||||||
|
responseType: "blob",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
listObjectsArgs: listObjectsArgs,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 预览文件
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
* @param filePath
|
||||||
|
*/
|
||||||
|
export const previewFile = (userId: any, bucket: any, type: any, filePath: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/previewFile`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
filePath: filePath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 重命名文件
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
* @param oldFileName
|
||||||
|
* @param newFileName
|
||||||
|
*/
|
||||||
|
export const renameFile = (
|
||||||
|
userId: any,
|
||||||
|
bucket: any,
|
||||||
|
type: any,
|
||||||
|
oldFileName: any,
|
||||||
|
newFileName: any,
|
||||||
|
) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/renameFile`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
oldFileName: oldFileName,
|
||||||
|
newFileName: newFileName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 拷贝文件
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
* @param oldFilePath
|
||||||
|
* @param newFilePath
|
||||||
|
*/
|
||||||
|
export const copyFile = (
|
||||||
|
userId: any,
|
||||||
|
bucket: any,
|
||||||
|
type: any,
|
||||||
|
oldFilePath: any,
|
||||||
|
newFilePath: any,
|
||||||
|
) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/copyFile`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
oldFilePath: oldFilePath,
|
||||||
|
newFilePath: newFilePath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 创建存储桶
|
||||||
|
* @param userId
|
||||||
|
* @param bucket
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
export const createBucket = (userId: any, bucket: any, type: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/createBucket`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
bucket: bucket,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param type
|
||||||
|
* @param data
|
||||||
|
* @param peram
|
||||||
|
*/
|
||||||
|
export const uploadFiles = (type: any, data: any, peram: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/` + type + `/uploadFile`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
params: peram,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@@ -5,13 +5,15 @@ import web from "@/utils/axios/web.ts";
|
|||||||
/**
|
/**
|
||||||
* 初始化minio
|
* 初始化minio
|
||||||
* @param data 用户id
|
* @param data 用户id
|
||||||
|
* @param id
|
||||||
*/
|
*/
|
||||||
export const initMinioOSS = (data: any) => {
|
export const initMinioOSS = (data: any, id: any) => {
|
||||||
return web.request({
|
return web.request({
|
||||||
url: "/oss/oss/minio/init",
|
url: "/oss/oss/minio/init",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: {
|
params: {
|
||||||
userId: data,
|
userId: data,
|
||||||
|
Id: id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -58,3 +60,75 @@ export const getAllMinioConfig = (userId: any) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 新增阿里云oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addMinioOSSConfig = (data: API.MinioOSSConfigRequest) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/minio/add`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 注销MinIo oss配置
|
||||||
|
* @param userId
|
||||||
|
* @param Id
|
||||||
|
*/
|
||||||
|
export const setMinioShutdown = (userId: any, Id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/minio/shutdown`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
Id: Id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Minio oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const deleteMinioConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/minio/delete`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Minio oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const updateMinioConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/minio/update`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取Minio oss配置详情
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getMinioConfigDetailById = (id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/minio/one`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
Id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@@ -5,13 +5,15 @@ import web from "@/utils/axios/web.ts";
|
|||||||
/**
|
/**
|
||||||
* 初始化qiniu
|
* 初始化qiniu
|
||||||
* @param data 用户id
|
* @param data 用户id
|
||||||
|
* @param id
|
||||||
*/
|
*/
|
||||||
export const initQiniuOSS = (data: any) => {
|
export const initQiniuOSS = (data: any, id: any) => {
|
||||||
return web.request({
|
return web.request({
|
||||||
url: "/oss/oss/qiniu/init",
|
url: "/oss/oss/qiniu/init",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: {
|
params: {
|
||||||
userId: data,
|
userId: data,
|
||||||
|
Id: id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -55,3 +57,77 @@ export const getAllQiniuConfigs = (userId: any) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增七牛oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addQiniuOSSConfig = (data: API.QiniuOSSConfigRequest) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/qiniu/add`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销 Qiniu oss配置
|
||||||
|
* @param userId
|
||||||
|
* @param Id
|
||||||
|
*/
|
||||||
|
export const setQiniuShutdown = (userId: any, Id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/qiniu/shutdown`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
Id: Id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Qiniu oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const deleteQiniuConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/qiniu/delete`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新Qiniu oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const updateQiniuConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/qiniu/update`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取Qiniu oss配置
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getQiniuConfigDetailById = (id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/qiniu/one`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
Id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@@ -5,13 +5,15 @@ import web from "@/utils/axios/web.ts";
|
|||||||
/**
|
/**
|
||||||
* 初始化Tencent oss
|
* 初始化Tencent oss
|
||||||
* @param data 用户id
|
* @param data 用户id
|
||||||
|
* @param id
|
||||||
*/
|
*/
|
||||||
export const initTencentOSS = (data: any) => {
|
export const initTencentOSS = (data: any, id: any) => {
|
||||||
return web.request({
|
return web.request({
|
||||||
url: "/oss/oss/ali/tencent",
|
url: "/oss/oss/tencent/init",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: {
|
params: {
|
||||||
userId: data,
|
userId: data,
|
||||||
|
Id: id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -58,3 +60,76 @@ export const getAllTencentOSsConfig = (userId: any) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 新增腾讯云oss
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addTencentOSSConfig = (data: API.TencentOSSConfigRequest) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/tencent/add`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销 Tencent oss配置
|
||||||
|
* @param userId
|
||||||
|
* @param Id
|
||||||
|
*/
|
||||||
|
export const setTencentShutdown = (userId: any, Id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/tencent/shutdown`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
Id: Id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Tencent oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const deleteTencentConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/tencent/delete`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新Tencent oss配置
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const updateTencentConfig = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/tencent/update`,
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取腾讯云oss配置详情
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getTencentConfigDetailById = (id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/oss/oss/tencent/one`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
Id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
123
src/api/share/index.ts
Normal file
123
src/api/share/index.ts
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/** @format */
|
||||||
|
|
||||||
|
import web from "@/utils/axios/web.ts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分享圈列表
|
||||||
|
*/
|
||||||
|
export const getShareCircleList = () => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/circle/sharelist`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 新增分享圈
|
||||||
|
* @param data
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export const addShareCircle = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/circle/add`,
|
||||||
|
method: "post",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 分享圈详情列表
|
||||||
|
* @param circleId
|
||||||
|
*/
|
||||||
|
export const shareDetailList = (circleId: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/detail/list`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
circleId: circleId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 分享圈详情
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getShareDetail = (id: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/detail/get_detail`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
Id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 新增分享圈详情
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addShareDetail = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/detail/add_detail`,
|
||||||
|
method: "post",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 分享圈详情评论列表
|
||||||
|
* @param detailId
|
||||||
|
*/
|
||||||
|
export const listComment = (detailId: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/comment/reply/listcomment`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
detailId: detailId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 分享圈详情回复列表
|
||||||
|
* @param commentId
|
||||||
|
*/
|
||||||
|
export const listReply = (commentId: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/comment/reply/listreply`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
commentId: commentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 新增评论
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addComment = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/comment/reply/addcomment`,
|
||||||
|
method: "post",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 新增回复
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addReply = (data: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/comment/reply/addreply`,
|
||||||
|
method: "post",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 返回评论总数
|
||||||
|
* @param detailId
|
||||||
|
*/
|
||||||
|
export const returnAllCommentAndReplyCount = (detailId: any) => {
|
||||||
|
return web.request({
|
||||||
|
url: `/share/share/comment/reply/returncount`,
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
detailId: detailId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@@ -1,29 +1,20 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { Avatar, Button, message, Skeleton } from "antd";
|
import { Avatar, Button, Form, Input, message, Modal, Popconfirm, Popover, Skeleton } from "antd";
|
||||||
import { DrawerForm, ProCard, ProForm, ProFormText } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import styles from "./index.module.less";
|
import { ClusterOutlined, DeleteOutlined, ReloadOutlined } from "@ant-design/icons";
|
||||||
import bucket from "@/assets/icons/bucket.svg";
|
import bucket from "@/assets/icons/bucket.svg";
|
||||||
|
import styles from "./index.module.less";
|
||||||
|
import { creatBucket, deleteBucket, getBucketSize } from "@/api/oss";
|
||||||
import { getAllAliOSsBucket } from "@/api/oss/ali";
|
import { getAllAliOSsBucket } from "@/api/oss/ali";
|
||||||
import { EditOutlined, EllipsisOutlined, ReloadOutlined, SettingOutlined } from "@ant-design/icons";
|
|
||||||
|
|
||||||
const DrawerContext = createContext<{
|
|
||||||
drawerVisit: boolean;
|
|
||||||
setDrawerVisit: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
}>({} as any);
|
|
||||||
const AliDrawer = () => {
|
const AliDrawer = () => {
|
||||||
const [drawerVisit, setDrawerVisit] = useState(false);
|
|
||||||
return (
|
|
||||||
<DrawerContext.Provider value={{ drawerVisit, setDrawerVisit }}>
|
|
||||||
<ProCardComponent />
|
|
||||||
</DrawerContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const ProCardComponent = () => {
|
|
||||||
const { drawerVisit, setDrawerVisit } = useContext(DrawerContext);
|
|
||||||
const [buckets, setBuckets] = useState<any>([]);
|
const [buckets, setBuckets] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [bucketSize, setBucketSize] = useState<string>("");
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
async function getAllBucket() {
|
async function getAllBucket() {
|
||||||
getAllAliOSsBucket("2").then((res: any) => {
|
getAllAliOSsBucket("2").then((res: any) => {
|
||||||
@@ -37,10 +28,11 @@ const ProCardComponent = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllBucket().then();
|
getAllBucket().then();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const bucketList = () => {
|
const bucketList = () => {
|
||||||
return (
|
return (
|
||||||
<ProCard
|
<ProCard
|
||||||
title={"阿里云OSS存储桶列表"}
|
title={"MinIO存储桶列表"}
|
||||||
headerBordered
|
headerBordered
|
||||||
extra={
|
extra={
|
||||||
<>
|
<>
|
||||||
@@ -53,7 +45,7 @@ const ProCardComponent = () => {
|
|||||||
getAllBucket().then();
|
getAllBucket().then();
|
||||||
}}
|
}}
|
||||||
icon={<ReloadOutlined />}></Button>
|
icon={<ReloadOutlined />}></Button>
|
||||||
<Button type="primary" onClick={() => setDrawerVisit(true)}>
|
<Button type="primary" onClick={() => setOpen(true)}>
|
||||||
创建存储桶
|
创建存储桶
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
@@ -63,33 +55,90 @@ const ProCardComponent = () => {
|
|||||||
{buckets &&
|
{buckets &&
|
||||||
Array.from(buckets).map((item: any, index: number) => {
|
Array.from(buckets).map((item: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<ProCard
|
<ProCard
|
||||||
headStyle={{ backgroundColor: "#f0f2f5" }}
|
headStyle={{ backgroundColor: "#f0f2f5" }}
|
||||||
hoverable
|
hoverable
|
||||||
bordered
|
bordered
|
||||||
title={<b>{item.name}</b>}
|
// title={}
|
||||||
style={{
|
style={{
|
||||||
width: "180px",
|
width: "180px",
|
||||||
height: 150,
|
|
||||||
borderWidth: "1px",
|
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
}}
|
}}
|
||||||
actions={[
|
actions={[
|
||||||
<SettingOutlined key="setting" />,
|
// eslint-disable-next-line react/jsx-key
|
||||||
<EditOutlined key="edit" />,
|
<Popover
|
||||||
<EllipsisOutlined key="ellipsis" />,
|
content={bucketSize}
|
||||||
|
title={`size:`}
|
||||||
|
trigger="click">
|
||||||
|
<ClusterOutlined
|
||||||
|
key={"calculate"}
|
||||||
|
onClick={() => {
|
||||||
|
getBucketSize(
|
||||||
|
1,
|
||||||
|
item.name,
|
||||||
|
"minio",
|
||||||
|
).then((res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.success &&
|
||||||
|
res.data
|
||||||
|
) {
|
||||||
|
setBucketSize(res.data);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "计算出错!",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover>,
|
||||||
|
// eslint-disable-next-line react/jsx-key
|
||||||
|
<Popconfirm
|
||||||
|
title={`删除存储桶:${item.name}`}
|
||||||
|
description="你知道你要做什么吗?"
|
||||||
|
onConfirm={() => {
|
||||||
|
deleteBucket(1, item.name, "minio").then(
|
||||||
|
(res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.data &&
|
||||||
|
res.data === "success"
|
||||||
|
) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "删除成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No">
|
||||||
|
<DeleteOutlined key="delete" />
|
||||||
|
</Popconfirm>,
|
||||||
]}>
|
]}>
|
||||||
<Avatar
|
<Avatar
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
src={bucket as any}
|
src={bucket as any}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
<b style={{ marginLeft: 10 }}>{item.size}</b>
|
<b style={{ marginLeft: 5 }}>{item.name}</b>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
@@ -101,32 +150,49 @@ const ProCardComponent = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{bucketList()}
|
{bucketList()}
|
||||||
<DrawerForm
|
<Modal
|
||||||
title="创建存储桶"
|
title="创建存储桶"
|
||||||
open={drawerVisit}
|
width={"30%"}
|
||||||
onOpenChange={setDrawerVisit}
|
open={open}
|
||||||
onFinish={async (values) => {
|
closable={true}
|
||||||
console.log(values.name);
|
onOk={() => {
|
||||||
message.success("提交成功");
|
const bucketName = form.getFieldValue("name" as any);
|
||||||
return true;
|
if (bucketName === "" || bucketName === null) {
|
||||||
}}>
|
message.open({
|
||||||
<ProForm.Group>
|
content: " 请输入存储桶名称!",
|
||||||
<ProFormText
|
type: "warning",
|
||||||
width="md"
|
});
|
||||||
|
} else {
|
||||||
|
creatBucket(1, bucketName, "ali").then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "创建成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setOpen(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onCancel={() => setOpen(false)}>
|
||||||
|
<Form layout="vertical" form={form}>
|
||||||
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label="存储桶名字"
|
label="存储桶名称"
|
||||||
tooltip="最长为 24 位"
|
rules={[{ required: true, message: "请输入存储桶名称!" }]}>
|
||||||
placeholder="请输入名称"
|
<Input placeholder="请输入存储桶名称!" />
|
||||||
/>
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
<ProFormText
|
</Modal>
|
||||||
width="md"
|
|
||||||
name="capacity"
|
|
||||||
label="我方公司名称"
|
|
||||||
placeholder="请输入名称"
|
|
||||||
/>
|
|
||||||
</ProForm.Group>
|
|
||||||
</DrawerForm>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,29 +1,20 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { Avatar, Button, message, Skeleton } from "antd";
|
import { Avatar, Button, Form, Input, message, Modal, Popconfirm, Popover, Skeleton } from "antd";
|
||||||
import { DrawerForm, ProCard, ProForm, ProFormText } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { EditOutlined, EllipsisOutlined, ReloadOutlined, SettingOutlined } from "@ant-design/icons";
|
import { ClusterOutlined, DeleteOutlined, ReloadOutlined } from "@ant-design/icons";
|
||||||
import bucket from "@/assets/icons/bucket.svg";
|
import bucket from "@/assets/icons/bucket.svg";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { getAllMinioBucket } from "@/api/oss/minio";
|
import { getAllMinioBucket } from "@/api/oss/minio";
|
||||||
|
import { creatBucket, deleteBucket, getBucketSize } from "@/api/oss";
|
||||||
|
|
||||||
const DrawerContext = createContext<{
|
|
||||||
drawerVisit: boolean;
|
|
||||||
setDrawerVisit: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
}>({} as any);
|
|
||||||
const MinioDrawer = () => {
|
const MinioDrawer = () => {
|
||||||
const [drawerVisit, setDrawerVisit] = useState(false);
|
|
||||||
return (
|
|
||||||
<DrawerContext.Provider value={{ drawerVisit, setDrawerVisit }}>
|
|
||||||
<ProCardComponent />
|
|
||||||
</DrawerContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const ProCardComponent = () => {
|
|
||||||
const { drawerVisit, setDrawerVisit } = useContext(DrawerContext);
|
|
||||||
const [buckets, setBuckets] = useState<any>([]);
|
const [buckets, setBuckets] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [bucketSize, setBucketSize] = useState<string>("");
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
async function getAllBucket() {
|
async function getAllBucket() {
|
||||||
getAllMinioBucket("1").then((res: any) => {
|
getAllMinioBucket("1").then((res: any) => {
|
||||||
@@ -53,7 +44,7 @@ const ProCardComponent = () => {
|
|||||||
getAllBucket().then();
|
getAllBucket().then();
|
||||||
}}
|
}}
|
||||||
icon={<ReloadOutlined />}></Button>
|
icon={<ReloadOutlined />}></Button>
|
||||||
<Button type="primary" onClick={() => setDrawerVisit(true)}>
|
<Button type="primary" onClick={() => setOpen(true)}>
|
||||||
创建存储桶
|
创建存储桶
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
@@ -68,23 +59,83 @@ const ProCardComponent = () => {
|
|||||||
headStyle={{ backgroundColor: "#f0f2f5" }}
|
headStyle={{ backgroundColor: "#f0f2f5" }}
|
||||||
hoverable
|
hoverable
|
||||||
bordered
|
bordered
|
||||||
title={<b>{item.name}</b>}
|
// title={}
|
||||||
style={{
|
style={{
|
||||||
width: "180px",
|
width: "200px",
|
||||||
height: "150px",
|
marginLeft: 20,
|
||||||
marginLeft: 10,
|
|
||||||
}}
|
}}
|
||||||
actions={[
|
actions={[
|
||||||
<SettingOutlined key="setting" />,
|
// eslint-disable-next-line react/jsx-key
|
||||||
<EditOutlined key="edit" />,
|
<Popover
|
||||||
<EllipsisOutlined key="ellipsis" />,
|
content={bucketSize}
|
||||||
|
title={`size:`}
|
||||||
|
trigger="click">
|
||||||
|
<ClusterOutlined
|
||||||
|
key={"calculate"}
|
||||||
|
onClick={() => {
|
||||||
|
getBucketSize(
|
||||||
|
1,
|
||||||
|
item.name,
|
||||||
|
"minio",
|
||||||
|
).then((res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.success &&
|
||||||
|
res.data
|
||||||
|
) {
|
||||||
|
setBucketSize(res.data);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "计算出错!",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover>,
|
||||||
|
// eslint-disable-next-line react/jsx-key
|
||||||
|
<Popconfirm
|
||||||
|
title={`删除存储桶:${item.name}`}
|
||||||
|
description="你知道你要做什么吗?"
|
||||||
|
onConfirm={() => {
|
||||||
|
deleteBucket(1, item.name, "minio").then(
|
||||||
|
(res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.data &&
|
||||||
|
res.data === "success"
|
||||||
|
) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "删除成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No">
|
||||||
|
<DeleteOutlined key="delete" />
|
||||||
|
</Popconfirm>,
|
||||||
]}>
|
]}>
|
||||||
<Avatar
|
<Avatar
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
src={bucket as any}
|
src={bucket as any}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
<b style={{ marginLeft: 10 }}>{item.size}</b>
|
<b style={{ marginLeft: 5 }}>{item.name}</b>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -98,32 +149,49 @@ const ProCardComponent = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{bucketList()}
|
{bucketList()}
|
||||||
<DrawerForm
|
<Modal
|
||||||
title="创建存储桶"
|
title="创建存储桶"
|
||||||
open={drawerVisit}
|
width={"30%"}
|
||||||
onOpenChange={setDrawerVisit}
|
open={open}
|
||||||
onFinish={async (values) => {
|
closable={true}
|
||||||
console.log(values.name);
|
onOk={() => {
|
||||||
message.success("提交成功");
|
const bucketName = form.getFieldValue("name" as any);
|
||||||
return true;
|
if (bucketName === "" || bucketName === null) {
|
||||||
}}>
|
message.open({
|
||||||
<ProForm.Group>
|
content: " 请输入存储桶名称!",
|
||||||
<ProFormText
|
type: "warning",
|
||||||
width="md"
|
});
|
||||||
|
} else {
|
||||||
|
creatBucket(1, bucketName, "minio").then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "创建成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setOpen(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onCancel={() => setOpen(false)}>
|
||||||
|
<Form layout="vertical" form={form}>
|
||||||
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label="存储桶名字"
|
label="存储桶名称"
|
||||||
tooltip="最长为 24 位"
|
rules={[{ required: true, message: "请输入存储桶名称!" }]}>
|
||||||
placeholder="请输入名称"
|
<Input placeholder="请输入存储桶名称!" />
|
||||||
/>
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
<ProFormText
|
</Modal>
|
||||||
width="md"
|
|
||||||
name="capacity"
|
|
||||||
label="我方公司名称"
|
|
||||||
placeholder="请输入名称"
|
|
||||||
/>
|
|
||||||
</ProForm.Group>
|
|
||||||
</DrawerForm>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -6,7 +6,6 @@ import React, { createContext, useContext, useEffect, useState } from "react";
|
|||||||
import { EditOutlined, EllipsisOutlined, ReloadOutlined, SettingOutlined } from "@ant-design/icons";
|
import { EditOutlined, EllipsisOutlined, ReloadOutlined, SettingOutlined } from "@ant-design/icons";
|
||||||
import bucket from "@/assets/icons/bucket.svg";
|
import bucket from "@/assets/icons/bucket.svg";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { getAllMinioBucket } from "@/api/oss/minio";
|
|
||||||
import { getAllQiniuBucket } from "@/api/oss/qiniu";
|
import { getAllQiniuBucket } from "@/api/oss/qiniu";
|
||||||
|
|
||||||
const DrawerContext = createContext<{
|
const DrawerContext = createContext<{
|
||||||
|
@@ -1,83 +1,147 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { Avatar, Button, message } from "antd";
|
import { Avatar, Button, Form, Input, message, Modal, Popconfirm, Popover, Skeleton } from "antd";
|
||||||
import {
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
DrawerForm,
|
import { useEffect, useState } from "react";
|
||||||
ProCard,
|
import { ClusterOutlined, DeleteOutlined, ReloadOutlined } from "@ant-design/icons";
|
||||||
ProForm,
|
import bucket from "@/assets/icons/bucket.svg";
|
||||||
ProFormText,
|
|
||||||
} from "@ant-design/pro-components";
|
|
||||||
import React, { createContext, useContext, useState } from "react";
|
|
||||||
import { EditOutlined, EllipsisOutlined, SettingOutlined } from "@ant-design/icons";
|
|
||||||
import bucket from "../../../../assets/icons/bucket.svg";
|
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
|
import { getAllMinioBucket } from "@/api/oss/minio";
|
||||||
|
import { creatBucket, deleteBucket, getBucketSize } from "@/api/oss";
|
||||||
|
|
||||||
const DrawerContext = createContext<{
|
|
||||||
drawerVisit: boolean;
|
|
||||||
setDrawerVisit: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
}>({} as any);
|
|
||||||
const QiniuDrawer = () => {
|
const QiniuDrawer = () => {
|
||||||
const [drawerVisit, setDrawerVisit] = useState(false);
|
const [buckets, setBuckets] = useState<any>([]);
|
||||||
return (
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
<DrawerContext.Provider value={{ drawerVisit, setDrawerVisit }}>
|
const [bucketSize, setBucketSize] = useState<string>("");
|
||||||
<ProCardComponent />
|
const [form] = Form.useForm();
|
||||||
</DrawerContext.Provider>
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
);
|
|
||||||
};
|
async function getAllBucket() {
|
||||||
const ProCardComponent = () => {
|
getAllMinioBucket("1").then((res: any) => {
|
||||||
const { drawerVisit, setDrawerVisit } = useContext(DrawerContext);
|
if (res && res.success) {
|
||||||
const list = [
|
setBuckets(res.data);
|
||||||
"test1",
|
setLoading(false);
|
||||||
"test2",
|
}
|
||||||
"test3",
|
});
|
||||||
"test1",
|
}
|
||||||
"test2",
|
|
||||||
"test3",
|
useEffect(() => {
|
||||||
"test1",
|
getAllBucket().then();
|
||||||
"test2",
|
}, []);
|
||||||
"test3",
|
|
||||||
"test1",
|
|
||||||
"test2",
|
|
||||||
"test3",
|
|
||||||
"test3",
|
|
||||||
"test1",
|
|
||||||
"test2",
|
|
||||||
"test3",
|
|
||||||
];
|
|
||||||
|
|
||||||
const bucketList = () => {
|
const bucketList = () => {
|
||||||
return (
|
return (
|
||||||
<ProCard
|
<ProCard
|
||||||
title={"存储桶列表"}
|
title={"MinIO存储桶列表"}
|
||||||
headerBordered
|
headerBordered
|
||||||
extra={
|
extra={
|
||||||
<Button type="primary" onClick={() => setDrawerVisit(true)}>
|
<>
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
shape={"circle"}
|
||||||
|
style={{ marginRight: 20 }}
|
||||||
|
onClick={() => {
|
||||||
|
setLoading(false);
|
||||||
|
getAllBucket().then();
|
||||||
|
}}
|
||||||
|
icon={<ReloadOutlined />}></Button>
|
||||||
|
<Button type="primary" onClick={() => setOpen(true)}>
|
||||||
创建存储桶
|
创建存储桶
|
||||||
</Button>
|
</Button>
|
||||||
|
</>
|
||||||
}>
|
}>
|
||||||
<div className={styles.div_proCard}>
|
<div className={styles.div_proCard}>
|
||||||
{list.map((item, index) => {
|
<Skeleton loading={loading} paragraph={{ rows: 13 }} active>
|
||||||
|
{buckets &&
|
||||||
|
Array.from(buckets).map((item: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
|
<div key={index}>
|
||||||
<ProCard
|
<ProCard
|
||||||
headStyle={{ backgroundColor: "#f0f2f5" }}
|
headStyle={{ backgroundColor: "#f0f2f5" }}
|
||||||
hoverable
|
hoverable
|
||||||
bordered
|
bordered
|
||||||
key={index}
|
// title={}
|
||||||
title={<b>名字:{item}</b>}
|
|
||||||
style={{
|
style={{
|
||||||
width: "180px",
|
width: "180px",
|
||||||
borderWidth: "1px",
|
marginLeft: 10,
|
||||||
}}
|
}}
|
||||||
actions={[
|
actions={[
|
||||||
<SettingOutlined key="setting" />,
|
// eslint-disable-next-line react/jsx-key
|
||||||
<EditOutlined key="edit" />,
|
<Popover
|
||||||
<EllipsisOutlined key="ellipsis" />,
|
content={bucketSize}
|
||||||
|
title={`size:`}
|
||||||
|
trigger="click">
|
||||||
|
<ClusterOutlined
|
||||||
|
key={"calculate"}
|
||||||
|
onClick={() => {
|
||||||
|
getBucketSize(
|
||||||
|
1,
|
||||||
|
item.name,
|
||||||
|
"minio",
|
||||||
|
).then((res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.success &&
|
||||||
|
res.data
|
||||||
|
) {
|
||||||
|
setBucketSize(res.data);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "计算出错!",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover>,
|
||||||
|
// eslint-disable-next-line react/jsx-key
|
||||||
|
<Popconfirm
|
||||||
|
title={`删除存储桶:${item.name}`}
|
||||||
|
description="你知道你要做什么吗?"
|
||||||
|
onConfirm={() => {
|
||||||
|
deleteBucket(1, item.name, "minio").then(
|
||||||
|
(res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.data &&
|
||||||
|
res.data === "success"
|
||||||
|
) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "删除成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No">
|
||||||
|
<DeleteOutlined key="delete" />
|
||||||
|
</Popconfirm>,
|
||||||
]}>
|
]}>
|
||||||
<Avatar shape={"square"} src={bucket} size={"large"} />
|
<Avatar
|
||||||
<b style={{ marginLeft: 10 }}> size</b>
|
shape={"square"}
|
||||||
|
src={bucket as any}
|
||||||
|
size={"large"}
|
||||||
|
/>
|
||||||
|
<b style={{ marginLeft: 5 }}>{item.name}</b>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
</Skeleton>
|
||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
);
|
);
|
||||||
@@ -86,32 +150,49 @@ const ProCardComponent = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{bucketList()}
|
{bucketList()}
|
||||||
<DrawerForm
|
<Modal
|
||||||
title="创建存储桶"
|
title="创建存储桶"
|
||||||
open={drawerVisit}
|
width={"30%"}
|
||||||
onOpenChange={setDrawerVisit}
|
open={open}
|
||||||
onFinish={async (values) => {
|
closable={true}
|
||||||
console.log(values.name);
|
onOk={() => {
|
||||||
message.success("提交成功");
|
const bucketName = form.getFieldValue("name" as any);
|
||||||
return true;
|
if (bucketName === "" || bucketName === null) {
|
||||||
}}>
|
message.open({
|
||||||
<ProForm.Group>
|
content: " 请输入存储桶名称!",
|
||||||
<ProFormText
|
type: "warning",
|
||||||
width="md"
|
});
|
||||||
|
} else {
|
||||||
|
creatBucket(1, bucketName, "qiniu").then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "创建成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setOpen(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onCancel={() => setOpen(false)}>
|
||||||
|
<Form layout="vertical" form={form}>
|
||||||
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label="存储桶名字"
|
label="存储桶名称"
|
||||||
tooltip="最长为 24 位"
|
rules={[{ required: true, message: "请输入存储桶名称!" }]}>
|
||||||
placeholder="请输入名称"
|
<Input placeholder="请输入存储桶名称!" />
|
||||||
/>
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
<ProFormText
|
</Modal>
|
||||||
width="md"
|
|
||||||
name="capacity"
|
|
||||||
label="我方公司名称"
|
|
||||||
placeholder="请输入名称"
|
|
||||||
/>
|
|
||||||
</ProForm.Group>
|
|
||||||
</DrawerForm>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,32 +1,23 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { Avatar, Button, message, Skeleton } from "antd";
|
import { Avatar, Button, Form, Input, message, Modal, Popconfirm, Popover, Skeleton } from "antd";
|
||||||
import { DrawerForm, ProCard, ProForm, ProFormText } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { EditOutlined, EllipsisOutlined, SettingOutlined } from "@ant-design/icons";
|
import { ClusterOutlined, DeleteOutlined, ReloadOutlined } from "@ant-design/icons";
|
||||||
import bucket from "../../../../assets/icons/bucket.svg";
|
import bucket from "@/assets/icons/bucket.svg";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { getAllTencentOSsBucket } from "@/api/oss/tencent";
|
import { getAllMinioBucket } from "@/api/oss/minio";
|
||||||
|
import { creatBucket, deleteBucket, getBucketSize } from "@/api/oss";
|
||||||
|
|
||||||
const DrawerContext = createContext<{
|
|
||||||
drawerVisit: boolean;
|
|
||||||
setDrawerVisit: React.Dispatch<React.SetStateAction<boolean>>;
|
|
||||||
}>({} as any);
|
|
||||||
const TencentDrawer = () => {
|
const TencentDrawer = () => {
|
||||||
const [drawerVisit, setDrawerVisit] = useState(false);
|
|
||||||
return (
|
|
||||||
<DrawerContext.Provider value={{ drawerVisit, setDrawerVisit }}>
|
|
||||||
<ProCardComponent />
|
|
||||||
</DrawerContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const ProCardComponent = () => {
|
|
||||||
const { drawerVisit, setDrawerVisit } = useContext(DrawerContext);
|
|
||||||
const [buckets, setBuckets] = useState<any>([]);
|
const [buckets, setBuckets] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [bucketSize, setBucketSize] = useState<string>("");
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
async function getAllBucket() {
|
async function getAllBucket() {
|
||||||
getAllTencentOSsBucket("1").then((res: any) => {
|
getAllMinioBucket("1").then((res: any) => {
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
setBuckets(res.data);
|
setBuckets(res.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -41,12 +32,23 @@ const ProCardComponent = () => {
|
|||||||
const bucketList = () => {
|
const bucketList = () => {
|
||||||
return (
|
return (
|
||||||
<ProCard
|
<ProCard
|
||||||
title={"腾讯云COS存储桶列表"}
|
title={"MinIO存储桶列表"}
|
||||||
headerBordered
|
headerBordered
|
||||||
extra={
|
extra={
|
||||||
<Button type="primary" onClick={() => setDrawerVisit(true)}>
|
<>
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
shape={"circle"}
|
||||||
|
style={{ marginRight: 20 }}
|
||||||
|
onClick={() => {
|
||||||
|
setLoading(false);
|
||||||
|
getAllBucket().then();
|
||||||
|
}}
|
||||||
|
icon={<ReloadOutlined />}></Button>
|
||||||
|
<Button type="primary" onClick={() => setOpen(true)}>
|
||||||
创建存储桶
|
创建存储桶
|
||||||
</Button>
|
</Button>
|
||||||
|
</>
|
||||||
}>
|
}>
|
||||||
<div className={styles.div_proCard}>
|
<div className={styles.div_proCard}>
|
||||||
<Skeleton loading={loading} paragraph={{ rows: 13 }} active>
|
<Skeleton loading={loading} paragraph={{ rows: 13 }} active>
|
||||||
@@ -58,23 +60,83 @@ const ProCardComponent = () => {
|
|||||||
headStyle={{ backgroundColor: "#f0f2f5" }}
|
headStyle={{ backgroundColor: "#f0f2f5" }}
|
||||||
hoverable
|
hoverable
|
||||||
bordered
|
bordered
|
||||||
title={<b>{item.name}</b>}
|
// title={}
|
||||||
style={{
|
style={{
|
||||||
width: "180px",
|
width: "180px",
|
||||||
height: "150px",
|
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
}}
|
}}
|
||||||
actions={[
|
actions={[
|
||||||
<SettingOutlined key="setting" />,
|
// eslint-disable-next-line react/jsx-key
|
||||||
<EditOutlined key="edit" />,
|
<Popover
|
||||||
<EllipsisOutlined key="ellipsis" />,
|
content={bucketSize}
|
||||||
|
title={`size:`}
|
||||||
|
trigger="click">
|
||||||
|
<ClusterOutlined
|
||||||
|
key={"calculate"}
|
||||||
|
onClick={() => {
|
||||||
|
getBucketSize(
|
||||||
|
1,
|
||||||
|
item.name,
|
||||||
|
"minio",
|
||||||
|
).then((res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.success &&
|
||||||
|
res.data
|
||||||
|
) {
|
||||||
|
setBucketSize(res.data);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "计算出错!",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover>,
|
||||||
|
// eslint-disable-next-line react/jsx-key
|
||||||
|
<Popconfirm
|
||||||
|
title={`删除存储桶:${item.name}`}
|
||||||
|
description="你知道你要做什么吗?"
|
||||||
|
onConfirm={() => {
|
||||||
|
deleteBucket(1, item.name, "minio").then(
|
||||||
|
(res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.data &&
|
||||||
|
res.data === "success"
|
||||||
|
) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "删除成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No">
|
||||||
|
<DeleteOutlined key="delete" />
|
||||||
|
</Popconfirm>,
|
||||||
]}>
|
]}>
|
||||||
<Avatar
|
<Avatar
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
src={bucket as any}
|
src={bucket as any}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
<b style={{ marginLeft: 10 }}>{item.size}</b>
|
<b style={{ marginLeft: 5 }}>{item.name}</b>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -88,32 +150,49 @@ const ProCardComponent = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{bucketList()}
|
{bucketList()}
|
||||||
<DrawerForm
|
<Modal
|
||||||
title="创建存储桶"
|
title="创建存储桶"
|
||||||
open={drawerVisit}
|
width={"30%"}
|
||||||
onOpenChange={setDrawerVisit}
|
open={open}
|
||||||
onFinish={async (values) => {
|
closable={true}
|
||||||
console.log(values.name);
|
onOk={() => {
|
||||||
message.success("提交成功");
|
const bucketName = form.getFieldValue("name" as any);
|
||||||
return true;
|
if (bucketName === "" || bucketName === null) {
|
||||||
}}>
|
message.open({
|
||||||
<ProForm.Group>
|
content: " 请输入存储桶名称!",
|
||||||
<ProFormText
|
type: "warning",
|
||||||
width="md"
|
});
|
||||||
|
} else {
|
||||||
|
creatBucket(1, bucketName, "tencent").then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "创建成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setOpen(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onCancel={() => setOpen(false)}>
|
||||||
|
<Form layout="vertical" form={form}>
|
||||||
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label="存储桶名字"
|
label="存储桶名称"
|
||||||
tooltip="最长为 24 位"
|
rules={[{ required: true, message: "请输入存储桶名称!" }]}>
|
||||||
placeholder="请输入名称"
|
<Input placeholder="请输入存储桶名称!" />
|
||||||
/>
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
<ProFormText
|
</Modal>
|
||||||
width="md"
|
|
||||||
name="capacity"
|
|
||||||
label="我方公司名称"
|
|
||||||
placeholder="请输入名称"
|
|
||||||
/>
|
|
||||||
</ProForm.Group>
|
|
||||||
</DrawerForm>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,34 +1,68 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Avatar, Card, Flex, Input, message, Select, Upload } from "antd";
|
import { Avatar, Card, Flex, Input, message, Progress, Select, Upload } from "antd";
|
||||||
import { CloudUploadOutlined } from "@ant-design/icons";
|
import { CloudUploadOutlined } from "@ant-design/icons";
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import selectOptions from "@/components/Main/Settings/settings.ts";
|
|
||||||
import StorageIcon from "@/constant/stroage-icon.ts";
|
import StorageIcon from "@/constant/stroage-icon.ts";
|
||||||
|
import { getStorageBuckets, uploadFiles } from "@/api/oss";
|
||||||
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
const { Dragger } = Upload;
|
const { Dragger } = Upload;
|
||||||
const props: any = {
|
|
||||||
name: "file",
|
const FileUpload: React.FC = (props: any) => {
|
||||||
multiple: true,
|
const [buckets, setBuckets] = useState<any[]>([]);
|
||||||
directory: true,
|
const store = useStore("file");
|
||||||
action: "https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload",
|
const [defaultFileList, setDefaultFileList] = useState([]);
|
||||||
onChange(info: any) {
|
async function getBuckets(type: any) {
|
||||||
const { status } = info.file;
|
getStorageBuckets("1", type).then((res: any) => {
|
||||||
if (status !== "uploading") {
|
if (res && res.success) {
|
||||||
console.log(info.file, info.fileList);
|
setBuckets(res.data);
|
||||||
}
|
}
|
||||||
if (status === "done") {
|
});
|
||||||
message.success(`${info.file.name} file uploaded successfully.`);
|
|
||||||
} else if (status === "error") {
|
|
||||||
message.error(`${info.file.name} file upload failed.`);
|
|
||||||
}
|
}
|
||||||
},
|
const handleOnChange = ({ fileList }) => {
|
||||||
onDrop(e: any) {
|
setDefaultFileList(fileList);
|
||||||
console.log("Dropped files", e.dataTransfer.files);
|
};
|
||||||
},
|
|
||||||
};
|
const uploadFile = async (options) => {
|
||||||
const FileUpload: React.FC = () => {
|
const { onSuccess, onError, file, onProgress } = options;
|
||||||
|
if (
|
||||||
|
store.getUploadFilePath() === null ||
|
||||||
|
(store.getUploadFileBucket() === null && store.getUploadFileStorage() === null)
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储桶和存储路径",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fileData = new FormData();
|
||||||
|
fileData.append("file", file);
|
||||||
|
const formData: any = {
|
||||||
|
userId: "1",
|
||||||
|
bucketName: store.getUploadFileBucket(),
|
||||||
|
path: store.getUploadFilePath(),
|
||||||
|
};
|
||||||
|
console.log(formData);
|
||||||
|
uploadFiles(store.getUploadFileStorage(), fileData, formData).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "上传成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
onSuccess(res.success);
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: "上传失败",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
setDefaultFileList([]);
|
||||||
|
onError(res.success);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -45,11 +79,24 @@ const FileUpload: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
showSearch={true}
|
showSearch={true}
|
||||||
allowClear={true}
|
allowClear={true}
|
||||||
notFoundContent={"未找到,请先配置存储商"}
|
onSelect={(value: any) => {
|
||||||
placeholder={"请选择存储商"}>
|
store.setUploadFileStorage(value);
|
||||||
{selectOptions.map((storage: any, index: any) => {
|
getBuckets(value).then();
|
||||||
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
store.setUploadFileStorage("");
|
||||||
|
setBuckets([]);
|
||||||
|
}}
|
||||||
|
onChange={(value: any) => {
|
||||||
|
store.setUploadFileStorage(value);
|
||||||
|
}}
|
||||||
|
fieldNames={{
|
||||||
|
label: "name",
|
||||||
|
value: "ossType",
|
||||||
|
}}
|
||||||
|
labelRender={(label: any) => {
|
||||||
return (
|
return (
|
||||||
<Select.Option value={storage.value} key={index}>
|
<>
|
||||||
<Card
|
<Card
|
||||||
bordered={false}
|
bordered={false}
|
||||||
style={{
|
style={{
|
||||||
@@ -59,22 +106,46 @@ const FileUpload: React.FC = () => {
|
|||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
}}
|
}}
|
||||||
size={"small"}>
|
size={"small"}>
|
||||||
<Avatar
|
<Avatar src={StorageIcon[label.value]} size={"small"} />
|
||||||
src={StorageIcon[storage.value]}
|
|
||||||
size={"small"}
|
|
||||||
/>{" "}
|
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
marginLeft: "10px",
|
marginLeft: "10px",
|
||||||
fontWeight: "bolder",
|
fontWeight: "bolder",
|
||||||
}}>
|
}}>
|
||||||
{storage.name}
|
{label.label}
|
||||||
</span>
|
</span>
|
||||||
</Card>
|
</Card>
|
||||||
</Select.Option>
|
</>
|
||||||
);
|
);
|
||||||
})}
|
}}
|
||||||
</Select>
|
options={props.userStorage}
|
||||||
|
notFoundContent={"未找到,请先配置存储商"}
|
||||||
|
optionRender={(item: any) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card
|
||||||
|
bordered={false}
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
}}
|
||||||
|
size={"small"}>
|
||||||
|
<Avatar src={StorageIcon[item.value]} size={"small"} />
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: "10px",
|
||||||
|
fontWeight: "bolder",
|
||||||
|
}}>
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
placeholder={"请选择存储商"}></Select>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
size="large"
|
size="large"
|
||||||
status="warning"
|
status="warning"
|
||||||
@@ -85,13 +156,55 @@ const FileUpload: React.FC = () => {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginLeft: "10px",
|
marginLeft: "10px",
|
||||||
}}
|
}}
|
||||||
|
onSelect={(value: any) => {
|
||||||
|
store.setUploadFileBucket(value);
|
||||||
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
store.setUploadFileBucket("");
|
||||||
|
setBuckets([]);
|
||||||
|
}}
|
||||||
|
onChange={(value: any) => {
|
||||||
|
store.setUploadFileBucket(value);
|
||||||
|
}}
|
||||||
showSearch={true}
|
showSearch={true}
|
||||||
allowClear={true}
|
allowClear={true}
|
||||||
notFoundContent={"未找到,请先配置存储商"}
|
notFoundContent={"未找到,请先配置存储商"}
|
||||||
placeholder={"请选择存储桶"}>
|
fieldNames={{
|
||||||
{selectOptions.map((storage: any, index: any) => {
|
label: "name",
|
||||||
|
value: "name",
|
||||||
|
}}
|
||||||
|
labelRender={(label: any) => {
|
||||||
return (
|
return (
|
||||||
<Select.Option value={storage.value} key={index}>
|
<>
|
||||||
|
<Card
|
||||||
|
bordered={false}
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
}}
|
||||||
|
size={"small"}>
|
||||||
|
<Avatar
|
||||||
|
src={StorageIcon["bucket"]}
|
||||||
|
shape={"square"}
|
||||||
|
size={"small"}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: "10px",
|
||||||
|
fontWeight: "bolder",
|
||||||
|
}}>
|
||||||
|
{label.label}
|
||||||
|
</span>
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
options={buckets}
|
||||||
|
optionRender={(item: any) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<Card
|
<Card
|
||||||
bordered={false}
|
bordered={false}
|
||||||
style={{
|
style={{
|
||||||
@@ -111,24 +224,41 @@ const FileUpload: React.FC = () => {
|
|||||||
marginLeft: "10px",
|
marginLeft: "10px",
|
||||||
fontWeight: "bolder",
|
fontWeight: "bolder",
|
||||||
}}>
|
}}>
|
||||||
{storage.name}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
</Card>
|
</Card>
|
||||||
</Select.Option>
|
</>
|
||||||
);
|
);
|
||||||
})}
|
}}
|
||||||
</Select>
|
placeholder={"请选择存储桶"}></Select>
|
||||||
<Input placeholder={"请输入路径/默认当前打开的路径"} style={{ marginLeft: 10,width: "40%" }}></Input>
|
<Input
|
||||||
|
placeholder={"请输入路径/默认当前打开的路径"}
|
||||||
|
onChange={(e: any) => {
|
||||||
|
store.setUploadFilePath(e.target.value);
|
||||||
|
}}
|
||||||
|
style={{ marginLeft: 10, width: "40%" }}></Input>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</Flex>
|
</Flex>
|
||||||
<ProCard>
|
<ProCard>
|
||||||
<Dragger {...props}>
|
<Dragger
|
||||||
|
name={"file"}
|
||||||
|
multiple={false}
|
||||||
|
directory={false}
|
||||||
|
maxCount={1}
|
||||||
|
defaultFileList={defaultFileList}
|
||||||
|
headers={{
|
||||||
|
ContentType: "multipart/form-data",
|
||||||
|
}}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
customRequest={uploadFile}
|
||||||
|
onDrop={() => uploadFile}>
|
||||||
<p className="ant-upload-drag-icon">
|
<p className="ant-upload-drag-icon">
|
||||||
<CloudUploadOutlined />
|
<CloudUploadOutlined />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
<p className="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||||
<p className="ant-upload-hint">支持单次或批量上传。</p>
|
<p className="ant-upload-hint">只支持单次上传。</p>
|
||||||
</Dragger>
|
</Dragger>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</>
|
</>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
import { CheckCard, ProCard } from "@ant-design/pro-components";
|
import { CheckCard, ProCard } from "@ant-design/pro-components";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import {
|
import {
|
||||||
@@ -14,23 +14,26 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
message,
|
message,
|
||||||
Modal,
|
Modal,
|
||||||
|
Popover,
|
||||||
|
QRCode,
|
||||||
Select,
|
Select,
|
||||||
|
Skeleton,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import bucket from "@/assets/icons/bucket.svg";
|
import bucket from "@/assets/icons/bucket.svg";
|
||||||
import {
|
import {
|
||||||
|
CheckOutlined,
|
||||||
CloudUploadOutlined,
|
CloudUploadOutlined,
|
||||||
CopyOutlined,
|
CopyOutlined,
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
DownloadOutlined,
|
DownloadOutlined,
|
||||||
|
EditOutlined,
|
||||||
EllipsisOutlined,
|
EllipsisOutlined,
|
||||||
EyeOutlined,
|
EyeOutlined,
|
||||||
LeftOutlined,
|
LeftOutlined,
|
||||||
QrcodeOutlined,
|
QrcodeOutlined,
|
||||||
RedoOutlined,
|
RedoOutlined,
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
ScissorOutlined,
|
|
||||||
SearchOutlined,
|
|
||||||
SnippetsOutlined,
|
SnippetsOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import standard_dir from "@/assets/icons/standard_directory.svg";
|
import standard_dir from "@/assets/icons/standard_directory.svg";
|
||||||
@@ -39,34 +42,39 @@ import { observer } from "mobx-react";
|
|||||||
import FileIcon from "@/constant/file-icon.ts";
|
import FileIcon from "@/constant/file-icon.ts";
|
||||||
import file_icon from "@/assets/icons/files/file.svg";
|
import file_icon from "@/assets/icons/files/file.svg";
|
||||||
import FileUpload from "@/components/Main/File/components/FileUpload.tsx";
|
import FileUpload from "@/components/Main/File/components/FileUpload.tsx";
|
||||||
import { getAllStorage, getBucketFiles, getStorageBuckets } from "@/api/oss";
|
import logo from "@/assets/images/logo.png";
|
||||||
|
import {
|
||||||
|
copyFile,
|
||||||
|
deleteFile,
|
||||||
|
downloadFiles,
|
||||||
|
getAllStorage,
|
||||||
|
getBucketFiles,
|
||||||
|
getStorageBuckets,
|
||||||
|
previewFile,
|
||||||
|
renameFile,
|
||||||
|
} from "@/api/oss";
|
||||||
import StorageIcon from "@/constant/stroage-icon.ts";
|
import StorageIcon from "@/constant/stroage-icon.ts";
|
||||||
const fileList: any = [
|
import { useNavigate } from "react-router-dom";
|
||||||
{
|
import Base64 from "base-64";
|
||||||
name: "test1.png",
|
|
||||||
isDir: false,
|
|
||||||
path: "test1.png",
|
|
||||||
length: "1766511",
|
|
||||||
createTime: "2024-06-29T10:28:03.224Z",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "schisandra",
|
|
||||||
isDir: true,
|
|
||||||
path: "schisandra/",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const File: FunctionComponent = () => {
|
const File: FunctionComponent = () => {
|
||||||
const store = useStore("file");
|
const store = useStore("file");
|
||||||
|
const navigate = useNavigate();
|
||||||
const [files, setFiles] = useState<any>([]);
|
const [files, setFiles] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [bucketLoading, setBucketLoading] = useState<boolean>(true);
|
const [loadingFile, setLoadingFile] = useState<boolean>(true);
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const [openRename, setOpenRename] = useState<boolean>(false);
|
||||||
const [userStorage, setUserStorage] = useState([]);
|
const [userStorage, setUserStorage] = useState([]);
|
||||||
const [buckets, setBuckets] = useState<any[]>([]);
|
const [buckets, setBuckets] = useState<any[]>([]);
|
||||||
const [currentStorage, setCurrentStorage] = useState<any>(null);
|
const [newFileName, setNewFileName] = useState<any>(null);
|
||||||
const [currentBucket, setCurrentBucket] = useState<any>(null);
|
const [disable, setDisable] = useState<boolean>(true);
|
||||||
|
const [previewUrl, setPreviewUrl] = useState<any>(null);
|
||||||
|
|
||||||
|
function setLoadingTimeOut() {
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoadingFile(false);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
async function getUserStorage() {
|
async function getUserStorage() {
|
||||||
getAllStorage("1").then((res: any) => {
|
getAllStorage("1").then((res: any) => {
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
@@ -79,6 +87,7 @@ const File: FunctionComponent = () => {
|
|||||||
return getBucketFiles("1", bucket, dirName, type).then((res: any) => {
|
return getBucketFiles("1", bucket, dirName, type).then((res: any) => {
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
setFiles(res.data);
|
setFiles(res.data);
|
||||||
|
setLoadingTimeOut();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -90,7 +99,6 @@ const File: FunctionComponent = () => {
|
|||||||
getStorageBuckets("1", type).then((res: any) => {
|
getStorageBuckets("1", type).then((res: any) => {
|
||||||
if (res && res.success) {
|
if (res && res.success) {
|
||||||
setBuckets(res.data);
|
setBuckets(res.data);
|
||||||
setBucketLoading(false);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -116,26 +124,24 @@ const File: FunctionComponent = () => {
|
|||||||
showSearch={true}
|
showSearch={true}
|
||||||
allowClear={true}
|
allowClear={true}
|
||||||
onSelect={(value: any) => {
|
onSelect={(value: any) => {
|
||||||
setCurrentStorage(value);
|
store.setCurrentStorage(value);
|
||||||
getBuckets(value).then();
|
getBuckets(value).then();
|
||||||
}}
|
}}
|
||||||
onClear={() => {
|
onClear={() => {
|
||||||
setCurrentStorage(null);
|
store.setCurrentStorage("");
|
||||||
setBuckets([]);
|
setBuckets([]);
|
||||||
}}
|
}}
|
||||||
onChange={(value: any) => {
|
onChange={(value: any) => {
|
||||||
setCurrentStorage(value);
|
store.setCurrentStorage(value);
|
||||||
// getBuckets(value).then();
|
|
||||||
}}
|
}}
|
||||||
notFoundContent={"未找到,请先配置存储商"}
|
fieldNames={{
|
||||||
placeholder={"请选择存储商"}>
|
label: "name",
|
||||||
{userStorage &&
|
value: "ossType",
|
||||||
userStorage.map((item: any, index: number) => {
|
}}
|
||||||
|
labelRender={(label: any) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Select.Option value={item.ossType} key={index}>
|
|
||||||
<Card
|
<Card
|
||||||
key={item}
|
|
||||||
bordered={false}
|
bordered={false}
|
||||||
style={{
|
style={{
|
||||||
height: 35,
|
height: 35,
|
||||||
@@ -145,7 +151,7 @@ const File: FunctionComponent = () => {
|
|||||||
}}
|
}}
|
||||||
size={"small"}>
|
size={"small"}>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={StorageIcon[item.ossType]}
|
src={StorageIcon[label.value]}
|
||||||
size={"small"}
|
size={"small"}
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -153,21 +159,49 @@ const File: FunctionComponent = () => {
|
|||||||
marginLeft: "10px",
|
marginLeft: "10px",
|
||||||
fontWeight: "bolder",
|
fontWeight: "bolder",
|
||||||
}}>
|
}}>
|
||||||
{item.name}
|
{label.label}
|
||||||
</span>
|
</span>
|
||||||
</Card>
|
</Card>
|
||||||
</Select.Option>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
})}
|
}}
|
||||||
</Select>
|
options={userStorage}
|
||||||
|
notFoundContent={"未找到,请先配置存储商"}
|
||||||
|
optionRender={(item: any) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card
|
||||||
|
bordered={false}
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
}}
|
||||||
|
size={"small"}>
|
||||||
|
<Avatar
|
||||||
|
src={StorageIcon[item.value]}
|
||||||
|
size={"small"}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: "10px",
|
||||||
|
fontWeight: "bolder",
|
||||||
|
}}>
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
placeholder={"请选择存储商"}></Select>
|
||||||
<Button
|
<Button
|
||||||
type="default"
|
type="default"
|
||||||
shape={"circle"}
|
shape={"circle"}
|
||||||
style={{ marginLeft: 10 }}
|
style={{ marginLeft: 10 }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (currentStorage != null) {
|
if (store.getCurrentStorage() != null) {
|
||||||
getBuckets(currentStorage).then();
|
getBuckets(store.getCurrentStorage()).then();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
icon={<ReloadOutlined />}></Button>
|
icon={<ReloadOutlined />}></Button>
|
||||||
@@ -176,14 +210,14 @@ const File: FunctionComponent = () => {
|
|||||||
<div>
|
<div>
|
||||||
<CheckCard.Group
|
<CheckCard.Group
|
||||||
size={"small"}
|
size={"small"}
|
||||||
loading={bucketLoading}
|
|
||||||
onChange={(value: any) => {
|
onChange={(value: any) => {
|
||||||
|
setFiles([]);
|
||||||
store.clearAllFilePath();
|
store.clearAllFilePath();
|
||||||
store.setFilePath(`/${value}`);
|
store.setFilePath(`/${value}`);
|
||||||
setCurrentBucket(value);
|
store.setCurrentBucket(value);
|
||||||
console.log(value);
|
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
getFiles(value, "", currentStorage).then();
|
setLoadingFile(true);
|
||||||
|
getFiles(value, "", store.getCurrentStorage()).then();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}>
|
style={{ width: "100%" }}>
|
||||||
@@ -196,7 +230,6 @@ const File: FunctionComponent = () => {
|
|||||||
{buckets &&
|
{buckets &&
|
||||||
Array.from(buckets).map((item: any, index: number) => {
|
Array.from(buckets).map((item: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<CheckCard
|
<CheckCard
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
@@ -208,22 +241,19 @@ const File: FunctionComponent = () => {
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
placement="top"
|
placement="top"
|
||||||
menu={{
|
menu={{
|
||||||
onClick: ({
|
onClick: (value: any) => {
|
||||||
domEvent,
|
if (
|
||||||
}) => {
|
value.key === "view"
|
||||||
domEvent.stopPropagation();
|
) {
|
||||||
message.info(
|
navigate(
|
||||||
"menu click",
|
"/main/bucket",
|
||||||
);
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
{
|
|
||||||
label: "删除",
|
|
||||||
key: "1",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "查看",
|
label: "查看",
|
||||||
key: "2",
|
key: "view",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}}>
|
}}>
|
||||||
@@ -240,7 +270,6 @@ const File: FunctionComponent = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
@@ -258,18 +287,59 @@ const File: FunctionComponent = () => {
|
|||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<LeftOutlined />}
|
icon={<LeftOutlined />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (store.getFilePath().length === 1) {
|
||||||
|
if (files.length !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoadingFile(true);
|
||||||
getFiles(
|
getFiles(
|
||||||
currentBucket,
|
store.getCurrentBucket(),
|
||||||
|
"",
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
).then();
|
||||||
|
} else {
|
||||||
|
setLoadingFile(true);
|
||||||
|
getFiles(
|
||||||
|
store.getCurrentBucket(),
|
||||||
store.getMiddlePath(),
|
store.getMiddlePath(),
|
||||||
currentStorage,
|
store.getCurrentStorage(),
|
||||||
).then(() => {
|
).then(() => {
|
||||||
store.clearFilePath();
|
store.clearFilePath();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 20 }}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoadingFile(true);
|
||||||
|
getFiles(
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getFilePathExceptFirst(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
).then();
|
||||||
|
}}
|
||||||
icon={<RedoOutlined />}
|
icon={<RedoOutlined />}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -283,13 +353,60 @@ const File: FunctionComponent = () => {
|
|||||||
align={"center"}
|
align={"center"}
|
||||||
justify={"flex-start"}
|
justify={"flex-start"}
|
||||||
style={{ marginTop: 10 }}>
|
style={{ marginTop: 10 }}>
|
||||||
<Tooltip title="删除" placement={"bottom"}>
|
{/*<Tooltip title="删除" placement={"bottom"}>*/}
|
||||||
<Button shape="circle" icon={<DeleteOutlined />} />
|
{/* <Button shape="circle" icon={<DeleteOutlined />} />*/}
|
||||||
</Tooltip>
|
{/*</Tooltip>*/}
|
||||||
<Tooltip title="下载" placement={"bottom"}>
|
<Tooltip title="下载" placement={"bottom"}>
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 0 }}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (store.getCurrentFile() === null) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
downloadFiles(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getCurrentFile(),
|
||||||
|
).then((res: any) => {
|
||||||
|
const content = res.data;
|
||||||
|
const blob = new Blob([content]);
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.style.display = "none";
|
||||||
|
link.href = url;
|
||||||
|
|
||||||
|
// 取后端给前端返的请求头中的文件名称
|
||||||
|
const temp = res.headers["content-disposition"]
|
||||||
|
.split(";")[1]
|
||||||
|
.split("filename=")[1];
|
||||||
|
const fileName = decodeURIComponent(temp);
|
||||||
|
console.log("fileName:" + fileName);
|
||||||
|
|
||||||
|
link.download = fileName;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link); //下载完成移除元素
|
||||||
|
window.URL.revokeObjectURL(url); //释放掉blob对象
|
||||||
|
});
|
||||||
|
}}
|
||||||
icon={<DownloadOutlined />}
|
icon={<DownloadOutlined />}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -297,50 +414,324 @@ const File: FunctionComponent = () => {
|
|||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 20 }}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (store.getCurrentFile() !== null) {
|
||||||
|
previewFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getCurrentFile(),
|
||||||
|
).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
window.open(
|
||||||
|
"http://1.95.0.111:8012/onlinePreview?url=" +
|
||||||
|
encodeURIComponent(
|
||||||
|
Base64.encode(res.data) as any,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
icon={<EyeOutlined />}
|
icon={<EyeOutlined />}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="扫码下载" placement={"bottom"}>
|
<Tooltip title="扫码查看" placement={"bottom"}>
|
||||||
|
<Popover
|
||||||
|
placement="bottom"
|
||||||
|
title={"扫码查看"}
|
||||||
|
trigger="click"
|
||||||
|
content={
|
||||||
|
<>
|
||||||
|
<QRCode
|
||||||
|
errorLevel="H"
|
||||||
|
size={300}
|
||||||
|
iconSize={300 / 5}
|
||||||
|
value={previewUrl}
|
||||||
|
icon={logo as any}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}>
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 20 }}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (store.getCurrentFile() === null) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
previewFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getCurrentFile(),
|
||||||
|
).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setPreviewUrl(
|
||||||
|
"http://1.95.0.111:8012/onlinePreview?url=" +
|
||||||
|
encodeURIComponent(
|
||||||
|
Base64.encode(res.data) as any,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
icon={<QrcodeOutlined />}
|
icon={<QrcodeOutlined />}
|
||||||
/>
|
/>
|
||||||
|
</Popover>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="粘贴" placement={"bottom"}>
|
<Tooltip title="粘贴" placement={"bottom"}>
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 20 }}
|
||||||
|
disabled={disable}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (store.getCopyFile() === null) {
|
||||||
|
message.open({
|
||||||
|
content: "请先复制文件",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
copyFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getCopyFile(),
|
||||||
|
store.getFilePathExceptFirst() +
|
||||||
|
"/" +
|
||||||
|
store.getCopyFileName(),
|
||||||
|
).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "粘贴成功 ",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setDisable(true);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "粘贴失败 ",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
icon={<SnippetsOutlined />}
|
icon={<SnippetsOutlined />}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="剪切" placement={"bottom"}>
|
{/*<Tooltip title="剪切" placement={"bottom"}>*/}
|
||||||
<Button
|
{/* <Button*/}
|
||||||
style={{ marginLeft: 20 }}
|
{/* style={{ marginLeft: 20 }}*/}
|
||||||
shape="circle"
|
{/* shape="circle"*/}
|
||||||
icon={<ScissorOutlined />}
|
{/* icon={<ScissorOutlined />}*/}
|
||||||
/>
|
{/* />*/}
|
||||||
</Tooltip>
|
{/*</Tooltip>*/}
|
||||||
<Tooltip title="复制" placement={"bottom"}>
|
<Tooltip title="复制" placement={"bottom"}>
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 20 }}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (store.getCurrentFile() === null) {
|
||||||
|
message.open({
|
||||||
|
content: "请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
store.getCurrentFile() !== "" &&
|
||||||
|
store.getCurrentFile() !== null
|
||||||
|
) {
|
||||||
|
store.setCopyFile(store.getCurrentFile() as string);
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "复制成功 ",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setDisable(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
icon={<CopyOutlined />}
|
icon={<CopyOutlined />}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title="搜索" placement={"bottom"}>
|
{/*<Tooltip title="搜索" placement={"bottom"}>*/}
|
||||||
|
{/* <Button*/}
|
||||||
|
{/* style={{ marginLeft: 20 }}*/}
|
||||||
|
{/* shape="circle"*/}
|
||||||
|
{/* icon={<SearchOutlined />}*/}
|
||||||
|
{/* />*/}
|
||||||
|
{/*</Tooltip>*/}
|
||||||
|
<Tooltip title="重命名" placement={"bottom"}>
|
||||||
|
<Popover
|
||||||
|
onOpenChange={(value: any) => {
|
||||||
|
setOpenRename(value);
|
||||||
|
}}
|
||||||
|
open={openRename}
|
||||||
|
content={
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<Input
|
||||||
|
onChange={(e: any) => {
|
||||||
|
setNewFileName(e.target.value);
|
||||||
|
}}></Input>
|
||||||
|
<Button
|
||||||
|
shape={"circle"}
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (newFileName !== null) {
|
||||||
|
renameFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getCurrentFile(),
|
||||||
|
store.getFilePathExceptFirst() +
|
||||||
|
"/" +
|
||||||
|
newFileName,
|
||||||
|
).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "重命名成功!",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setNewFileName(null);
|
||||||
|
setOpenRename(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "重命名失败!",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请输入新文件名!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
icon={<CheckOutlined />}></Button>
|
||||||
|
</Flex>
|
||||||
|
}
|
||||||
|
title={"重命名:" + store.getCurrentFile()}
|
||||||
|
trigger="click">
|
||||||
<Button
|
<Button
|
||||||
style={{ marginLeft: 20 }}
|
style={{ marginLeft: 20 }}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<SearchOutlined />}
|
icon={<EditOutlined />}
|
||||||
|
onClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
store.getCurrentFile() === null ||
|
||||||
|
store.getCurrentFile() === ""
|
||||||
|
) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
setOpenRename(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
</Popover>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.file_right_content}>
|
<div className={styles.file_right_content}>
|
||||||
|
<Skeleton active loading={loadingFile} paragraph={{ rows: 13 }}>
|
||||||
<CheckCard.Group
|
<CheckCard.Group
|
||||||
multiple={true}
|
multiple={false}
|
||||||
bordered={false}
|
bordered={false}
|
||||||
className={styles.file_right_content}>
|
className={styles.file_right_content}>
|
||||||
{files.map((file: any, index: any) => {
|
{files.map((file: any, index: any) => {
|
||||||
@@ -350,24 +741,31 @@ const File: FunctionComponent = () => {
|
|||||||
key={index}
|
key={index}
|
||||||
menu={{
|
menu={{
|
||||||
items: [
|
items: [
|
||||||
{
|
// {
|
||||||
label: "删除",
|
// label: "删除",
|
||||||
key: "1",
|
// key: "delete",
|
||||||
},
|
// },
|
||||||
{
|
|
||||||
label: "编辑",
|
|
||||||
key: "2",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
trigger={["contextMenu"]}>
|
trigger={["contextMenu"]}>
|
||||||
<div
|
<div
|
||||||
style={{ marginLeft: 10 }}
|
style={{ marginLeft: 10 }}
|
||||||
onDoubleClick={() => {
|
onDoubleClick={() => {
|
||||||
|
if (
|
||||||
|
store.getCurrentBucket() === null ||
|
||||||
|
store.getCurrentStorage() === null
|
||||||
|
) {
|
||||||
|
message.open({
|
||||||
|
content: "请选择存储商和桶",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoadingTimeOut();
|
||||||
getFiles(
|
getFiles(
|
||||||
currentBucket,
|
store.getCurrentBucket(),
|
||||||
`${file.name}/`,
|
`${store.getFilePathExceptFirst()}/${file.name}`,
|
||||||
currentStorage,
|
store.getCurrentStorage(),
|
||||||
).then(() => {
|
).then(() => {
|
||||||
store.setFilePath(file.name);
|
store.setFilePath(file.name);
|
||||||
});
|
});
|
||||||
@@ -418,14 +816,136 @@ const File: FunctionComponent = () => {
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
key={index}
|
key={index}
|
||||||
menu={{
|
menu={{
|
||||||
|
onClick: ({ key }) => {
|
||||||
|
if (key === "delete") {
|
||||||
|
deleteFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getFilePathExceptFirst() +
|
||||||
|
"/" +
|
||||||
|
file.name,
|
||||||
|
).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功!",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: "删除失败!",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (key === "view") {
|
||||||
|
previewFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getFilePathExceptFirst() +
|
||||||
|
"/" +
|
||||||
|
file.name,
|
||||||
|
).then((res: any) => {
|
||||||
|
if (
|
||||||
|
res &&
|
||||||
|
res.success &&
|
||||||
|
res.data
|
||||||
|
) {
|
||||||
|
window.open(
|
||||||
|
"http://1.95.0.111:8012/onlinePreview?url=" +
|
||||||
|
encodeURIComponent(
|
||||||
|
Base64.encode(
|
||||||
|
res.data,
|
||||||
|
) as any,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (key === "copy") {
|
||||||
|
if (
|
||||||
|
store.getCurrentFile() !== "" &&
|
||||||
|
store.getCurrentFile() !== null
|
||||||
|
) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "复制成功 ",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
store.setCopyFile(
|
||||||
|
store.getCurrentFile() as string,
|
||||||
|
);
|
||||||
|
setDisable(false);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content:
|
||||||
|
"请先选择文件!",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
} else if (key === "paste") {
|
||||||
|
if (disable) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "请先复制文件",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
} else {
|
||||||
|
copyFile(
|
||||||
|
1,
|
||||||
|
store.getCurrentBucket(),
|
||||||
|
store.getCurrentStorage(),
|
||||||
|
store.getCopyFile(),
|
||||||
|
store.getFilePathExceptFirst() +
|
||||||
|
"/" +
|
||||||
|
store.getCopyFileName(),
|
||||||
|
).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content:
|
||||||
|
"粘贴成功 ",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setDisable(true);
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content:
|
||||||
|
"粘贴失败 ",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: "删除",
|
label: "复制",
|
||||||
key: "1",
|
key: "copy",
|
||||||
|
icon: <CopyOutlined />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "编辑",
|
label: "粘贴",
|
||||||
key: "2",
|
key: "paste",
|
||||||
|
icon: <SnippetsOutlined />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "删除",
|
||||||
|
key: "delete",
|
||||||
|
icon: <DeleteOutlined />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "预览",
|
||||||
|
key: "view",
|
||||||
|
icon: <EyeOutlined />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
@@ -434,6 +954,24 @@ const File: FunctionComponent = () => {
|
|||||||
<CheckCard
|
<CheckCard
|
||||||
size={"small"}
|
size={"small"}
|
||||||
value={file.name}
|
value={file.name}
|
||||||
|
onChange={(value: any) => {
|
||||||
|
if (value) {
|
||||||
|
const pathExceptFirst =
|
||||||
|
store.getFilePathExceptFirst();
|
||||||
|
const fileValue =
|
||||||
|
pathExceptFirst +
|
||||||
|
"/" +
|
||||||
|
file.name;
|
||||||
|
store.setCurrentFile(fileValue);
|
||||||
|
store.setCopyFileName(
|
||||||
|
file.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (value === false) {
|
||||||
|
store.setCopyFileName("");
|
||||||
|
store.setCurrentFile("");
|
||||||
|
}
|
||||||
|
}}
|
||||||
bodyStyle={{ overflow: "hidden" }}
|
bodyStyle={{ overflow: "hidden" }}
|
||||||
avatar={
|
avatar={
|
||||||
<div
|
<div
|
||||||
@@ -484,6 +1022,7 @@ const File: FunctionComponent = () => {
|
|||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</CheckCard.Group>
|
</CheckCard.Group>
|
||||||
|
</Skeleton>
|
||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
@@ -502,7 +1041,7 @@ const File: FunctionComponent = () => {
|
|||||||
open={open}
|
open={open}
|
||||||
width={"50%"}
|
width={"50%"}
|
||||||
onCancel={() => setOpen(false)}>
|
onCancel={() => setOpen(false)}>
|
||||||
<FileUpload></FileUpload>
|
<FileUpload userStorage={userStorage}></FileUpload>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
import React, { memo, useEffect, useState } from "react";
|
import React, { memo, useEffect, useState } from "react";
|
||||||
import { Avatar, Card, Flex, message, Skeleton, Space, Tag, Tooltip } from "antd";
|
import { Avatar, Card, Flex, message, Skeleton, Tooltip } from "antd";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import ReactECharts from "echarts-for-react";
|
import ReactECharts from "echarts-for-react";
|
||||||
import { ProCard, ProList } from "@ant-design/pro-components";
|
import { ProCard, ProList } from "@ant-design/pro-components";
|
||||||
@@ -17,11 +17,13 @@ import {
|
|||||||
getUserDownloadFileDiagramPerMonth,
|
getUserDownloadFileDiagramPerMonth,
|
||||||
getUserFileCount,
|
getUserFileCount,
|
||||||
getUserFileFlow,
|
getUserFileFlow,
|
||||||
getUserFileHeatMap, getUserRecentDownloadFile, getUserRecentPreviewFile, getUserRecentUploadFile,
|
getUserFileHeatMap,
|
||||||
getUserUploadFileDiagramPerMonth
|
getUserRecentPreviewFile,
|
||||||
|
getUserRecentUploadFile,
|
||||||
|
getUserUploadFileDiagramPerMonth,
|
||||||
} from "@/api/oss";
|
} from "@/api/oss";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { EyeOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||||
import FileIcon from "@/constant/file-icon.ts";
|
import FileIcon from "@/constant/file-icon.ts";
|
||||||
import file_icon from "@/assets/icons/files/file.svg";
|
import file_icon from "@/assets/icons/files/file.svg";
|
||||||
|
|
||||||
@@ -42,10 +44,9 @@ const MainHome: React.FC = () => {
|
|||||||
const [monthUpload, setMonthUpload] = useState<any>([]);
|
const [monthUpload, setMonthUpload] = useState<any>([]);
|
||||||
const [monthDownload, setMonthDownload] = useState<any>([]);
|
const [monthDownload, setMonthDownload] = useState<any>([]);
|
||||||
const [recentUploadFile, setRecentUploadFile] = useState<any>([]);
|
const [recentUploadFile, setRecentUploadFile] = useState<any>([]);
|
||||||
const [recentDownloadFile, setRecentDownloadFile] = useState<any>([]);
|
// const [recentDownloadFile, setRecentDownloadFile] = useState<any>([]);
|
||||||
const [recentPreviewFile, setRecentPreviewFile] = useState<any>([]);
|
const [recentPreviewFile, setRecentPreviewFile] = useState<any>([]);
|
||||||
|
|
||||||
|
|
||||||
// 获取存储同和存储商的个数
|
// 获取存储同和存储商的个数
|
||||||
async function getStorageAndBucketsCount() {
|
async function getStorageAndBucketsCount() {
|
||||||
return getStorageAndBuckets("1").then((res: any) => {
|
return getStorageAndBuckets("1").then((res: any) => {
|
||||||
@@ -101,7 +102,7 @@ const MainHome: React.FC = () => {
|
|||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setMonthUpload(res.data);
|
setMonthUpload(res.data);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
// 获取用户最近上传文件
|
// 获取用户最近上传文件
|
||||||
async function getRecentUploadFile() {
|
async function getRecentUploadFile() {
|
||||||
@@ -109,23 +110,23 @@ const MainHome: React.FC = () => {
|
|||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setRecentUploadFile(res.data);
|
setRecentUploadFile(res.data);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
//获取用户最近下载文件
|
//获取用户最近下载文件
|
||||||
async function getRecentDownloadFile() {
|
// async function getRecentDownloadFile() {
|
||||||
getUserRecentDownloadFile(1).then((res: any)=>{
|
// getUserRecentDownloadFile(1).then((res: any) => {
|
||||||
if(res && res.success && res.data){
|
// if (res && res.success && res.data) {
|
||||||
setRecentDownloadFile(res.data);
|
// setRecentDownloadFile(res.data);
|
||||||
}
|
// }
|
||||||
})
|
// });
|
||||||
}
|
// }
|
||||||
//获取用户最近预览文件
|
//获取用户最近预览文件
|
||||||
async function getRecentPreviewFile() {
|
async function getRecentPreviewFile() {
|
||||||
getUserRecentPreviewFile(1).then((res:any)=>{
|
getUserRecentPreviewFile(1).then((res: any) => {
|
||||||
if(res && res.success && res.data){
|
if (res && res.success && res.data) {
|
||||||
setRecentPreviewFile(res.data);
|
setRecentPreviewFile(res.data);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
const option = {
|
const option = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@@ -145,7 +146,8 @@ const MainHome: React.FC = () => {
|
|||||||
height: "80%",
|
height: "80%",
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
xAxis: [{
|
xAxis: [
|
||||||
|
{
|
||||||
type: "time",
|
type: "time",
|
||||||
// data: month,
|
// data: month,
|
||||||
axisLine: {
|
axisLine: {
|
||||||
@@ -153,7 +155,8 @@ const MainHome: React.FC = () => {
|
|||||||
color: "#999",
|
color: "#999",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: "value",
|
type: "value",
|
||||||
|
|
||||||
@@ -257,9 +260,8 @@ const MainHome: React.FC = () => {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getStorageAndBucketsCount().then(()=>{
|
getStorageAndBucketsCount().then(() => {
|
||||||
getUploadDownloadFlux().then(() => {
|
getUploadDownloadFlux().then(() => {
|
||||||
getUploadDownloadCount().then(() => {
|
getUploadDownloadCount().then(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -268,27 +270,25 @@ const MainHome: React.FC = () => {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFileHeatMap().then(()=>{
|
getFileHeatMap().then(() => {
|
||||||
setLoadingHeatmap(false);
|
setLoadingHeatmap(false);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getDownloadCountByMonth().then(()=>{
|
getDownloadCountByMonth().then(() => {
|
||||||
getUploadCountByMonth().then(()=>{
|
getUploadCountByMonth().then(() => {
|
||||||
setLoadingEChart(false);
|
setLoadingEChart(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRecentUploadFile().then(()=>{
|
getRecentUploadFile().then(() => {
|
||||||
setLoadingRecentFile(false);
|
setLoadingRecentFile(false);
|
||||||
});
|
});
|
||||||
getRecentPreviewFile().then(()=>{
|
getRecentPreviewFile().then(() => {
|
||||||
setLoadingPreviewFile(false);
|
setLoadingPreviewFile(false);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
@@ -343,11 +343,20 @@ const MainHome: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"} justify={"flex-end"} style={{marginTop: 50}}>
|
<Flex
|
||||||
<Tooltip title={"存储商个数,点击查看详情"} color={"#47D8BE"}>
|
vertical={false}
|
||||||
<InfoCircleOutlined onClick={()=>{
|
align={"center"}
|
||||||
navigate("/main/setting")
|
justify={"flex-end"}
|
||||||
}} className={styles.home_content_icon}/>
|
style={{ marginTop: 50 }}>
|
||||||
|
<Tooltip
|
||||||
|
title={"存储商个数,点击查看详情"}
|
||||||
|
color={"#47D8BE"}>
|
||||||
|
<InfoCircleOutlined
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/main/setting");
|
||||||
|
}}
|
||||||
|
className={styles.home_content_icon}
|
||||||
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -395,11 +404,20 @@ const MainHome: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"} justify={"flex-end"} style={{marginTop: 50}}>
|
<Flex
|
||||||
<Tooltip title={"存储桶个数,点击查看详情"} color={"#47D8BE"}>
|
vertical={false}
|
||||||
<InfoCircleOutlined onClick={()=>{
|
align={"center"}
|
||||||
navigate("/main/bucket")
|
justify={"flex-end"}
|
||||||
}} className={styles.home_content_icon}/>
|
style={{ marginTop: 50 }}>
|
||||||
|
<Tooltip
|
||||||
|
title={"存储桶个数,点击查看详情"}
|
||||||
|
color={"#47D8BE"}>
|
||||||
|
<InfoCircleOutlined
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/main/bucket");
|
||||||
|
}}
|
||||||
|
className={styles.home_content_icon}
|
||||||
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -567,11 +585,12 @@ const MainHome: React.FC = () => {
|
|||||||
showMonthLabels={true}
|
showMonthLabels={true}
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
showWeekdayLabels={false}
|
showWeekdayLabels={false}
|
||||||
onClick={(value:any)=>{
|
onClick={(value: any) => {
|
||||||
if(value!==null) {
|
if (value !== null) {
|
||||||
message.open({
|
message
|
||||||
|
.open({
|
||||||
content: (<>
|
content: (
|
||||||
|
<>
|
||||||
<Flex vertical={true}>
|
<Flex vertical={true}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
日期:{value.date}
|
日期:{value.date}
|
||||||
@@ -580,12 +599,13 @@ const MainHome: React.FC = () => {
|
|||||||
数量:{value.count}
|
数量:{value.count}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>),
|
</>
|
||||||
type:"success",
|
),
|
||||||
|
type: "success",
|
||||||
duration: 2,
|
duration: 2,
|
||||||
}).then();
|
})
|
||||||
|
.then();
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
monthLabels={[
|
monthLabels={[
|
||||||
"一月",
|
"一月",
|
||||||
@@ -632,36 +652,43 @@ const MainHome: React.FC = () => {
|
|||||||
dataIndex: "fileName",
|
dataIndex: "fileName",
|
||||||
},
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
render: (text: any,record: any) => {
|
render: (_: any, record: any) => {
|
||||||
if(record.fileName) {
|
if (record.fileName) {
|
||||||
return (<>
|
return (
|
||||||
|
<>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={
|
src={
|
||||||
FileIcon[getFileExtension(record.fileName)] || file_icon
|
FileIcon[
|
||||||
|
getFileExtension(
|
||||||
|
record.fileName,
|
||||||
|
)
|
||||||
|
] || file_icon
|
||||||
}
|
}
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
</>)
|
</>
|
||||||
}else {
|
);
|
||||||
return (<>
|
} else {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={file_icon as any}
|
src={file_icon as any}
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
</>)
|
</>
|
||||||
}
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
description: {
|
description: {
|
||||||
dataIndex: "size",
|
dataIndex: "size",
|
||||||
valueType: "text"
|
valueType: "text",
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
dataIndex: "time"
|
dataIndex: "time",
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
@@ -682,36 +709,43 @@ const MainHome: React.FC = () => {
|
|||||||
dataIndex: "fileName",
|
dataIndex: "fileName",
|
||||||
},
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
render: (text: any,record: any) => {
|
render: (_: any, record: any) => {
|
||||||
if(record.fileName) {
|
if (record.fileName) {
|
||||||
return (<>
|
return (
|
||||||
|
<>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={
|
src={
|
||||||
FileIcon[getFileExtension(record.fileName)] || file_icon
|
FileIcon[
|
||||||
|
getFileExtension(
|
||||||
|
record.fileName,
|
||||||
|
)
|
||||||
|
] || file_icon
|
||||||
}
|
}
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
</>)
|
</>
|
||||||
}else {
|
);
|
||||||
return (<>
|
} else {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={file_icon as any}
|
src={file_icon as any}
|
||||||
shape={"square"}
|
shape={"square"}
|
||||||
size={"large"}
|
size={"large"}
|
||||||
/>
|
/>
|
||||||
</>)
|
</>
|
||||||
}
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
description: {
|
description: {
|
||||||
dataIndex: "size",
|
dataIndex: "size",
|
||||||
valueType: "text",
|
valueType: "text",
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
dataIndex: "time"
|
dataIndex: "time",
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
|
@@ -2,22 +2,38 @@
|
|||||||
import { PlusOutlined } from "@ant-design/icons";
|
import { PlusOutlined } from "@ant-design/icons";
|
||||||
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
||||||
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
||||||
import { Button, Col, Drawer, Form, Input, Row, Space } from "antd";
|
import {
|
||||||
|
Button,
|
||||||
|
Col,
|
||||||
|
Drawer,
|
||||||
|
Flex,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
message,
|
||||||
|
Modal,
|
||||||
|
Row,
|
||||||
|
Space,
|
||||||
|
} from "antd";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { getAllAliOSSConfig } from "@/api/oss/ali";
|
import {
|
||||||
|
addAliOSSConfig,
|
||||||
|
deleteAliConfig,
|
||||||
|
getAliConfigDetailById,
|
||||||
|
getAllAliOSSConfig,
|
||||||
|
initAliOSS,
|
||||||
|
setAliShutdown,
|
||||||
|
updateAliConfig,
|
||||||
|
} from "@/api/oss/ali";
|
||||||
|
|
||||||
type AliOssConfigItem = {
|
const AliSettings: React.FC = () => {
|
||||||
id: number;
|
const [form] = Form.useForm();
|
||||||
userId: number;
|
const actionRef = useRef<ActionType>();
|
||||||
endpoint: string;
|
const [open, setOpen] = useState(false);
|
||||||
accessKeyId: string;
|
const [openModal, setOpenModal] = useState(false);
|
||||||
accessKeySecret: string;
|
const [configs, setConfigs] = useState<any>([]);
|
||||||
createdTime: string;
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
updateTime: string;
|
const [configDetail, setConfigDetail] = useState<object>({});
|
||||||
status: string;
|
const columns: ProColumns<any[]>[] = [
|
||||||
};
|
|
||||||
|
|
||||||
const columns: ProColumns<AliOssConfigItem>[] = [
|
|
||||||
{
|
{
|
||||||
dataIndex: "index",
|
dataIndex: "index",
|
||||||
valueType: "indexBorder",
|
valueType: "indexBorder",
|
||||||
@@ -25,10 +41,12 @@ const columns: ProColumns<AliOssConfigItem>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "ID",
|
title: "ID",
|
||||||
|
valueType: "text",
|
||||||
dataIndex: "id",
|
dataIndex: "id",
|
||||||
copyable: true,
|
copyable: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: "Id",
|
tooltip: "Id",
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disable: true,
|
disable: true,
|
||||||
@@ -59,18 +77,25 @@ const columns: ProColumns<AliOssConfigItem>[] = [
|
|||||||
dataIndex: "createdTime",
|
dataIndex: "createdTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "更新时间",
|
title: "更新时间",
|
||||||
dataIndex: "updateTime",
|
dataIndex: "updateTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disable: true,
|
disable: true,
|
||||||
title: "状态",
|
title: "状态",
|
||||||
dataIndex: "status",
|
dataIndex: "status",
|
||||||
search: true,
|
search: true,
|
||||||
|
valueEnum: {
|
||||||
|
true: { text: "开启", status: "Success" },
|
||||||
|
false: { text: "关闭", status: "Error" },
|
||||||
|
},
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
@@ -86,34 +111,126 @@ const columns: ProColumns<AliOssConfigItem>[] = [
|
|||||||
}}>
|
}}>
|
||||||
编辑
|
编辑
|
||||||
</a>,
|
</a>,
|
||||||
<a target="_blank" rel="noopener noreferrer" key="view">
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
key="view"
|
||||||
|
onClick={() => {
|
||||||
|
getConfigDetail(record.id).then(() => {
|
||||||
|
setOpenModal(true);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}}>
|
||||||
查看
|
查看
|
||||||
</a>,
|
</a>,
|
||||||
<TableDropdown
|
<TableDropdown
|
||||||
key="actionGroup"
|
key="actionGroup"
|
||||||
onSelect={() => action?.reload()}
|
onSelect={(key: string) => {
|
||||||
|
if (key === "open") {
|
||||||
|
init(record.id).then();
|
||||||
|
} else if (key === "close") {
|
||||||
|
shutdown(record.id).then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
menus={[
|
menus={[
|
||||||
{ key: "copy", name: "复制" },
|
{ key: "open", name: "开启" },
|
||||||
{ key: "delete", name: "删除" },
|
{ key: "close", name: "关闭" },
|
||||||
]}
|
]}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const AliSettings: React.FC = () => {
|
|
||||||
const actionRef = useRef<ActionType>();
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [configs, setConfigs] = useState<AliOssConfigItem[]>([]);
|
|
||||||
|
|
||||||
async function getAllConfig() {
|
async function getAllConfig() {
|
||||||
getAllAliOSSConfig(1).then((res) => {
|
getAllAliOSSConfig("1").then((res: any) => {
|
||||||
console.log(res);
|
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setConfigs(res.data);
|
setConfigs(res.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
async function getConfigDetail(id: any) {
|
||||||
|
getAliConfigDetailById(id).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setConfigDetail(res.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function init(id: any) {
|
||||||
|
initAliOSS("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "开启成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function shutdown(id: any) {
|
||||||
|
setAliShutdown("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function deleteConfig(id: any) {
|
||||||
|
const form: any = {
|
||||||
|
id: id,
|
||||||
|
isDeleted: 1,
|
||||||
|
};
|
||||||
|
deleteAliConfig(form).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function addConfigs() {
|
||||||
|
const fieldsValue = form.getFieldsValue();
|
||||||
|
const AliOssConfig = {
|
||||||
|
userId: "1",
|
||||||
|
...fieldsValue,
|
||||||
|
};
|
||||||
|
addAliOSSConfig(AliOssConfig).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
onClose();
|
||||||
|
getAllConfig().then(() => {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "新增成功",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
const showDrawer = () => {
|
const showDrawer = () => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
@@ -121,7 +238,7 @@ const AliSettings: React.FC = () => {
|
|||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllConfig();
|
getAllConfig().then();
|
||||||
}, []);
|
}, []);
|
||||||
const AddAliOssConfigDrawer = () => {
|
const AddAliOssConfigDrawer = () => {
|
||||||
return (
|
return (
|
||||||
@@ -139,12 +256,12 @@ const AliSettings: React.FC = () => {
|
|||||||
extra={
|
extra={
|
||||||
<Space>
|
<Space>
|
||||||
<Button onClick={onClose}>取消</Button>
|
<Button onClick={onClose}>取消</Button>
|
||||||
<Button onClick={onClose} type="primary">
|
<Button onClick={addConfigs} type="primary">
|
||||||
提交
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
}>
|
}>
|
||||||
<Form layout="vertical">
|
<Form layout="vertical" form={form}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -180,14 +297,52 @@ const AliSettings: React.FC = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ height: "65vh" }}>
|
<div style={{ minHeight: "65vh" }}>
|
||||||
<ProTable<AliOssConfigItem>
|
<ProTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={configs}
|
dataSource={configs}
|
||||||
actionRef={actionRef}
|
actionRef={actionRef}
|
||||||
cardBordered={true}
|
cardBordered={true}
|
||||||
editable={{
|
editable={{
|
||||||
type: "multiple",
|
type: "multiple",
|
||||||
|
onSave: async (__: any, originRow: any, _: any) => {
|
||||||
|
const updateForm: any = {
|
||||||
|
id: originRow.id,
|
||||||
|
endpoint: originRow.endpoint,
|
||||||
|
accessKeyId: originRow.accessKeyId,
|
||||||
|
accessKeySecret: originRow.accessKeySecret,
|
||||||
|
};
|
||||||
|
updateAliConfig(updateForm).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "修改成功!",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDelete: async (row: any) => {
|
||||||
|
deleteConfig(row).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
columnsState={{
|
columnsState={{
|
||||||
persistenceKey: "pro-table-singe-demos",
|
persistenceKey: "pro-table-singe-demos",
|
||||||
@@ -224,6 +379,43 @@ const AliSettings: React.FC = () => {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<AddAliOssConfigDrawer />
|
<AddAliOssConfigDrawer />
|
||||||
|
<Modal
|
||||||
|
title={<p>配置详情</p>}
|
||||||
|
loading={loading}
|
||||||
|
footer={false}
|
||||||
|
open={openModal}
|
||||||
|
afterClose={() => {
|
||||||
|
setConfigDetail({});
|
||||||
|
}}
|
||||||
|
onCancel={() => setOpenModal(false)}>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>ID:</h4> <span style={{ marginLeft: 10 }}>{configDetail.id}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>endpoint: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.endpoint}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>accessKeyId: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.accessKeyId} </span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>accessKeySecret: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.accessKeySecret}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>status: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.status}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>createdTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.createdTime}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>updateTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.updateTime}</span>
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -2,9 +2,17 @@
|
|||||||
import { PlusOutlined } from "@ant-design/icons";
|
import { PlusOutlined } from "@ant-design/icons";
|
||||||
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
||||||
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
||||||
import { Button, Col, Drawer, Form, Input, Row, Space } from "antd";
|
import { Button, Col, Drawer, Flex, Form, Input, message, Modal, Row, Space } from "antd";
|
||||||
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
||||||
import { getAllMinioConfig } from "@/api/oss/minio";
|
import {
|
||||||
|
addMinioOSSConfig,
|
||||||
|
deleteMinioConfig,
|
||||||
|
getAllMinioConfig,
|
||||||
|
getMinioConfigDetailById,
|
||||||
|
initMinioOSS,
|
||||||
|
setMinioShutdown,
|
||||||
|
updateMinioConfig,
|
||||||
|
} from "@/api/oss/minio";
|
||||||
|
|
||||||
type MinioOssConfigItem = {
|
type MinioOssConfigItem = {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -17,11 +25,20 @@ type MinioOssConfigItem = {
|
|||||||
status: string;
|
status: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns: ProColumns<MinioOssConfigItem>[] = [
|
const MinioSettings: React.FC = () => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [configs, setConfigs] = useState<MinioOssConfigItem[]>([]);
|
||||||
|
const [openModal, setOpenModal] = useState(false);
|
||||||
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [configDetail, setConfigDetail] = useState<object>({});
|
||||||
|
const columns: ProColumns<MinioOssConfigItem>[] = [
|
||||||
{
|
{
|
||||||
dataIndex: "index",
|
dataIndex: "index",
|
||||||
valueType: "indexBorder",
|
valueType: "indexBorder",
|
||||||
width: 48,
|
width: 48,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "ID",
|
title: "ID",
|
||||||
@@ -29,6 +46,7 @@ const columns: ProColumns<MinioOssConfigItem>[] = [
|
|||||||
copyable: true,
|
copyable: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: "Id",
|
tooltip: "Id",
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disable: true,
|
disable: true,
|
||||||
@@ -54,24 +72,32 @@ const columns: ProColumns<MinioOssConfigItem>[] = [
|
|||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
copyable: true,
|
copyable: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
disable: true,
|
|
||||||
title: "状态",
|
|
||||||
dataIndex: "status",
|
|
||||||
search: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
dataIndex: "createdTime",
|
dataIndex: "createdTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "更新时间",
|
title: "更新时间",
|
||||||
dataIndex: "updateTime",
|
dataIndex: "updateTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
editable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disable: true,
|
||||||
|
title: "状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
search: true,
|
||||||
|
valueEnum: {
|
||||||
|
true: { text: "开启", status: "Success" },
|
||||||
|
false: { text: "关闭", status: "Error" },
|
||||||
|
},
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
@@ -79,7 +105,7 @@ const columns: ProColumns<MinioOssConfigItem>[] = [
|
|||||||
key: "option",
|
key: "option",
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
render: (text: ReactNode, record: MinioOssConfigItem, _: number, action: any) => [
|
render: (text: ReactNode, record: any, _: number, action: any) => [
|
||||||
<a
|
<a
|
||||||
key="editable"
|
key="editable"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -87,25 +113,35 @@ const columns: ProColumns<MinioOssConfigItem>[] = [
|
|||||||
}}>
|
}}>
|
||||||
编辑
|
编辑
|
||||||
</a>,
|
</a>,
|
||||||
<a target="_blank" rel="noopener noreferrer" key="view">
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
key="view"
|
||||||
|
onClick={() => {
|
||||||
|
getConfigDetail(record.id).then(() => {
|
||||||
|
setOpenModal(true);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}}>
|
||||||
查看
|
查看
|
||||||
</a>,
|
</a>,
|
||||||
<TableDropdown
|
<TableDropdown
|
||||||
key="actionGroup"
|
key="actionGroup"
|
||||||
onSelect={() => action?.reload()}
|
onSelect={(key: string) => {
|
||||||
|
if (key === "open") {
|
||||||
|
init(record.id).then();
|
||||||
|
} else if (key === "close") {
|
||||||
|
shutdown(record.id).then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
menus={[
|
menus={[
|
||||||
{ key: "copy", name: "复制" },
|
{ key: "open", name: "开启" },
|
||||||
{ key: "delete", name: "删除" },
|
{ key: "close", name: "关闭" },
|
||||||
]}
|
]}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const MinioSettings: React.FC = () => {
|
|
||||||
const actionRef = useRef<ActionType>();
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [configs, setConfigs] = useState<MinioOssConfigItem[]>([]);
|
|
||||||
const showDrawer = () => {
|
const showDrawer = () => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
@@ -114,14 +150,101 @@ const MinioSettings: React.FC = () => {
|
|||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function getConfigDetail(id: any) {
|
||||||
|
getMinioConfigDetailById(id).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setConfigDetail(res.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init(id: any) {
|
||||||
|
initMinioOSS("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "开启成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function shutdown(id: any) {
|
||||||
|
setMinioShutdown("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteConfig(id: any) {
|
||||||
|
const form: any = {
|
||||||
|
id: id,
|
||||||
|
isDeleted: 1,
|
||||||
|
};
|
||||||
|
deleteMinioConfig(form).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function getAllConfig() {
|
async function getAllConfig() {
|
||||||
getAllMinioConfig(1).then((res: any) => {
|
getAllMinioConfig("1").then((res: any) => {
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setConfigs(res.data);
|
setConfigs(res.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addMinioConfig() {
|
||||||
|
const fieldsValue = form.getFieldsValue();
|
||||||
|
const MinioOssConfig = {
|
||||||
|
userId: "1",
|
||||||
|
...fieldsValue,
|
||||||
|
};
|
||||||
|
addMinioOSSConfig(MinioOssConfig).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "新增成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then(() => {
|
||||||
|
onClose();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllConfig().then();
|
getAllConfig().then();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -130,7 +253,7 @@ const MinioSettings: React.FC = () => {
|
|||||||
<>
|
<>
|
||||||
<Drawer
|
<Drawer
|
||||||
title="创建连接配置"
|
title="创建连接配置"
|
||||||
width={720}
|
width={"45%"}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
open={open}
|
open={open}
|
||||||
styles={{
|
styles={{
|
||||||
@@ -141,12 +264,12 @@ const MinioSettings: React.FC = () => {
|
|||||||
extra={
|
extra={
|
||||||
<Space>
|
<Space>
|
||||||
<Button onClick={onClose}>取消</Button>
|
<Button onClick={onClose}>取消</Button>
|
||||||
<Button onClick={onClose} type="primary">
|
<Button onClick={addMinioConfig} type="primary">
|
||||||
提交
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
}>
|
}>
|
||||||
<Form layout="vertical">
|
<Form layout="vertical" form={form}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -182,7 +305,7 @@ const MinioSettings: React.FC = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ height: "65vh" }}>
|
<div style={{ minHeight: "65vh" }}>
|
||||||
<ProTable<MinioOssConfigItem>
|
<ProTable<MinioOssConfigItem>
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={configs}
|
dataSource={configs}
|
||||||
@@ -190,6 +313,44 @@ const MinioSettings: React.FC = () => {
|
|||||||
cardBordered={true}
|
cardBordered={true}
|
||||||
editable={{
|
editable={{
|
||||||
type: "multiple",
|
type: "multiple",
|
||||||
|
onSave: async (__: any, originRow: any, _: any) => {
|
||||||
|
const updateForm: any = {
|
||||||
|
id: originRow.id,
|
||||||
|
endpoint: originRow.endpoint,
|
||||||
|
accessKey: originRow.accessKey,
|
||||||
|
secretKey: originRow.secretKey,
|
||||||
|
};
|
||||||
|
updateMinioConfig(updateForm).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "修改成功!",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDelete: async (row: any) => {
|
||||||
|
deleteConfig(row).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfig().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
columnsState={{
|
columnsState={{
|
||||||
persistenceKey: "pro-table-singe-demos",
|
persistenceKey: "pro-table-singe-demos",
|
||||||
@@ -226,6 +387,43 @@ const MinioSettings: React.FC = () => {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<AddMinioOssConfigDrawer />
|
<AddMinioOssConfigDrawer />
|
||||||
|
<Modal
|
||||||
|
title={<p>配置详情</p>}
|
||||||
|
loading={loading}
|
||||||
|
footer={false}
|
||||||
|
afterClose={() => {
|
||||||
|
setConfigDetail({});
|
||||||
|
}}
|
||||||
|
open={openModal}
|
||||||
|
onCancel={() => setOpenModal(false)}>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>ID:</h4> <span style={{ marginLeft: 10 }}>{configDetail.id}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>endpoint: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.endpoint}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>accessKey: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.accessKey} </span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>secretKey: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.secretKey}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>status: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.status}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>createdTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.createdTime}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>updateTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.updateTime}</span>
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -2,9 +2,17 @@
|
|||||||
import { PlusOutlined } from "@ant-design/icons";
|
import { PlusOutlined } from "@ant-design/icons";
|
||||||
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
||||||
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
||||||
import { Button, Col, Drawer, Form, Input, Row, Space } from "antd";
|
import { Button, Col, Drawer, Flex, Form, Input, message, Modal, Row, Space } from "antd";
|
||||||
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
||||||
import { getAllQiniuConfigs } from "@/api/oss/qiniu";
|
import {
|
||||||
|
addQiniuOSSConfig,
|
||||||
|
deleteQiniuConfig,
|
||||||
|
getAllQiniuConfigs,
|
||||||
|
getQiniuConfigDetailById,
|
||||||
|
initQiniuOSS,
|
||||||
|
setQiniuShutdown,
|
||||||
|
updateQiniuConfig,
|
||||||
|
} from "@/api/oss/qiniu";
|
||||||
|
|
||||||
type QiniuOssConfigItem = {
|
type QiniuOssConfigItem = {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -17,11 +25,20 @@ type QiniuOssConfigItem = {
|
|||||||
status: string;
|
status: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns: ProColumns<QiniuOssConfigItem>[] = [
|
const QiniuSettings: React.FC = () => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [config, setConfig] = useState<QiniuOssConfigItem[]>([]);
|
||||||
|
const [openModal, setOpenModal] = useState(false);
|
||||||
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [configDetail, setConfigDetail] = useState<object>({});
|
||||||
|
const columns: ProColumns<QiniuOssConfigItem>[] = [
|
||||||
{
|
{
|
||||||
dataIndex: "index",
|
dataIndex: "index",
|
||||||
valueType: "indexBorder",
|
valueType: "indexBorder",
|
||||||
width: 48,
|
width: 48,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "ID",
|
title: "ID",
|
||||||
@@ -29,6 +46,7 @@ const columns: ProColumns<QiniuOssConfigItem>[] = [
|
|||||||
copyable: true,
|
copyable: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: "Id",
|
tooltip: "Id",
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disable: true,
|
disable: true,
|
||||||
@@ -54,24 +72,32 @@ const columns: ProColumns<QiniuOssConfigItem>[] = [
|
|||||||
copyable: true,
|
copyable: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
disable: true,
|
|
||||||
title: "状态",
|
|
||||||
dataIndex: "status",
|
|
||||||
search: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
dataIndex: "createdTime",
|
dataIndex: "createdTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "更新时间",
|
title: "更新时间",
|
||||||
dataIndex: "updateTime",
|
dataIndex: "updateTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
editable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disable: true,
|
||||||
|
title: "状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
search: true,
|
||||||
|
valueEnum: {
|
||||||
|
true: { text: "开启", status: "Success" },
|
||||||
|
false: { text: "关闭", status: "Error" },
|
||||||
|
},
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
@@ -87,25 +113,99 @@ const columns: ProColumns<QiniuOssConfigItem>[] = [
|
|||||||
}}>
|
}}>
|
||||||
编辑
|
编辑
|
||||||
</a>,
|
</a>,
|
||||||
<a target="_blank" rel="noopener noreferrer" key="view">
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
key="view"
|
||||||
|
onClick={() => {
|
||||||
|
getConfigDetail(record.id).then(() => {
|
||||||
|
setOpenModal(true);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}}>
|
||||||
查看
|
查看
|
||||||
</a>,
|
</a>,
|
||||||
<TableDropdown
|
<TableDropdown
|
||||||
key="actionGroup"
|
key="actionGroup"
|
||||||
onSelect={() => action?.reload()}
|
onSelect={(key: string) => {
|
||||||
|
if (key === "open") {
|
||||||
|
init(record.id).then();
|
||||||
|
} else if (key === "close") {
|
||||||
|
shutdown(record.id).then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
menus={[
|
menus={[
|
||||||
{ key: "copy", name: "复制" },
|
{ key: "open", name: "开启" },
|
||||||
{ key: "delete", name: "删除" },
|
{ key: "close", name: "关闭" },
|
||||||
]}
|
]}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
async function init(id: any) {
|
||||||
|
initQiniuOSS("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "开启成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getConfigDetail(id: any) {
|
||||||
|
getQiniuConfigDetailById(id).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setConfigDetail(res.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function shutdown(id: any) {
|
||||||
|
setQiniuShutdown("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteConfig(id: any) {
|
||||||
|
const form: any = {
|
||||||
|
id: id,
|
||||||
|
isDeleted: 1,
|
||||||
|
};
|
||||||
|
deleteQiniuConfig(form).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const QiniuSettings: React.FC = () => {
|
|
||||||
const actionRef = useRef<ActionType>();
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [config, setConfig] = useState<QiniuOssConfigItem[]>([]);
|
|
||||||
const showDrawer = () => {
|
const showDrawer = () => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
@@ -113,7 +213,8 @@ const QiniuSettings: React.FC = () => {
|
|||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
async function getAllCOnfigs() {
|
|
||||||
|
async function getAllConfigs() {
|
||||||
getAllQiniuConfigs(1).then((res: any) => {
|
getAllQiniuConfigs(1).then((res: any) => {
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setConfig(res.data);
|
setConfig(res.data);
|
||||||
@@ -121,15 +222,39 @@ const QiniuSettings: React.FC = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addQiniuoConfig() {
|
||||||
|
const fieldsValue = form.getFieldsValue();
|
||||||
|
const QiniuOssConfig = {
|
||||||
|
userId: 1,
|
||||||
|
...fieldsValue,
|
||||||
|
};
|
||||||
|
addQiniuOSSConfig(QiniuOssConfig).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "新增成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then(() => {
|
||||||
|
onClose();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllCOnfigs().then();
|
getAllConfigs().then();
|
||||||
}, []);
|
}, []);
|
||||||
const AddQiniuOssConfigDrawer = () => {
|
const AddQiniuOssConfigDrawer = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Drawer
|
<Drawer
|
||||||
title="创建连接配置"
|
title="创建连接配置"
|
||||||
width={720}
|
width={"45%"}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
open={open}
|
open={open}
|
||||||
styles={{
|
styles={{
|
||||||
@@ -140,12 +265,12 @@ const QiniuSettings: React.FC = () => {
|
|||||||
extra={
|
extra={
|
||||||
<Space>
|
<Space>
|
||||||
<Button onClick={onClose}>取消</Button>
|
<Button onClick={onClose}>取消</Button>
|
||||||
<Button onClick={onClose} type="primary">
|
<Button onClick={addQiniuoConfig} type="primary">
|
||||||
提交
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
}>
|
}>
|
||||||
<Form layout="vertical">
|
<Form layout="vertical" form={form}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -155,6 +280,14 @@ const QiniuSettings: React.FC = () => {
|
|||||||
<Input placeholder="请输入存储桶!" />
|
<Input placeholder="请输入存储桶!" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name="endpoint"
|
||||||
|
label="服务地址"
|
||||||
|
rules={[{ required: true, message: "请输入服务地址!" }]}>
|
||||||
|
<Input placeholder="请输入服务地址!" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
@@ -189,6 +322,44 @@ const QiniuSettings: React.FC = () => {
|
|||||||
cardBordered={true}
|
cardBordered={true}
|
||||||
editable={{
|
editable={{
|
||||||
type: "multiple",
|
type: "multiple",
|
||||||
|
onSave: async (__: any, originRow: any, _: any) => {
|
||||||
|
const updateForm: any = {
|
||||||
|
id: originRow.id,
|
||||||
|
endpoint: originRow.endpoint,
|
||||||
|
accessKey: originRow.accessKey,
|
||||||
|
secretKey: originRow.secretKey,
|
||||||
|
};
|
||||||
|
updateQiniuConfig(updateForm).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "修改成功!",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDelete: async (row: any) => {
|
||||||
|
deleteConfig(row).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
columnsState={{
|
columnsState={{
|
||||||
persistenceKey: "pro-table-singe-demos",
|
persistenceKey: "pro-table-singe-demos",
|
||||||
@@ -225,6 +396,43 @@ const QiniuSettings: React.FC = () => {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<AddQiniuOssConfigDrawer />
|
<AddQiniuOssConfigDrawer />
|
||||||
|
<Modal
|
||||||
|
title={<p>配置详情</p>}
|
||||||
|
loading={loading}
|
||||||
|
afterClose={() => {
|
||||||
|
setConfigDetail({});
|
||||||
|
}}
|
||||||
|
footer={false}
|
||||||
|
open={openModal}
|
||||||
|
onCancel={() => setOpenModal(false)}>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>ID:</h4> <span style={{ marginLeft: 10 }}>{configDetail.id}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>endpoint: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.endpoint}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>accessKey: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.accessKey} </span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>secretKey: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.secretKey}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>status: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.status}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>createdTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.createdTime}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>updateTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.updateTime}</span>
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -2,25 +2,45 @@
|
|||||||
import { PlusOutlined } from "@ant-design/icons";
|
import { PlusOutlined } from "@ant-design/icons";
|
||||||
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
import type { ActionType, ProColumns } from "@ant-design/pro-components";
|
||||||
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
import { ProTable, TableDropdown } from "@ant-design/pro-components";
|
||||||
import { Button, Col, Drawer, Form, Input, Row, Space } from "antd";
|
import { Button, Col, Drawer, Flex, Form, Input, message, Modal, Row, Space } from "antd";
|
||||||
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
import React, { ReactNode, useEffect, useRef, useState } from "react";
|
||||||
import { getAllTencentOSsConfig } from "@/api/oss/tencent";
|
import {
|
||||||
|
addTencentOSSConfig,
|
||||||
|
deleteTencentConfig,
|
||||||
|
getAllTencentOSsConfig,
|
||||||
|
getTencentConfigDetailById,
|
||||||
|
initTencentOSS,
|
||||||
|
setTencentShutdown,
|
||||||
|
updateTencentConfig,
|
||||||
|
} from "@/api/oss/tencent";
|
||||||
|
|
||||||
type TencentOssConfigItem = {
|
type TencentOssConfigItem = {
|
||||||
id: number;
|
id: number;
|
||||||
userId: number;
|
userId: number;
|
||||||
|
endpoint: number;
|
||||||
secretId: string;
|
secretId: string;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
|
appId: string;
|
||||||
|
region: string;
|
||||||
createdTime: string;
|
createdTime: string;
|
||||||
updateTime: string;
|
updateTime: string;
|
||||||
status: string;
|
status: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns: ProColumns<TencentOssConfigItem>[] = [
|
const TencentSettings: React.FC = () => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const actionRef = useRef<ActionType>();
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [configs, setConfigs] = useState<TencentOssConfigItem[]>([]);
|
||||||
|
const [openModal, setOpenModal] = useState(false);
|
||||||
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [configDetail, setConfigDetail] = useState<object>({});
|
||||||
|
const columns: ProColumns<TencentOssConfigItem>[] = [
|
||||||
{
|
{
|
||||||
dataIndex: "index",
|
dataIndex: "index",
|
||||||
valueType: "indexBorder",
|
valueType: "indexBorder",
|
||||||
width: 48,
|
width: 48,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "ID",
|
title: "ID",
|
||||||
@@ -28,6 +48,15 @@ const columns: ProColumns<TencentOssConfigItem>[] = [
|
|||||||
copyable: true,
|
copyable: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: "Id",
|
tooltip: "Id",
|
||||||
|
editable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disable: true,
|
||||||
|
title: "服务地址",
|
||||||
|
dataIndex: "endpoint",
|
||||||
|
copyable: true,
|
||||||
|
tooltip: "endpoint",
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
disable: true,
|
disable: true,
|
||||||
@@ -47,9 +76,19 @@ const columns: ProColumns<TencentOssConfigItem>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
disable: true,
|
disable: true,
|
||||||
title: "状态",
|
title: "appId",
|
||||||
dataIndex: "status",
|
dataIndex: "appId",
|
||||||
search: true,
|
tooltip: "appId",
|
||||||
|
copyable: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disable: true,
|
||||||
|
title: "地域",
|
||||||
|
dataIndex: "region",
|
||||||
|
tooltip: "region",
|
||||||
|
copyable: true,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
@@ -57,12 +96,25 @@ const columns: ProColumns<TencentOssConfigItem>[] = [
|
|||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "更新时间",
|
title: "更新时间",
|
||||||
dataIndex: "updateTime",
|
dataIndex: "updateTime",
|
||||||
valueType: "dateTime",
|
valueType: "dateTime",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
editable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
disable: true,
|
||||||
|
title: "状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
search: true,
|
||||||
|
valueEnum: {
|
||||||
|
true: { text: "开启", status: "Success" },
|
||||||
|
false: { text: "关闭", status: "Error" },
|
||||||
|
},
|
||||||
|
editable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
@@ -78,25 +130,97 @@ const columns: ProColumns<TencentOssConfigItem>[] = [
|
|||||||
}}>
|
}}>
|
||||||
编辑
|
编辑
|
||||||
</a>,
|
</a>,
|
||||||
<a target="_blank" rel="noopener noreferrer" key="view">
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
key="view"
|
||||||
|
onClick={() => {
|
||||||
|
getConfigDetail(record.id).then(() => {
|
||||||
|
setOpenModal(true);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}}>
|
||||||
查看
|
查看
|
||||||
</a>,
|
</a>,
|
||||||
<TableDropdown
|
<TableDropdown
|
||||||
key="actionGroup"
|
key="actionGroup"
|
||||||
onSelect={() => action?.reload()}
|
onSelect={(key: string) => {
|
||||||
|
if (key === "open") {
|
||||||
|
init(record.id).then();
|
||||||
|
} else if (key === "close") {
|
||||||
|
shutdown(record.id).then();
|
||||||
|
}
|
||||||
|
}}
|
||||||
menus={[
|
menus={[
|
||||||
{ key: "copy", name: "复制" },
|
{ key: "open", name: "开启" },
|
||||||
{ key: "delete", name: "删除" },
|
{ key: "close", name: "关闭" },
|
||||||
]}
|
]}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
async function init(id: any) {
|
||||||
|
initTencentOSS("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "开启成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function getConfigDetail(id: any) {
|
||||||
|
getTencentConfigDetailById(id).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setConfigDetail(res.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function shutdown(id: any) {
|
||||||
|
setTencentShutdown("1", id).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteConfig(id: any) {
|
||||||
|
const form: any = {
|
||||||
|
id: id,
|
||||||
|
isDeleted: 1,
|
||||||
|
};
|
||||||
|
deleteTencentConfig(form).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const TencentSettings: React.FC = () => {
|
|
||||||
const actionRef = useRef<ActionType>();
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [configs, setConfigs] = useState<TencentOssConfigItem[]>([]);
|
|
||||||
const showDrawer = () => {
|
const showDrawer = () => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
@@ -104,14 +228,39 @@ const TencentSettings: React.FC = () => {
|
|||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getAllConfigs() {
|
async function getAllConfigs() {
|
||||||
getAllTencentOSsConfig(5).then((res: any) => {
|
getAllTencentOSsConfig("1").then((res: any) => {
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setConfigs(res.data);
|
setConfigs(res.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addTencentConfig() {
|
||||||
|
const fieldsValue = form.getFieldsValue();
|
||||||
|
const TencentOssConfig = {
|
||||||
|
userId: "1",
|
||||||
|
...fieldsValue,
|
||||||
|
};
|
||||||
|
addTencentOSSConfig(TencentOssConfig).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "新增成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then(() => {
|
||||||
|
onClose();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllConfigs().then();
|
getAllConfigs().then();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -131,12 +280,12 @@ const TencentSettings: React.FC = () => {
|
|||||||
extra={
|
extra={
|
||||||
<Space>
|
<Space>
|
||||||
<Button onClick={onClose}>取消</Button>
|
<Button onClick={onClose}>取消</Button>
|
||||||
<Button onClick={onClose} type="primary">
|
<Button onClick={addTencentConfig} type="primary">
|
||||||
提交
|
提交
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
}>
|
}>
|
||||||
<Form layout="vertical">
|
<Form layout="vertical" form={form}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -155,6 +304,24 @@ const TencentSettings: React.FC = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name="appId"
|
||||||
|
label="appId"
|
||||||
|
rules={[{ required: true, message: "请输入appID!" }]}>
|
||||||
|
<Input placeholder="请输入appID!" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name="region"
|
||||||
|
label="地区"
|
||||||
|
rules={[{ required: true, message: "请输入地区!" }]}>
|
||||||
|
<Input placeholder="请输入地区!" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</Form>
|
</Form>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</>
|
</>
|
||||||
@@ -170,6 +337,46 @@ const TencentSettings: React.FC = () => {
|
|||||||
cardBordered={true}
|
cardBordered={true}
|
||||||
editable={{
|
editable={{
|
||||||
type: "multiple",
|
type: "multiple",
|
||||||
|
onSave: async (__: any, originRow: any, _: any) => {
|
||||||
|
const updateForm: any = {
|
||||||
|
id: originRow.id,
|
||||||
|
endpoint: originRow.endpoint,
|
||||||
|
secretId: originRow.secretId,
|
||||||
|
secretKey: originRow.secretKey,
|
||||||
|
appId: originRow.appId,
|
||||||
|
region: originRow.region,
|
||||||
|
};
|
||||||
|
updateTencentConfig(updateForm).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "修改成功!",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDelete: async (row: any) => {
|
||||||
|
deleteConfig(row).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
content: "删除成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
getAllConfigs().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
columnsState={{
|
columnsState={{
|
||||||
persistenceKey: "pro-table-singe-demos",
|
persistenceKey: "pro-table-singe-demos",
|
||||||
@@ -206,6 +413,51 @@ const TencentSettings: React.FC = () => {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<AddTencentOssConfigDrawer />
|
<AddTencentOssConfigDrawer />
|
||||||
|
<Modal
|
||||||
|
title={<p>配置详情</p>}
|
||||||
|
loading={loading}
|
||||||
|
footer={false}
|
||||||
|
open={openModal}
|
||||||
|
afterClose={() => {
|
||||||
|
setConfigDetail({});
|
||||||
|
}}
|
||||||
|
onCancel={() => setOpenModal(false)}>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>ID:</h4> <span style={{ marginLeft: 10 }}>{configDetail.id}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>endpoint: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.endpoint}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>secretId: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.secretId} </span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>secretKey: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.secretKey}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>appId: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.appId}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>region: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.region}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>status: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.status}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>createdTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.createdTime}</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex vertical={false} align={"center"}>
|
||||||
|
<h4>updateTime: </h4>{" "}
|
||||||
|
<span style={{ marginLeft: 10 }}>{configDetail.updateTime}</span>
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -27,10 +27,13 @@ export default () => {
|
|||||||
onSelect={(value: any) => {
|
onSelect={(value: any) => {
|
||||||
navigate("/main/setting/" + value);
|
navigate("/main/setting/" + value);
|
||||||
}}
|
}}
|
||||||
placeholder={"请选择存储商"}>
|
fieldNames={{
|
||||||
{selectOptions.map((storage: any, index: any) => {
|
label: "name",
|
||||||
|
value: "value",
|
||||||
|
}}
|
||||||
|
labelRender={(label: any) => {
|
||||||
return (
|
return (
|
||||||
<Select.Option value={storage.value} key={index}>
|
<>
|
||||||
<Card
|
<Card
|
||||||
bordered={false}
|
bordered={false}
|
||||||
style={{
|
style={{
|
||||||
@@ -40,19 +43,44 @@ export default () => {
|
|||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
}}
|
}}
|
||||||
size={"small"}>
|
size={"small"}>
|
||||||
<Avatar src={StorageIcon[storage.value]} size={"small"} />{" "}
|
<Avatar src={StorageIcon[label.value]} size={"small"} />
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
marginLeft: "10px",
|
marginLeft: "10px",
|
||||||
fontWeight: "bolder",
|
fontWeight: "bolder",
|
||||||
}}>
|
}}>
|
||||||
{storage.name}
|
{label.label}
|
||||||
</span>
|
</span>
|
||||||
</Card>
|
</Card>
|
||||||
</Select.Option>
|
</>
|
||||||
);
|
);
|
||||||
})}
|
}}
|
||||||
</Select>
|
options={selectOptions}
|
||||||
|
optionRender={(item: any) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card
|
||||||
|
bordered={false}
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
}}
|
||||||
|
size={"small"}>
|
||||||
|
<Avatar src={StorageIcon[item.value]} size={"small"} />
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: "10px",
|
||||||
|
fontWeight: "bolder",
|
||||||
|
}}>
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
placeholder={"请选择存储商"}></Select>
|
||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard style={{ marginTop: 20, height: "100%" }} bordered boxShadow>
|
<ProCard style={{ marginTop: 20, height: "100%" }} bordered boxShadow>
|
||||||
|
@@ -6,18 +6,53 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import "aieditor/dist/style.css";
|
import "aieditor/dist/style.css";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import { Button, Card, Flex, Form, FormListFieldData, FormProps, Input, Select } from "antd";
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Flex,
|
||||||
|
Form,
|
||||||
|
FormListFieldData,
|
||||||
|
FormProps,
|
||||||
|
Input,
|
||||||
|
message,
|
||||||
|
Select,
|
||||||
|
} from "antd";
|
||||||
import { CloseOutlined, LeftOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
|
import { CloseOutlined, LeftOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
|
||||||
import selectOptions from "@/components/Main/Settings/settings.ts";
|
import selectOptions from "@/components/Main/Settings/settings.ts";
|
||||||
|
import { addShareDetail } from "@/api/share";
|
||||||
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
const ShareAdd: React.FunctionComponent = () => {
|
const ShareAdd: React.FunctionComponent = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const divRef = useRef(null);
|
const divRef = useRef(null);
|
||||||
const fromRef: any = useRef();
|
const [form] = Form.useForm();
|
||||||
const [isDisabled, setIsDisabled] = React.useState(false);
|
const [isDisabled, setIsDisabled] = React.useState(false);
|
||||||
|
const store = useStore("share");
|
||||||
|
|
||||||
const onFinish: FormProps["onFinish"] = (values) => {
|
const onFinish: FormProps["onFinish"] = (values) => {
|
||||||
console.log("Success:", values);
|
const formData: any = {
|
||||||
|
circleId: store.getCircleId(),
|
||||||
|
userId: 32,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
addShareDetail(formData).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "新增成功",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "新增失败",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (divRef.current) {
|
if (divRef.current) {
|
||||||
@@ -39,9 +74,7 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
onChange: async (value: any) => {
|
onChange: async (value: any) => {
|
||||||
fromRef.current.setFieldsValue({
|
form.setFieldValue("content" as any, value.getHtml());
|
||||||
content: value.getHtml(),
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
} as any);
|
} as any);
|
||||||
return () => {
|
return () => {
|
||||||
@@ -58,7 +91,7 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<LeftOutlined />}
|
icon={<LeftOutlined />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate("/main/share/list/1");
|
navigate("/main/share/list/" + store.getCircleId());
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -71,7 +104,7 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<div className={styles.share_add_content}>
|
<div className={styles.share_add_content}>
|
||||||
<Form onFinish={onFinish} autoComplete="off" ref={fromRef}>
|
<Form onFinish={onFinish} autoComplete="off" form={form}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
@@ -111,6 +144,7 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
<h4>介绍</h4>
|
<h4>介绍</h4>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
rules={[{ required: true, message: "请输入介绍" }]}
|
||||||
name="content"
|
name="content"
|
||||||
id={"content"}>
|
id={"content"}>
|
||||||
<div
|
<div
|
||||||
@@ -126,7 +160,7 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
if (!tags) {
|
if (!tags) {
|
||||||
return Promise.reject(new Error("请至少填写一个标签"));
|
return Promise.reject(new Error("请至少填写一个标签"));
|
||||||
}
|
}
|
||||||
if (tags.length >= 3) {
|
if (tags.length > 3) {
|
||||||
setIsDisabled(true);
|
setIsDisabled(true);
|
||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
new Error("最多只能添加三个标签"),
|
new Error("最多只能添加三个标签"),
|
||||||
@@ -148,7 +182,7 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
id={"tags"}>
|
id={"tags"}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
validateTrigger={["onChange", "onBlur"]}
|
validateTrigger={["onChange", "onBlur"]}
|
||||||
name={[field.name, "tag"]}
|
name={[field.name, "tagName"] as any}
|
||||||
noStyle>
|
noStyle>
|
||||||
<Input
|
<Input
|
||||||
placeholder="请输入标签"
|
placeholder="请输入标签"
|
||||||
@@ -209,7 +243,9 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}>
|
}>
|
||||||
<Form.Item name={[field.name, "type"]} label="分享类型">
|
<Form.Item
|
||||||
|
name={[field.name, "type"] as any}
|
||||||
|
label="分享类型">
|
||||||
<Select
|
<Select
|
||||||
size="middle"
|
size="middle"
|
||||||
style={{ width: "20%" }}
|
style={{ width: "20%" }}
|
||||||
@@ -231,15 +267,17 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, "description"]}
|
name={[field.name, "description"] as any}
|
||||||
label="资源描述">
|
label="资源描述">
|
||||||
<Input name={"description"} />
|
<Input name={"description"} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name={[field.name, "url"]} label="资源链接">
|
<Form.Item
|
||||||
|
name={[field.name, "url"] as any}
|
||||||
|
label="资源链接">
|
||||||
<Input name={"url"} />
|
<Input name={"url"} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, "password"]}
|
name={[field.name, "password"] as any}
|
||||||
label={"提取密码"}>
|
label={"提取密码"}>
|
||||||
<Input name={"password"} />
|
<Input name={"password"} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -269,4 +307,4 @@ const ShareAdd: React.FunctionComponent = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ShareAdd;
|
export default observer(ShareAdd);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Avatar, Button, Card, Divider, Flex, Tag, Tooltip } from "antd";
|
import { Avatar, Button, Card, Divider, Flex, Skeleton, Tag, Tooltip } from "antd";
|
||||||
import {
|
import {
|
||||||
CommentOutlined,
|
CommentOutlined,
|
||||||
ExportOutlined,
|
ExportOutlined,
|
||||||
@@ -11,33 +11,54 @@ import {
|
|||||||
TagsOutlined,
|
TagsOutlined,
|
||||||
WarningOutlined,
|
WarningOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import "aieditor/dist/style.css";
|
import "aieditor/dist/style.css";
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import logo from "@/assets/icons/baiduyun.svg";
|
|
||||||
import { Typography } from "antd";
|
import { Typography } from "antd";
|
||||||
import Comment from "@/components/Main/Share/components/ShareDetail/components/Comment";
|
import Comment from "@/components/Main/Share/components/ShareDetail/components/Comment";
|
||||||
import getRandomColor from "@/constant/random-color.ts";
|
import getRandomColor from "@/constant/random-color.ts";
|
||||||
const { Paragraph } = Typography;
|
const { Paragraph } = Typography;
|
||||||
import like from "@/assets/icons/like.svg";
|
import like from "@/assets/icons/like.svg";
|
||||||
import favorite from "@/assets/icons/favorite.svg";
|
import favorite from "@/assets/icons/favorite.svg";
|
||||||
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
|
import { getShareDetail } from "@/api/share";
|
||||||
|
import StorageIcon from "@/constant/stroage-icon.ts";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
const ShareDetail: React.FunctionComponent = () => {
|
const ShareDetail: React.FunctionComponent = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const store = useStore("share");
|
||||||
|
const params = useParams();
|
||||||
|
const [detail, setDetail] = useState<any>({});
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
async function getDetail() {
|
||||||
|
getShareDetail(params.id).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setDetail(res.data);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getDetail().then();
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<Skeleton loading={loading} active={true} paragraph={{ rows: 16 }}>
|
||||||
<ProCard bordered={true}>
|
<ProCard bordered={true}>
|
||||||
<Flex vertical={false} align={"center"} justify={"space-between"}>
|
<Flex vertical={false} align={"center"} justify={"space-between"}>
|
||||||
<Button
|
<Button
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<LeftOutlined />}
|
icon={<LeftOutlined />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate("/main/share/list/1");
|
const circleId = store.getCircleId();
|
||||||
|
navigate("/main/share/list/" + circleId);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<h3>办公软件分享</h3>
|
<h3>{detail.title as string}</h3>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
@@ -45,14 +66,14 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
justify={"space-between"}
|
justify={"space-between"}
|
||||||
style={{ width: "20%" }}>
|
style={{ width: "20%" }}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<Avatar src={logo as any} size={"small"} />
|
<Avatar src={detail.avatar as any} size={"small"} />
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}>
|
}}>
|
||||||
landaiqing
|
{detail.nickname}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -62,7 +83,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
1024
|
{detail.likesCount}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -72,7 +93,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
1024
|
{detail.commentCount}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -82,7 +103,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
1024
|
{detail.views}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -90,7 +111,9 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
</ProCard>
|
</ProCard>
|
||||||
<div className={styles.share_detail_container}>
|
<div className={styles.share_detail_container}>
|
||||||
<ProCard bordered={true}>
|
<ProCard bordered={true}>
|
||||||
<div style={{ height: 500 }}>资源描述</div>
|
<div
|
||||||
|
style={{ height: 500 }}
|
||||||
|
dangerouslySetInnerHTML={{ __html: detail.content }}></div>
|
||||||
|
|
||||||
<Card style={{ borderRadius: "10px", borderColor: "#1677FF" }}>
|
<Card style={{ borderRadius: "10px", borderColor: "#1677FF" }}>
|
||||||
<Flex vertical={false} align={"center"} justify={"space-between"}>
|
<Flex vertical={false} align={"center"} justify={"space-between"}>
|
||||||
@@ -111,7 +134,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
align={"center"}
|
align={"center"}
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
justify={"space-between"}>
|
justify={"space-between"}>
|
||||||
<span style={{ fontSize: 16 }}>Windows DefenderRemover</span>
|
<span style={{ fontSize: 16 }}>{detail.title}</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
@@ -131,15 +154,28 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
justify={"space-between"}>
|
justify={"flex-start"}>
|
||||||
<Card hoverable={true} style={{ width: 280, height: 140 }}>
|
{detail.urls &&
|
||||||
|
Array.from(detail.urls).map((url: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<div key={index}>
|
||||||
|
<Card
|
||||||
|
hoverable={true}
|
||||||
|
style={{
|
||||||
|
width: 280,
|
||||||
|
height: 140,
|
||||||
|
marginLeft: 10,
|
||||||
|
}}>
|
||||||
<Flex vertical={true}>
|
<Flex vertical={true}>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
justify={"space-between"}
|
justify={"space-between"}
|
||||||
align={"center"}>
|
align={"center"}>
|
||||||
<div>
|
<div>
|
||||||
<Avatar src={logo as any}></Avatar>
|
<Avatar
|
||||||
|
src={
|
||||||
|
StorageIcon[url.type] as any
|
||||||
|
}></Avatar>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
@@ -149,15 +185,24 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
百度云
|
百度云
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ExportOutlined className={styles.link_btn} />
|
<ExportOutlined
|
||||||
|
className={styles.link_btn}
|
||||||
|
onClick={() => {
|
||||||
|
window.open(url.url, "_blank");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Divider></Divider>
|
<Divider></Divider>
|
||||||
<Flex vertical={false}>
|
<Flex vertical={false}>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="DefenderRemove111111111"
|
title={url.description}
|
||||||
placement={"bottom"}>
|
placement={"bottom"}>
|
||||||
<span style={{ width: 150, overflowX: "hidden" }}>
|
<span
|
||||||
DefenderRemove111111111
|
style={{
|
||||||
|
width: 150,
|
||||||
|
overflowX: "hidden",
|
||||||
|
}}>
|
||||||
|
{url.description}
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<span
|
<span
|
||||||
@@ -167,12 +212,19 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
}}>
|
}}>
|
||||||
<span style={{ color: "#1677FF" }}>密码:</span>{" "}
|
<span style={{ color: "#1677FF" }}>
|
||||||
<Paragraph copyable>12345</Paragraph>
|
密码:
|
||||||
|
</span>{" "}
|
||||||
|
<Paragraph copyable>
|
||||||
|
{url.password}
|
||||||
|
</Paragraph>
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} style={{ marginTop: 10 }}>
|
<Flex vertical={false} style={{ marginTop: 10 }}>
|
||||||
<span style={{ color: "grey" }}>
|
<span style={{ color: "grey" }}>
|
||||||
@@ -185,19 +237,27 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
<Flex vertical={false} align={"center"} style={{ marginTop: 20 }}>
|
<Flex vertical={false} align={"center"} style={{ marginTop: 20 }}>
|
||||||
<TagsOutlined style={{ fontSize: 30, color: "#1677FF" }} />
|
<TagsOutlined style={{ fontSize: 30, color: "#1677FF" }} />
|
||||||
<Flex vertical={false} align={"center"} style={{ marginLeft: 10 }}>
|
<Flex vertical={false} align={"center"} style={{ marginLeft: 10 }}>
|
||||||
|
{detail.tags &&
|
||||||
|
Array.from(detail.tags).map((tag: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<div key={index}>
|
||||||
<Tag bordered={false} color={getRandomColor()}>
|
<Tag bordered={false} color={getRandomColor()}>
|
||||||
测试标签
|
{tag.tagName}
|
||||||
</Tag>
|
|
||||||
<Tag bordered={false} color={getRandomColor()}>
|
|
||||||
测试标签
|
|
||||||
</Tag>
|
|
||||||
<Tag bordered={false} color={getRandomColor()}>
|
|
||||||
测试标签
|
|
||||||
</Tag>
|
</Tag>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"} justify={"center"} style={{height: 50}}>
|
<Flex
|
||||||
<Avatar className={styles.like_icon} src={like as any} size={"large"}></Avatar>
|
vertical={false}
|
||||||
|
align={"center"}
|
||||||
|
justify={"center"}
|
||||||
|
style={{ height: 50 }}>
|
||||||
|
<Avatar
|
||||||
|
className={styles.like_icon}
|
||||||
|
src={like as any}
|
||||||
|
size={"large"}></Avatar>
|
||||||
<Avatar
|
<Avatar
|
||||||
className={styles.favtorie_icon}
|
className={styles.favtorie_icon}
|
||||||
src={favorite as any}
|
src={favorite as any}
|
||||||
@@ -206,8 +266,8 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
<Comment />
|
<Comment />
|
||||||
</div>
|
</Skeleton>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ShareDetail;
|
export default observer(ShareDetail);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import { Avatar, Button, Flex, Input, Segmented, Tag } from "antd";
|
import { Avatar, Button, Empty, Flex, Input, message, Segmented, Skeleton, Tag } from "antd";
|
||||||
import logo from "@/assets/icons/gitee.svg";
|
import logo from "@/assets/icons/gitee.svg";
|
||||||
import {
|
import {
|
||||||
BarsOutlined,
|
BarsOutlined,
|
||||||
@@ -13,15 +13,88 @@ import {
|
|||||||
SendOutlined,
|
SendOutlined,
|
||||||
SmileOutlined,
|
SmileOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { addComment, addReply, listComment, listReply } from "@/api/share";
|
||||||
const Comment = () => {
|
const Comment = () => {
|
||||||
const [isReply, setIsReply] = useState<boolean>(false);
|
const params = useParams();
|
||||||
const [isReplyComment, setIsReplyComment] = useState<boolean>(false);
|
const [isReply, setIsReply] = useState<any>(null);
|
||||||
|
const [isReplyReply, setIsReplyReply] = useState<any>(null);
|
||||||
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
const [isReplyComment, setIsReplyComment] = useState<any>(null);
|
||||||
|
const [comment, setComment] = useState<any[]>([]);
|
||||||
|
const [reply, setReply] = useState<any[]>([]);
|
||||||
|
const [commentData, setCommentData] = useState<any>("");
|
||||||
|
const [replyData, setReplyData] = useState<any>("");
|
||||||
|
const [replyReplyData, setReplyReplyData] = useState<any>("");
|
||||||
|
async function listComments() {
|
||||||
|
listComment(params.id).then((res: any) => {
|
||||||
|
console.log(res);
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setComment(res.data);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addComments(data: any) {
|
||||||
|
addComment(data).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
message.open({
|
||||||
|
content: "评论成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
listComments().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: "评论失败",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function replyComment(commentId: any) {
|
||||||
|
listReply(commentId).then((res: any) => {
|
||||||
|
console.log(res);
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setReply(res.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function addReplies(data: any) {
|
||||||
|
addReply(data).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
message.open({
|
||||||
|
content: "回复成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
listComments().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
content: "回复失败",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const handleExpandClick = (index: any) => {
|
||||||
|
setIsReply(isReply === index ? null : index);
|
||||||
|
};
|
||||||
|
const handleExpandReplyReplyClick = (index: any) => {
|
||||||
|
setIsReplyReply(isReplyReply === index ? null : index);
|
||||||
|
};
|
||||||
|
const handleExpandReplyCommentClick = (index: any) => {
|
||||||
|
setIsReplyComment(isReplyComment === index ? null : index);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
listComments().then();
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<ProCard title={"评论 5"}>
|
<ProCard title={"评论"}>
|
||||||
|
<Skeleton active={true} loading={loading} paragraph={{ rows: 2 }}>
|
||||||
<Flex vertical={false}>
|
<Flex vertical={false}>
|
||||||
<Flex vertical={true} justify={"flex-start"}>
|
<Flex vertical={true} justify={"flex-start"}>
|
||||||
<Avatar src={logo as any} size={"large"} />
|
<Avatar src={logo as any} size={"large"} />
|
||||||
@@ -31,6 +104,9 @@ const Comment = () => {
|
|||||||
style={{ marginLeft: 10 }}
|
style={{ marginLeft: 10 }}
|
||||||
rows={5}
|
rows={5}
|
||||||
maxLength={500}
|
maxLength={500}
|
||||||
|
onChange={(e: any) => {
|
||||||
|
setCommentData(e.target.value);
|
||||||
|
}}
|
||||||
showCount
|
showCount
|
||||||
placeholder={"平等表达,友善交流"}></Input.TextArea>
|
placeholder={"平等表达,友善交流"}></Input.TextArea>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -43,31 +119,75 @@ const Comment = () => {
|
|||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"} justify={"flex-end"}>
|
<Flex vertical={false} align={"center"} justify={"flex-end"}>
|
||||||
<Button icon={<SendOutlined />} type={"primary"}>
|
<Button
|
||||||
|
icon={<SendOutlined />}
|
||||||
|
type={"primary"}
|
||||||
|
onClick={() => {
|
||||||
|
const data: any = {
|
||||||
|
userId: 17,
|
||||||
|
detailId: params.id,
|
||||||
|
content: commentData,
|
||||||
|
};
|
||||||
|
addComments(data).then(() => {
|
||||||
|
listComments().then();
|
||||||
|
});
|
||||||
|
}}>
|
||||||
发表
|
发表
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex vertical={true}>
|
<Flex vertical={true}>
|
||||||
<Segmented
|
<Segmented
|
||||||
block={false}
|
block={false}
|
||||||
style={{ width: 145 }}
|
style={{ width: 145 }}
|
||||||
size={"middle"}
|
size={"middle"}
|
||||||
options={[
|
options={[
|
||||||
{ label: "最新", value: "List", icon: <BarsOutlined /> },
|
{
|
||||||
{ label: "最热", value: "Kanban", icon: <FireOutlined /> },
|
label: "最新",
|
||||||
|
value: "List",
|
||||||
|
icon: <BarsOutlined />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "最热",
|
||||||
|
value: "Kanban",
|
||||||
|
icon: <FireOutlined />,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<Flex vertical={true} style={{ marginTop: 20, width: "100%" }}>
|
{comment.length === 0 ? (
|
||||||
|
<Empty description={"暂无评论!"} />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{comment &&
|
||||||
|
Array.from(comment).map((item: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
key={index}
|
||||||
|
vertical={true}
|
||||||
|
style={{ marginTop: 20, width: "100%" }}>
|
||||||
<Flex vertical={false}>
|
<Flex vertical={false}>
|
||||||
<Flex vertical={true} justify={"flex-start"}>
|
<Flex
|
||||||
<Avatar src={logo as any} size={"large"}></Avatar>
|
vertical={true}
|
||||||
|
justify={"flex-start"}>
|
||||||
|
<Avatar
|
||||||
|
src={item.avatar as any}
|
||||||
|
size={"large"}></Avatar>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={true} style={{ marginLeft: 15, width: "100%" }}>
|
<Flex
|
||||||
|
vertical={true}
|
||||||
|
style={{
|
||||||
|
marginLeft: 15,
|
||||||
|
width: "100%",
|
||||||
|
}}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<span style={{ fontSize: 16, fontWeight: 500 }}>
|
<span
|
||||||
landaiqing
|
style={{
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 500,
|
||||||
|
}}>
|
||||||
|
{item.nick}
|
||||||
</span>
|
</span>
|
||||||
<Tag
|
<Tag
|
||||||
bordered={false}
|
bordered={false}
|
||||||
@@ -82,193 +202,101 @@ const Comment = () => {
|
|||||||
boxShadow={false}
|
boxShadow={false}
|
||||||
extra={<></>}
|
extra={<></>}
|
||||||
style={{ width: "100%" }}>
|
style={{ width: "100%" }}>
|
||||||
<span>
|
<span>{item.content}</span>
|
||||||
i回复OIDHJHDCEHIceh车hi是事实上事实是事实hi是是是是是是是是是是
|
|
||||||
</span>
|
|
||||||
<Flex
|
|
||||||
vertical={false}
|
|
||||||
style={{ marginTop: 10, width: "100%" }}>
|
|
||||||
<span style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
1 小时前
|
|
||||||
</span>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<LikeOutlined className={styles.like_icon} />
|
|
||||||
<span style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
10
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<CommentOutlined className={styles.comment_icon} />
|
|
||||||
<span style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
10
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<Button
|
|
||||||
type="text"
|
|
||||||
size={"small"}
|
|
||||||
onClick={() => setIsReply(true)}
|
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
回复
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</ProCard>
|
|
||||||
{isReply && (
|
|
||||||
<>
|
|
||||||
<Flex vertical={true}>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<span style={{ fontSize: 13 }}> 回复: </span>
|
|
||||||
<span style={{ fontSize: 13 }}>
|
|
||||||
{" "}
|
|
||||||
landaiqing
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
icon={<CloseOutlined />}
|
|
||||||
style={{ fontSize: 13, marginLeft: 5 }}
|
|
||||||
type={"dashed"}
|
|
||||||
onClick={() => setIsReply(false)}
|
|
||||||
size={"small"}>
|
|
||||||
{" "}
|
|
||||||
取消回复
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} style={{ marginTop: 5 }}>
|
|
||||||
<Flex vertical={true} justify={"flex-start"}>
|
|
||||||
<Avatar
|
|
||||||
src={logo as any}
|
|
||||||
size={"default"}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={true} style={{ width: "100%" }}>
|
|
||||||
<Input.TextArea
|
|
||||||
style={{
|
|
||||||
marginLeft: 10,
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
rows={3}
|
|
||||||
maxLength={500}
|
|
||||||
showCount
|
|
||||||
placeholder={
|
|
||||||
"平等表达,友善交流"
|
|
||||||
}></Input.TextArea>
|
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
style={{
|
style={{
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
marginLeft: 10,
|
width: "100%",
|
||||||
}}>
|
}}>
|
||||||
<SmileOutlined
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: 20,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
}}
|
}}>
|
||||||
/>
|
{item.createdTime}
|
||||||
<PictureOutlined
|
|
||||||
style={{
|
|
||||||
marginLeft: 20,
|
|
||||||
fontSize: 20,
|
|
||||||
color: "grey",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Flex
|
|
||||||
vertical={false}
|
|
||||||
align={"center"}
|
|
||||||
justify={"flex-end"}>
|
|
||||||
<Button
|
|
||||||
icon={<SendOutlined />}
|
|
||||||
type={"primary"}>
|
|
||||||
发表
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<Flex vertical={false}>
|
|
||||||
<Flex vertical={true} justify={"flex-start"}>
|
|
||||||
<Avatar src={logo as any} size={"default"}></Avatar>
|
|
||||||
</Flex>
|
|
||||||
<Flex
|
|
||||||
vertical={true}
|
|
||||||
style={{ marginLeft: 15, width: "100%" }}>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<span style={{ fontSize: 14, fontWeight: 500 }}>
|
|
||||||
sjm 回复 landaiqing
|
|
||||||
</span>
|
|
||||||
{/*<Tag*/}
|
|
||||||
{/* bordered={false}*/}
|
|
||||||
{/* icon={<CrownOutlined />}*/}
|
|
||||||
{/* color={"cyan"}*/}
|
|
||||||
{/* style={{ marginLeft: 5 }}>*/}
|
|
||||||
{/* 作者*/}
|
|
||||||
{/*</Tag>*/}
|
|
||||||
</Flex>
|
|
||||||
<ProCard
|
|
||||||
bordered={true}
|
|
||||||
boxShadow={false}
|
|
||||||
extra={<></>}
|
|
||||||
style={{ width: "100%" }}>
|
|
||||||
<span>
|
|
||||||
i回复OIDHJHDCEHIceh车hi是事实上事实是事实hi是是是是是是是是是是
|
|
||||||
</span>
|
</span>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
style={{ marginTop: 10, width: "100%" }}>
|
align={"center"}>
|
||||||
<span style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
1 小时前
|
|
||||||
</span>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<LikeOutlined
|
<LikeOutlined
|
||||||
|
className={
|
||||||
|
styles.like_icon
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
marginLeft: 10,
|
}}>
|
||||||
}}
|
{item.likes}
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
10
|
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}>
|
||||||
<CommentOutlined
|
<CommentOutlined
|
||||||
|
onClick={() => {
|
||||||
|
setReply([]);
|
||||||
|
if (item.id) {
|
||||||
|
replyComment(
|
||||||
|
item.id,
|
||||||
|
).then(() => {
|
||||||
|
handleExpandReplyCommentClick(
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className={
|
||||||
|
styles.comment_icon
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
marginLeft: 10,
|
}}>
|
||||||
}}
|
{item.replyCount}
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
10
|
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}>
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
size={"small"}
|
size={"small"}
|
||||||
onClick={() => setIsReplyComment(true)}
|
onClick={() => {
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
handleExpandClick(
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
回复
|
回复
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
{isReplyComment && (
|
{isReply === index && (
|
||||||
<>
|
|
||||||
<Flex vertical={true}>
|
<Flex vertical={true}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex
|
||||||
<span style={{ fontSize: 13 }}>
|
vertical={false}
|
||||||
{" "}
|
align={"center"}>
|
||||||
回复:{" "}
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
}}>
|
||||||
|
回复:
|
||||||
</span>
|
</span>
|
||||||
<span style={{ fontSize: 13 }}>
|
<span
|
||||||
{" "}
|
style={{
|
||||||
landaiqing
|
fontSize: 13,
|
||||||
|
}}>
|
||||||
|
{item.nick}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
icon={<CloseOutlined />}
|
icon={<CloseOutlined />}
|
||||||
@@ -277,11 +305,10 @@ const Comment = () => {
|
|||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
}}
|
}}
|
||||||
type={"dashed"}
|
type={"dashed"}
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
setIsReplyComment(false)
|
setIsReply(null);
|
||||||
}
|
}}
|
||||||
size={"small"}>
|
size={"small"}>
|
||||||
{" "}
|
|
||||||
取消回复
|
取消回复
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -298,7 +325,9 @@ const Comment = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={true}
|
vertical={true}
|
||||||
style={{ width: "100%" }}>
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
}}>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
style={{
|
style={{
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
@@ -307,6 +336,12 @@ const Comment = () => {
|
|||||||
rows={3}
|
rows={3}
|
||||||
maxLength={500}
|
maxLength={500}
|
||||||
showCount
|
showCount
|
||||||
|
onChange={(e) => {
|
||||||
|
setReplyData(
|
||||||
|
e.target
|
||||||
|
.value,
|
||||||
|
);
|
||||||
|
}}
|
||||||
placeholder={
|
placeholder={
|
||||||
"平等表达,友善交流"
|
"平等表达,友善交流"
|
||||||
}></Input.TextArea>
|
}></Input.TextArea>
|
||||||
@@ -334,30 +369,88 @@ const Comment = () => {
|
|||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
justify={"flex-end"}>
|
justify={
|
||||||
|
"flex-end"
|
||||||
|
}>
|
||||||
<Button
|
<Button
|
||||||
icon={<SendOutlined />}
|
onClick={() => {
|
||||||
type={"primary"}>
|
const data: any =
|
||||||
|
{
|
||||||
|
userId: 32,
|
||||||
|
detailId:
|
||||||
|
params.id,
|
||||||
|
content:
|
||||||
|
replyData,
|
||||||
|
toId: item.id,
|
||||||
|
replyId:
|
||||||
|
item.id,
|
||||||
|
};
|
||||||
|
addReplies(
|
||||||
|
data,
|
||||||
|
).then();
|
||||||
|
}}
|
||||||
|
icon={
|
||||||
|
<SendOutlined />
|
||||||
|
}
|
||||||
|
type={
|
||||||
|
"primary"
|
||||||
|
}>
|
||||||
发表
|
发表
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</Flex>
|
{isReplyComment === index &&
|
||||||
</Flex>
|
reply &&
|
||||||
<Flex vertical={false}>
|
Array.from(reply).map(
|
||||||
<Flex vertical={true} justify={"flex-start"}>
|
(
|
||||||
<Avatar src={logo as any} size={"default"}></Avatar>
|
replyItem: any,
|
||||||
|
replyIndex: number,
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
key={replyIndex}
|
||||||
|
vertical={false}>
|
||||||
|
<Flex
|
||||||
|
vertical={true}
|
||||||
|
justify={
|
||||||
|
"flex-start"
|
||||||
|
}>
|
||||||
|
<Avatar
|
||||||
|
src={
|
||||||
|
replyItem.avatar as any
|
||||||
|
}
|
||||||
|
size={
|
||||||
|
"default"
|
||||||
|
}></Avatar>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={true}
|
vertical={true}
|
||||||
style={{ marginLeft: 15, width: "100%" }}>
|
style={{
|
||||||
<Flex vertical={false} align={"center"}>
|
marginLeft: 15,
|
||||||
<span style={{ fontSize: 14, fontWeight: 500 }}>
|
width: "100%",
|
||||||
sjm 回复 landaiqing
|
}}>
|
||||||
|
<Flex
|
||||||
|
vertical={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 500,
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
replyItem.nick
|
||||||
|
}{" "}
|
||||||
|
回复
|
||||||
|
{
|
||||||
|
replyItem.nickto
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
{/*<Tag*/}
|
{/*<Tag*/}
|
||||||
{/* bordered={false}*/}
|
{/* bordered={false}*/}
|
||||||
@@ -368,20 +461,47 @@ const Comment = () => {
|
|||||||
{/*</Tag>*/}
|
{/*</Tag>*/}
|
||||||
</Flex>
|
</Flex>
|
||||||
<ProCard
|
<ProCard
|
||||||
bordered={true}
|
bordered={
|
||||||
boxShadow={false}
|
true
|
||||||
extra={<></>}
|
}
|
||||||
style={{ width: "100%" }}>
|
boxShadow={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
extra={
|
||||||
|
<></>
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
}}>
|
||||||
<span>
|
<span>
|
||||||
i回复OIDHJHDCEHIceh车hi是事实上事实是事实hi是是是是是是是是是是
|
{
|
||||||
|
replyItem.content
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={
|
||||||
style={{ marginTop: 10, width: "100%" }}>
|
false
|
||||||
<span style={{ fontSize: 13, color: "grey" }}>
|
}
|
||||||
1 小时前
|
style={{
|
||||||
|
marginTop: 10,
|
||||||
|
width: "100%",
|
||||||
|
}}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
replyItem.createdTime
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex
|
||||||
|
vertical={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}>
|
||||||
<LikeOutlined
|
<LikeOutlined
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
@@ -390,89 +510,152 @@ const Comment = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
10
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<CommentOutlined
|
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
marginLeft: 10,
|
}}>
|
||||||
}}
|
{
|
||||||
/>
|
replyItem.likes
|
||||||
<span
|
}
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
|
||||||
10
|
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex
|
||||||
|
vertical={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}>
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
size={"small"}
|
size={
|
||||||
onClick={() => setIsReplyComment(true)}
|
"small"
|
||||||
style={{ fontSize: 13, color: "grey" }}>
|
}
|
||||||
|
onClick={() => {
|
||||||
|
handleExpandReplyReplyClick(
|
||||||
|
replyItem.id,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
回复
|
回复
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
{isReplyComment && (
|
{isReplyReply ===
|
||||||
|
replyItem.id && (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={true}>
|
<Flex
|
||||||
<Flex vertical={false} align={"center"}>
|
vertical={
|
||||||
<span style={{ fontSize: 13 }}>
|
true
|
||||||
{" "}
|
}>
|
||||||
回复:{" "}
|
<Flex
|
||||||
|
vertical={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
}}>
|
||||||
|
回复:
|
||||||
</span>
|
</span>
|
||||||
<span style={{ fontSize: 13 }}>
|
<span
|
||||||
{" "}
|
style={{
|
||||||
landaiqing
|
fontSize: 13,
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
replyItem.nick
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
icon={<CloseOutlined />}
|
icon={
|
||||||
|
<CloseOutlined />
|
||||||
|
}
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
}}
|
}}
|
||||||
type={"dashed"}
|
type={
|
||||||
onClick={() =>
|
"dashed"
|
||||||
setIsReplyComment(false)
|
|
||||||
}
|
}
|
||||||
size={"small"}>
|
onClick={() => {
|
||||||
{" "}
|
setIsReplyReply(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
size={
|
||||||
|
"small"
|
||||||
|
}>
|
||||||
取消回复
|
取消回复
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={
|
||||||
style={{ marginTop: 5 }}>
|
false
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
marginTop: 5,
|
||||||
|
}}>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={true}
|
vertical={
|
||||||
justify={"flex-start"}>
|
true
|
||||||
|
}
|
||||||
|
justify={
|
||||||
|
"flex-start"
|
||||||
|
}>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={logo as any}
|
src={
|
||||||
size={"default"}
|
logo as any
|
||||||
|
}
|
||||||
|
size={
|
||||||
|
"default"
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={true}
|
vertical={
|
||||||
style={{ width: "100%" }}>
|
true
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
}}>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
style={{
|
style={{
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
rows={3}
|
rows={
|
||||||
maxLength={500}
|
3
|
||||||
|
}
|
||||||
|
onChange={(
|
||||||
|
e: any,
|
||||||
|
) => {
|
||||||
|
setReplyReplyData(
|
||||||
|
e
|
||||||
|
.target
|
||||||
|
.value,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
maxLength={
|
||||||
|
500
|
||||||
|
}
|
||||||
showCount
|
showCount
|
||||||
placeholder={
|
placeholder={
|
||||||
"平等表达,友善交流"
|
"平等表达,友善交流"
|
||||||
}></Input.TextArea>
|
}></Input.TextArea>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={
|
||||||
align={"center"}
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}
|
||||||
style={{
|
style={{
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
@@ -492,12 +675,38 @@ const Comment = () => {
|
|||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={
|
||||||
align={"center"}
|
false
|
||||||
justify={"flex-end"}>
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}
|
||||||
|
justify={
|
||||||
|
"flex-end"
|
||||||
|
}>
|
||||||
<Button
|
<Button
|
||||||
icon={<SendOutlined />}
|
onClick={() => {
|
||||||
type={"primary"}>
|
const data: any =
|
||||||
|
{
|
||||||
|
userId: 32,
|
||||||
|
detailId:
|
||||||
|
params.id,
|
||||||
|
content:
|
||||||
|
replyReplyData,
|
||||||
|
toId: item.id,
|
||||||
|
replyId:
|
||||||
|
replyItem.id,
|
||||||
|
};
|
||||||
|
addReplies(
|
||||||
|
data,
|
||||||
|
).then();
|
||||||
|
}}
|
||||||
|
icon={
|
||||||
|
<SendOutlined />
|
||||||
|
}
|
||||||
|
type={
|
||||||
|
"primary"
|
||||||
|
}>
|
||||||
发表
|
发表
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -508,10 +717,18 @@ const Comment = () => {
|
|||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
</Skeleton>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@@ -1,11 +1,10 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import { Avatar, Button, Divider, Flex, Input, List, Skeleton, Tag } from "antd";
|
import { Avatar, Button, Flex, Input, List, Skeleton, Tag } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import InfiniteScroll from "react-infinite-scroll-component";
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
CommentOutlined,
|
CommentOutlined,
|
||||||
EyeOutlined,
|
EyeOutlined,
|
||||||
@@ -13,7 +12,10 @@ import {
|
|||||||
LeftOutlined,
|
LeftOutlined,
|
||||||
ShareAltOutlined,
|
ShareAltOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import logo from "@/assets/icons/aliyun.svg";
|
import { shareDetailList } from "@/api/share";
|
||||||
|
import getRandomColor from "@/constant/random-color.ts";
|
||||||
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
interface DataType {
|
interface DataType {
|
||||||
gender: string;
|
gender: string;
|
||||||
name: {
|
name: {
|
||||||
@@ -30,28 +32,24 @@ interface DataType {
|
|||||||
nat: string;
|
nat: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => {
|
export default observer(() => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState(false);
|
const params = useParams();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
const [data, setData] = useState<DataType[]>([]);
|
const [data, setData] = useState<DataType[]>([]);
|
||||||
const loadMoreData = () => {
|
const store = useStore("share");
|
||||||
if (loading) {
|
async function getShareDetailList() {
|
||||||
return;
|
store.setCircleId(params.id as string);
|
||||||
|
shareDetailList(params.id).then((res: any) => {
|
||||||
|
if (res && res.data && res.data) {
|
||||||
|
setData(res.data);
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
setLoading(true);
|
|
||||||
fetch("https://randomuser.me/api/?results=10&inc=name,gender,email,nat,picture&noinfo")
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((body) => {
|
|
||||||
setData([...data, ...body.results]);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setLoading(false);
|
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadMoreData();
|
getShareDetailList().then();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -83,13 +81,7 @@ export default () => {
|
|||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard bordered={false} boxShadow={false}>
|
<ProCard bordered={false} boxShadow={false}>
|
||||||
<InfiniteScroll
|
<Skeleton loading={loading} active={true} paragraph={{ rows: 14 }}>
|
||||||
dataLength={data.length}
|
|
||||||
next={loadMoreData}
|
|
||||||
hasMore={data.length < 50}
|
|
||||||
loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
|
|
||||||
endMessage={<Divider plain>It is all, nothing more 🤐</Divider>}
|
|
||||||
scrollableTarget="scrollableDiv">
|
|
||||||
<List
|
<List
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
header={
|
header={
|
||||||
@@ -97,25 +89,34 @@ export default () => {
|
|||||||
<h4>分享列表</h4>
|
<h4>分享列表</h4>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
renderItem={(item) => (
|
renderItem={(item: any) => (
|
||||||
<List.Item key={item.email}>
|
<List.Item key={item.id}>
|
||||||
<List.Item.Meta
|
<List.Item.Meta
|
||||||
avatar={<Avatar src={item.picture.large} />}
|
avatar={<Avatar src={item.icon} />}
|
||||||
title={
|
title={
|
||||||
<>
|
<Flex vertical={false} align={"center"}>
|
||||||
<a
|
<Link to={"/main/share/detail/" + item.id}>
|
||||||
onClick={() => {
|
{item.title}
|
||||||
navigate("/main/share/detail/1");
|
</Link>
|
||||||
}}>
|
{item.tags &&
|
||||||
{item.name.last}
|
Array.from(item.tags).map(
|
||||||
</a>
|
(tag: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}
|
||||||
|
key={index}>
|
||||||
<Tag
|
<Tag
|
||||||
bordered={false}
|
bordered={false}
|
||||||
color="processing"
|
color={getRandomColor()}
|
||||||
style={{ marginLeft: 10 }}>
|
style={{ marginLeft: 10 }}>
|
||||||
IDM
|
{tag.tagName}
|
||||||
</Tag>
|
</Tag>
|
||||||
</>
|
</Flex>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
}
|
}
|
||||||
description={
|
description={
|
||||||
<>
|
<>
|
||||||
@@ -123,7 +124,7 @@ export default () => {
|
|||||||
vertical={false}
|
vertical={false}
|
||||||
justify={"space-between"}
|
justify={"space-between"}
|
||||||
align={"center"}>
|
align={"center"}>
|
||||||
{item.email}
|
{item.description}
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
@@ -131,7 +132,7 @@ export default () => {
|
|||||||
style={{ width: "300px" }}>
|
style={{ width: "300px" }}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<Avatar
|
<Avatar
|
||||||
src={logo as any}
|
src={item.avatar as any}
|
||||||
size={"small"}
|
size={"small"}
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -140,7 +141,7 @@ export default () => {
|
|||||||
color: "gray",
|
color: "gray",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}>
|
}}>
|
||||||
landaiqing
|
{item.nickname}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -150,7 +151,7 @@ export default () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
1024
|
{item.likesCount}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -160,7 +161,7 @@ export default () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
1024
|
{item.commentCount}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -172,7 +173,7 @@ export default () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
1024
|
{item.views}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -180,13 +181,12 @@ export default () => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{/*<div>Content</div>*/}
|
|
||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</InfiniteScroll>
|
</Skeleton>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
@@ -1,22 +1,48 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
import { FunctionComponent, useState } from "react";
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { Avatar, Button, Card, Drawer, Flex, FloatButton, Form, Image, Input, Space } from "antd";
|
import {
|
||||||
|
Avatar,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Drawer,
|
||||||
|
Flex,
|
||||||
|
FloatButton,
|
||||||
|
Form,
|
||||||
|
Image,
|
||||||
|
Input,
|
||||||
|
message,
|
||||||
|
Skeleton,
|
||||||
|
Tooltip,
|
||||||
|
} from "antd";
|
||||||
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import TextArea from "antd/es/input/TextArea";
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { EyeOutlined, PlusOutlined, UnorderedListOutlined } from "@ant-design/icons";
|
import { EyeOutlined, PlusOutlined, UnorderedListOutlined } from "@ant-design/icons";
|
||||||
import pic from "@/assets/images/background.png";
|
|
||||||
|
|
||||||
import Meta from "antd/es/card/Meta";
|
import Meta from "antd/es/card/Meta";
|
||||||
|
import { addShareCircle, getShareCircleList } from "@/api/share";
|
||||||
const MainShare: FunctionComponent = () => {
|
const MainShare: FunctionComponent = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [circleList, setCircleList] = useState<any[]>([]);
|
||||||
|
const [form] = Form.useForm();
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
|
async function getShareCircles() {
|
||||||
|
getShareCircleList().then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setCircleList(res.data);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getShareCircles().then();
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.share_main}>
|
<div className={styles.share_main}>
|
||||||
@@ -30,53 +56,68 @@ const MainShare: FunctionComponent = () => {
|
|||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard title={<h3>文件分享圈</h3>} bordered={false} boxShadow={false}>
|
<ProCard title={<h3>文件分享圈</h3>} bordered={false} boxShadow={false}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"} wrap={true} justify={"flex-start"}>
|
||||||
|
<Skeleton active={true} loading={loading} paragraph={{ rows: 10 }}>
|
||||||
|
{circleList &&
|
||||||
|
circleList.map((item: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<div key={index}>
|
||||||
<Card
|
<Card
|
||||||
hoverable
|
hoverable
|
||||||
style={{
|
style={{
|
||||||
width: "250px",
|
width: "250px",
|
||||||
boxShadow: " 0 0 10px rgba(0, 0, 0, 0.1)",
|
boxShadow: " 0 0 10px rgba(0, 0, 0, 0.1)",
|
||||||
borderRadius: 20,
|
borderRadius: 20,
|
||||||
|
marginLeft: 30,
|
||||||
|
marginTop: 20,
|
||||||
// backgroundColor: "rgba(79,68,68,0.11)",
|
// backgroundColor: "rgba(79,68,68,0.11)",
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate("/main/share/list/1");
|
navigate("/main/share/list/" + item.id);
|
||||||
}}
|
}}
|
||||||
cover={
|
cover={
|
||||||
<Image
|
<Image
|
||||||
alt="example"
|
alt="example"
|
||||||
src={pic as any}
|
src={item.icon}
|
||||||
style={{
|
style={{
|
||||||
height: 180,
|
height: 180,
|
||||||
borderTopLeftRadius: 20,
|
borderTopLeftRadius: 20,
|
||||||
borderTopRightRadius: 20,
|
borderTopRightRadius: 20,
|
||||||
|
backgroundSize: "cover",
|
||||||
}}
|
}}
|
||||||
preview={false}
|
preview={false}
|
||||||
width={"100%"}
|
width={"100%"}
|
||||||
|
height={"100%"}
|
||||||
fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg=="
|
fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg=="
|
||||||
/>
|
/>
|
||||||
}>
|
}>
|
||||||
<Meta title="工具软件分享" description="分享一些常用的办公软件" />
|
<Meta
|
||||||
{/*<Avatar*/}
|
title={item.name}
|
||||||
{/* src={pic2 as any}*/}
|
description={
|
||||||
{/* shape={"circle"}*/}
|
<>
|
||||||
{/* style={{*/}
|
<Tooltip title={item.description}>
|
||||||
{/* position: "absolute",*/}
|
<span>{item.description}</span>
|
||||||
{/* top: 160,*/}
|
</Tooltip>
|
||||||
{/* left: 10,*/}
|
</>
|
||||||
{/* width: 60,*/}
|
}
|
||||||
{/* height: 60,*/}
|
/>
|
||||||
{/* zIndex: 9999,*/}
|
|
||||||
{/* }}></Avatar>*/}
|
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
style={{ marginTop: 10 }}
|
style={{ marginTop: 10 }}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
justify={"space-between"}>
|
justify={"space-between"}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<Avatar src={pic as any} size={"small"} />{" "}
|
<Avatar
|
||||||
<span style={{ fontSize: 12, color: "gray", marginLeft: 5 }}>
|
src={item.avatar as any}
|
||||||
landaiqing
|
size={"small"}
|
||||||
|
/>{" "}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
marginLeft: 5,
|
||||||
|
}}>
|
||||||
|
{item.nickName}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -85,22 +126,38 @@ const MainShare: FunctionComponent = () => {
|
|||||||
style={{ width: 100 }}
|
style={{ width: 100 }}
|
||||||
justify={"space-between"}>
|
justify={"space-between"}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<EyeOutlined style={{ color: "gray" }} />{" "}
|
<EyeOutlined
|
||||||
|
style={{ color: "gray" }}
|
||||||
|
/>{" "}
|
||||||
<span
|
<span
|
||||||
style={{ fontSize: 12, color: "gray", marginLeft: 5 }}>
|
style={{
|
||||||
1024
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
marginLeft: 5,
|
||||||
|
}}>
|
||||||
|
{item.views}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<UnorderedListOutlined style={{ color: "gray" }} />{" "}
|
<UnorderedListOutlined
|
||||||
|
style={{ color: "gray" }}
|
||||||
|
/>{" "}
|
||||||
<span
|
<span
|
||||||
style={{ fontSize: 12, color: "gray", marginLeft: 5 }}>
|
style={{
|
||||||
999
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
marginLeft: 5,
|
||||||
|
}}>
|
||||||
|
{item.count}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Skeleton>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,15 +171,44 @@ const MainShare: FunctionComponent = () => {
|
|||||||
paddingBottom: 80,
|
paddingBottom: 80,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
extra={
|
// extra={
|
||||||
<Space>
|
// <Space>
|
||||||
<Button onClick={onClose}>取消</Button>
|
// <Button onClick={onClose}>取消</Button>
|
||||||
<Button onClick={onClose} type="primary">
|
// <Button onClick={onClose} type="primary">
|
||||||
提交
|
// 提交
|
||||||
</Button>
|
// </Button>
|
||||||
</Space>
|
// </Space>
|
||||||
}>
|
// }
|
||||||
<Form layout="vertical">
|
>
|
||||||
|
<Form
|
||||||
|
layout="vertical"
|
||||||
|
form={form}
|
||||||
|
onFinish={(values: any) => {
|
||||||
|
const formData = {
|
||||||
|
userId: 17,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
addShareCircle(formData).then((res: any) => {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: "创建成功",
|
||||||
|
type: "success",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
setOpen(false);
|
||||||
|
getShareCircles().then();
|
||||||
|
form.resetFields();
|
||||||
|
} else {
|
||||||
|
message
|
||||||
|
.open({
|
||||||
|
content: res.data,
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label="名称"
|
label="名称"
|
||||||
@@ -143,6 +229,16 @@ const MainShare: FunctionComponent = () => {
|
|||||||
rules={[{ required: true, message: "请输入描述!" }]}>
|
rules={[{ required: true, message: "请输入描述!" }]}>
|
||||||
<TextArea rows={4} maxLength={50} showCount placeholder="请输入描述!" />
|
<TextArea rows={4} maxLength={50} showCount placeholder="请输入描述!" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
}}>
|
||||||
|
<Button type="primary" htmlType="submit">
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<FloatButton
|
<FloatButton
|
||||||
|
@@ -10,17 +10,15 @@ import {
|
|||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import Meta from "antd/es/card/Meta";
|
import Meta from "antd/es/card/Meta";
|
||||||
import gitee from "@/assets/icons/gitee.svg";
|
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { getAllStorage } from "@/api/oss";
|
import { getAllStorage } from "@/api/oss";
|
||||||
import StorageIcon from "@/constant/stroage-icon.ts";
|
import StorageIcon from "@/constant/stroage-icon.ts";
|
||||||
import { getUserInfoApi } from "@/api/user";
|
|
||||||
|
|
||||||
const UserInfo: FunctionComponent = () => {
|
const UserInfo: FunctionComponent = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [userStorage, setUserStorage] = useState([]);
|
const [userStorage, setUserStorage] = useState([]);
|
||||||
const [userInfo, setUserInfo] = useState<any>({} as any);
|
// const [userInfo, setUserInfo] = useState<any>({} as any);
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
title: "Ant Design Title 1",
|
title: "Ant Design Title 1",
|
||||||
@@ -36,20 +34,20 @@ const UserInfo: FunctionComponent = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
async function getUserStorage() {
|
async function getUserStorage() {
|
||||||
const res = await getAllStorage("1");
|
const res: any = await getAllStorage("1");
|
||||||
if (res.success) {
|
if (res && res.success && res.data) {
|
||||||
setUserStorage(res.data);
|
setUserStorage(res.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const getUserInfo = async () => {
|
// const getUserInfo = async () => {
|
||||||
const res = await getUserInfoApi("9");
|
// const res = await getUserInfoApi("9");
|
||||||
if (res.success) {
|
// if (res && res.success && res.data) {
|
||||||
setUserInfo(res.data);
|
// setUserInfo(res.data);
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserInfo().then();
|
// getUserInfo().then();
|
||||||
getUserStorage().then();
|
getUserStorage().then();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
|
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
import { useUserStore } from "./modules/user.ts";
|
import { useUserStore } from "./modules/user.ts";
|
||||||
import { useFileStore } from "@/store/modules/file.ts";
|
import { useFileStore } from "@/store/modules/file.ts";
|
||||||
|
import { useShareStore } from "@/store/modules/share.ts";
|
||||||
|
|
||||||
/** 将每个Store实例化 */
|
/** 将每个Store实例化 */
|
||||||
export const RootStore = {
|
export const RootStore = {
|
||||||
user: new useUserStore(),
|
user: new useUserStore(),
|
||||||
file: new useFileStore(),
|
file: new useFileStore(),
|
||||||
|
share: new useShareStore(),
|
||||||
};
|
};
|
||||||
|
@@ -5,34 +5,78 @@ import { isHydrated, makePersistable } from "mobx-persist-store";
|
|||||||
import { handleLocalforage } from "@/utils/localforage";
|
import { handleLocalforage } from "@/utils/localforage";
|
||||||
|
|
||||||
export class useFileStore {
|
export class useFileStore {
|
||||||
filePath: [any] = [];
|
filePath: any[] = []; // 文件路径
|
||||||
|
currentStorage: string = ""; // 当前存储商
|
||||||
|
currentBucket: string = ""; // 当前存储桶
|
||||||
|
currentFile: string = ""; // 当前文件
|
||||||
|
copyFile: string = ""; // 复制的文件地址
|
||||||
|
pasteFile: string = ""; //粘贴的地址
|
||||||
|
copyFileName: string = ""; // 复制的文件名
|
||||||
|
uploadFileStorage: string = ""; // 上传文件的存储商
|
||||||
|
uploadFileBucket: string = ""; // 上传文件的存储桶
|
||||||
|
uploadFilePath: string = ""; // 上传文件的路径
|
||||||
constructor() {
|
constructor() {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
filePath: observable,
|
filePath: observable,
|
||||||
|
currentStorage: observable,
|
||||||
|
currentFile: observable,
|
||||||
|
currentBucket: observable,
|
||||||
|
copyFile: observable,
|
||||||
|
pasteFile: observable,
|
||||||
|
copyFileName: observable,
|
||||||
|
uploadFileStorage: observable,
|
||||||
|
uploadFileBucket: observable,
|
||||||
|
uploadFilePath: observable,
|
||||||
setFilePath: action,
|
setFilePath: action,
|
||||||
getFilePath: action,
|
getFilePath: action,
|
||||||
clearFilePath: action,
|
clearFilePath: action,
|
||||||
getFilePathSecondLast: action,
|
getFilePathSecondLast: action,
|
||||||
getMiddlePath: action,
|
getMiddlePath: action,
|
||||||
clearAllFilePath: action,
|
clearAllFilePath: action,
|
||||||
|
getFilePathExceptFirst: action,
|
||||||
|
setCurrentBucket: action,
|
||||||
|
setCurrentStorage: action,
|
||||||
|
getCurrentBucket: action,
|
||||||
|
getCurrentStorage: action,
|
||||||
|
getCurrentFile: action,
|
||||||
|
setCurrentFile: action,
|
||||||
isHydrated: action,
|
isHydrated: action,
|
||||||
|
setCopyFile: action,
|
||||||
|
getCopyFile: action,
|
||||||
|
setPasteFile: action,
|
||||||
|
getPasteFile: action,
|
||||||
|
getCopyFileName: action,
|
||||||
|
setCopyFileName: action,
|
||||||
|
setUploadFileStorage: action,
|
||||||
|
getUploadFileStorage: action,
|
||||||
|
setUploadFileBucket: action,
|
||||||
|
getUploadFileBucket: action,
|
||||||
|
setUploadFilePath: action,
|
||||||
|
getUploadFilePath: action,
|
||||||
});
|
});
|
||||||
makePersistable(
|
makePersistable(
|
||||||
this,
|
this,
|
||||||
{
|
{
|
||||||
// 在构造函数内使用 makePersistable
|
// 在构造函数内使用 makePersistable
|
||||||
name: "file", // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
|
name: "file", // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
|
||||||
properties: ["filePath"], // 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
|
properties: [
|
||||||
|
"filePath",
|
||||||
|
"currentStorage",
|
||||||
|
"currentBucket",
|
||||||
|
"currentFile",
|
||||||
|
"copyFile",
|
||||||
|
"pasteFile",
|
||||||
|
"copyFileName",
|
||||||
|
], // 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
|
||||||
storage: handleLocalforage, // 保存的位置:可以是localStorage,sessionstorage
|
storage: handleLocalforage, // 保存的位置:可以是localStorage,sessionstorage
|
||||||
removeOnExpiration: true, //如果 expireIn 具有值且已过期,则在调用 getItem 时将自动删除存储中的数据。默认值为 true。
|
// removeOnExpiration: true, //如果 expireIn 具有值且已过期,则在调用 getItem 时将自动删除存储中的数据。默认值为 true。
|
||||||
stringify: false, //如果为 true,则数据在传递给 setItem 之前将是 JSON.stringify。默认值为 true。
|
// stringify: false, //如果为 true,则数据在传递给 setItem 之前将是 JSON.stringify。默认值为 true。
|
||||||
expireIn: 2592000000, // 一个以毫秒为单位的值,用于确定 getItem 何时不应检索存储中的数据。默认情况下永不过期。
|
// expireIn: 2592000000, // 一个以毫秒为单位的值,用于确定 getItem 何时不应检索存储中的数据。默认情况下永不过期。
|
||||||
debugMode: false, // 如果为 true,将为多个 mobx-persist-store 项调用 console.info。默认值为 false。
|
// debugMode: false, // 如果为 true,将为多个 mobx-persist-store 项调用 console.info。默认值为 false。
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
delay: 0, // 允许您设置一个 delay 选项来限制 write 函数的调用次数。默认情况下没有延迟。
|
// delay: 0, // 允许您设置一个 delay 选项来限制 write 函数的调用次数。默认情况下没有延迟。
|
||||||
fireImmediately: false, // 确定是应立即保留存储数据,还是等到存储中的属性发生更改。 false 默认情况下。
|
// fireImmediately: false, // 确定是应立即保留存储数据,还是等到存储中的属性发生更改。 false 默认情况下。
|
||||||
},
|
},
|
||||||
).then(
|
).then(
|
||||||
action(() => {
|
action(() => {
|
||||||
@@ -64,6 +108,15 @@ export class useFileStore {
|
|||||||
getFilePathSecondLast() {
|
getFilePathSecondLast() {
|
||||||
return this.filePath.slice(0, -1).pop();
|
return this.filePath.slice(0, -1).pop();
|
||||||
}
|
}
|
||||||
|
// 获取文件路径除了第一个
|
||||||
|
getFilePathExceptFirst() {
|
||||||
|
if (this.filePath.length === 1) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return this.filePath.slice(1).join("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 获取文件路径中间路径
|
// 获取文件路径中间路径
|
||||||
getMiddlePath() {
|
getMiddlePath() {
|
||||||
if (this.filePath.length <= 2) {
|
if (this.filePath.length <= 2) {
|
||||||
@@ -75,4 +128,72 @@ export class useFileStore {
|
|||||||
isHydrated() {
|
isHydrated() {
|
||||||
return isHydrated(this);
|
return isHydrated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置当前存储桶
|
||||||
|
setCurrentBucket(currentBucket: string) {
|
||||||
|
this.currentBucket = currentBucket;
|
||||||
|
}
|
||||||
|
// 设置当前存储商
|
||||||
|
setCurrentStorage(currentStorage: string) {
|
||||||
|
this.currentStorage = currentStorage;
|
||||||
|
}
|
||||||
|
// 获取当前存储商
|
||||||
|
getCurrentStorage() {
|
||||||
|
return this.currentStorage ? this.currentStorage : null;
|
||||||
|
}
|
||||||
|
// 获取当前存储桶
|
||||||
|
getCurrentBucket() {
|
||||||
|
return this.currentBucket ? this.currentBucket : null;
|
||||||
|
}
|
||||||
|
// 获取当前文件
|
||||||
|
getCurrentFile() {
|
||||||
|
return this.currentFile ? this.currentFile : null;
|
||||||
|
}
|
||||||
|
// 设置当前文件
|
||||||
|
setCurrentFile(currentFile: string) {
|
||||||
|
return (this.currentFile = currentFile);
|
||||||
|
}
|
||||||
|
//设置复制文件
|
||||||
|
setCopyFile(copyFile: string) {
|
||||||
|
this.copyFile = copyFile;
|
||||||
|
}
|
||||||
|
// 设置粘贴文件
|
||||||
|
setPasteFile(pasteFile: string) {
|
||||||
|
this.pasteFile = pasteFile;
|
||||||
|
}
|
||||||
|
// 获取复制文件
|
||||||
|
getCopyFile() {
|
||||||
|
return this.copyFile ? this.copyFile : null;
|
||||||
|
}
|
||||||
|
// 获取粘贴文件
|
||||||
|
getPasteFile() {
|
||||||
|
return this.pasteFile ? this.pasteFile : null;
|
||||||
|
}
|
||||||
|
// 设置文件名称
|
||||||
|
setCopyFileName(copyFileName: string) {
|
||||||
|
this.copyFileName = copyFileName;
|
||||||
|
}
|
||||||
|
// 获取文件名称
|
||||||
|
getCopyFileName() {
|
||||||
|
return this.copyFileName ? this.copyFileName : null;
|
||||||
|
}
|
||||||
|
setUploadFileStorage(uploadFileStorage: string) {
|
||||||
|
this.uploadFileStorage = uploadFileStorage;
|
||||||
|
}
|
||||||
|
getUploadFileStorage() {
|
||||||
|
return this.uploadFileStorage ? this.uploadFileStorage : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setUploadFileBucket(uploadFileBucket: string) {
|
||||||
|
this.uploadFileBucket = uploadFileBucket;
|
||||||
|
}
|
||||||
|
getUploadFileBucket() {
|
||||||
|
return this.uploadFileBucket ? this.uploadFileBucket : null;
|
||||||
|
}
|
||||||
|
setUploadFilePath(uploadFilePath: string) {
|
||||||
|
this.uploadFilePath = uploadFilePath;
|
||||||
|
}
|
||||||
|
getUploadFilePath() {
|
||||||
|
return this.uploadFilePath ? this.uploadFilePath : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
52
src/store/modules/share.ts
Normal file
52
src/store/modules/share.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/** @format */
|
||||||
|
|
||||||
|
import { action, makeObservable, observable } from "mobx";
|
||||||
|
import { isHydrated, makePersistable } from "mobx-persist-store";
|
||||||
|
import { handleLocalforage } from "@/utils/localforage";
|
||||||
|
|
||||||
|
export class useShareStore {
|
||||||
|
circleId: string = "";
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
makeObservable(this, {
|
||||||
|
circleId: observable,
|
||||||
|
setCircleId: action,
|
||||||
|
getCircleId: action,
|
||||||
|
isHydrated: action,
|
||||||
|
});
|
||||||
|
makePersistable(
|
||||||
|
this,
|
||||||
|
{
|
||||||
|
// 在构造函数内使用 makePersistable
|
||||||
|
name: "shareInfo", // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
|
||||||
|
properties: ["circleId"], // 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
|
||||||
|
storage: handleLocalforage, // 保存的位置:可以是localStorage,sessionstorage
|
||||||
|
// removeOnExpiration: true, //如果 expireIn 具有值且已过期,则在调用 getItem 时将自动删除存储中的数据。默认值为 true。
|
||||||
|
// stringify: false, //如果为 true,则数据在传递给 setItem 之前将是 JSON.stringify。默认值为 true。
|
||||||
|
// expireIn: 2592000000, // 一个以毫秒为单位的值,用于确定 getItem 何时不应检索存储中的数据。默认情况下永不过期。
|
||||||
|
// debugMode: false, // 如果为 true,将为多个 mobx-persist-store 项调用 console.info。默认值为 false。
|
||||||
|
} as any,
|
||||||
|
{
|
||||||
|
// delay: 0, // 允许您设置一个 delay 选项来限制 write 函数的调用次数。默认情况下没有延迟。
|
||||||
|
// fireImmediately: false, // 确定是应立即保留存储数据,还是等到存储中的属性发生更改。 false 默认情况下。
|
||||||
|
},
|
||||||
|
).then(
|
||||||
|
action(() => {
|
||||||
|
// persist 完成的回调,在这里可以执行一些拿到数据后需要执行的操作,如果在页面上要判断是否完成persist,使用 isHydrated
|
||||||
|
// console.log(persistStore)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCircleId() {
|
||||||
|
return this.circleId ? this.circleId : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
isHydrated() {
|
||||||
|
return isHydrated(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCircleId(circleId: string) {
|
||||||
|
this.circleId = circleId;
|
||||||
|
}
|
||||||
|
}
|
@@ -25,14 +25,14 @@ export class useUserStore {
|
|||||||
name: "userInfo", // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
|
name: "userInfo", // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
|
||||||
properties: ["token", "userId"], // 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
|
properties: ["token", "userId"], // 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
|
||||||
storage: handleLocalforage, // 保存的位置:可以是localStorage,sessionstorage
|
storage: handleLocalforage, // 保存的位置:可以是localStorage,sessionstorage
|
||||||
removeOnExpiration: true, //如果 expireIn 具有值且已过期,则在调用 getItem 时将自动删除存储中的数据。默认值为 true。
|
// removeOnExpiration: true, //如果 expireIn 具有值且已过期,则在调用 getItem 时将自动删除存储中的数据。默认值为 true。
|
||||||
stringify: false, //如果为 true,则数据在传递给 setItem 之前将是 JSON.stringify。默认值为 true。
|
// stringify: false, //如果为 true,则数据在传递给 setItem 之前将是 JSON.stringify。默认值为 true。
|
||||||
expireIn: 2592000000, // 一个以毫秒为单位的值,用于确定 getItem 何时不应检索存储中的数据。默认情况下永不过期。
|
// expireIn: 2592000000, // 一个以毫秒为单位的值,用于确定 getItem 何时不应检索存储中的数据。默认情况下永不过期。
|
||||||
debugMode: false, // 如果为 true,将为多个 mobx-persist-store 项调用 console.info。默认值为 false。
|
// debugMode: false, // 如果为 true,将为多个 mobx-persist-store 项调用 console.info。默认值为 false。
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
delay: 0, // 允许您设置一个 delay 选项来限制 write 函数的调用次数。默认情况下没有延迟。
|
// delay: 0, // 允许您设置一个 delay 选项来限制 write 函数的调用次数。默认情况下没有延迟。
|
||||||
fireImmediately: false, // 确定是应立即保留存储数据,还是等到存储中的属性发生更改。 false 默认情况下。
|
// fireImmediately: false, // 确定是应立即保留存储数据,还是等到存储中的属性发生更改。 false 默认情况下。
|
||||||
},
|
},
|
||||||
).then(
|
).then(
|
||||||
action(() => {
|
action(() => {
|
||||||
|
25
src/types/user.d.ts
vendored
25
src/types/user.d.ts
vendored
@@ -29,4 +29,29 @@ declare namespace API {
|
|||||||
token: string;
|
token: string;
|
||||||
deg: number;
|
deg: number;
|
||||||
};
|
};
|
||||||
|
type AliOSSConfigRequest = {
|
||||||
|
userId?:number;
|
||||||
|
endpoint?:string;
|
||||||
|
accessKeyId?:string;
|
||||||
|
accessKeySecret?:string;
|
||||||
|
}
|
||||||
|
type MinioOSSConfigRequest = {
|
||||||
|
userId?:number;
|
||||||
|
endpoint?:string;
|
||||||
|
accessKey?:string;
|
||||||
|
secretKey?:string;
|
||||||
|
}
|
||||||
|
type QiniuOSSConfigRequest = {
|
||||||
|
userId?:number;
|
||||||
|
endpoint?:string;
|
||||||
|
accessKey?:string;
|
||||||
|
secretKey?:string;
|
||||||
|
region?:string;
|
||||||
|
}
|
||||||
|
type TencentOSSConfigRequest = {
|
||||||
|
userId?:number;
|
||||||
|
appId?:string;
|
||||||
|
secretKey?:string;
|
||||||
|
region?:string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,10 +16,6 @@ class Request {
|
|||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${token}`;
|
config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${token}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (config.method == "post") {
|
|
||||||
// config.data = EncryptData(JSON.stringify(config.data));
|
|
||||||
// }
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
@@ -30,15 +26,11 @@ class Request {
|
|||||||
// 全局响应拦截
|
// 全局响应拦截
|
||||||
this.instance.interceptors.response.use(
|
this.instance.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
// 后端返回字符串表示需要解密操作
|
if (response.data instanceof Blob) {
|
||||||
// if (typeof response.data == "string") {
|
return response;
|
||||||
// response.data = DecryptData(response.data);
|
} else {
|
||||||
// if (response.status !== 200) {
|
|
||||||
// message.error(response.statusText).then();
|
|
||||||
// return Promise.reject(response.data);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return response.data;
|
return response.data;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
const { response } = error;
|
const { response } = error;
|
||||||
@@ -47,9 +39,6 @@ class Request {
|
|||||||
}
|
}
|
||||||
if (!window.navigator.onLine) {
|
if (!window.navigator.onLine) {
|
||||||
message.error("网络连接失败");
|
message.error("网络连接失败");
|
||||||
// return router.push({
|
|
||||||
// path: '/404',
|
|
||||||
// })
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -4,7 +4,7 @@ import Request from "./request";
|
|||||||
|
|
||||||
const web: Request = new Request({
|
const web: Request = new Request({
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
timeout: 5000,
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default web;
|
export default web;
|
||||||
|
@@ -11,7 +11,6 @@ import {
|
|||||||
PageContainer,
|
PageContainer,
|
||||||
ProCard,
|
ProCard,
|
||||||
ProLayout,
|
ProLayout,
|
||||||
SettingDrawer,
|
|
||||||
} from "@ant-design/pro-components";
|
} from "@ant-design/pro-components";
|
||||||
import { Link, Outlet, useLocation } from "react-router-dom";
|
import { Link, Outlet, useLocation } from "react-router-dom";
|
||||||
import logo from "@/assets/images/logo.png";
|
import logo from "@/assets/images/logo.png";
|
||||||
|
1
src/vite-env.d.ts
vendored
1
src/vite-env.d.ts
vendored
@@ -36,3 +36,4 @@ declare module "*.jpeg";
|
|||||||
declare module "*.gif";
|
declare module "*.gif";
|
||||||
declare module "*.bmp";
|
declare module "*.bmp";
|
||||||
declare module "*.tiff";
|
declare module "*.tiff";
|
||||||
|
declare module "base-64";
|
||||||
|
Reference in New Issue
Block a user