Commit 80b273a8 authored by chenshouchao's avatar chenshouchao

feat: 环境压缩包上传

parent 69330ca5
...@@ -49,6 +49,8 @@ const RESTAPI = { ...@@ -49,6 +49,8 @@ const RESTAPI = {
API_ADD_PROJECT_USER:`${BACKEND_API_URI_PREFIX}/cpp/project/updatemember`, // 添加项目成员 API_ADD_PROJECT_USER:`${BACKEND_API_URI_PREFIX}/cpp/project/updatemember`, // 添加项目成员
API_GET_PROJECT_POWER:`${BACKEND_API_URI_PREFIX}/cpp/project/listroles`, // 获取项目权限 API_GET_PROJECT_POWER:`${BACKEND_API_URI_PREFIX}/cpp/project/listroles`, // 获取项目权限
API_GET_HARDWARE:`${BACKEND_API_URI_PREFIX}/cpp/cpce/hardware`, // 获取计算队列列表 API_GET_HARDWARE:`${BACKEND_API_URI_PREFIX}/cpp/cpce/hardware`, // 获取计算队列列表
API_GET_PUBLIC_ENV:`${BACKEND_API_URI_PREFIX}/cpp/common/public/env`, // 获取公共环境
API_GET_PUBLIC_PROJECT:`${BACKEND_API_URI_PREFIX}/cpp/common/public/project`, // 获取公共环境
}; };
export default RESTAPI; export default RESTAPI;
...@@ -354,9 +354,26 @@ const getHardwreList = (params: {zoneId: string, computeType: string}) => { ...@@ -354,9 +354,26 @@ const getHardwreList = (params: {zoneId: string, computeType: string}) => {
params, params,
}); });
} }
// // 获取公共项目
const getPublicProject = () => {
return request({
url: Api.API_GET_PUBLIC_PROJECT,
method: "get",
});
}
// 获取公共环境
const getPublicEnv = (params: {taskType: 'BATCH' | 'FLOW'}) => {
return request({
url: Api.API_GET_PUBLIC_ENV,
method: "get",
params,
});
};
export { export {
getPublicEnv,
getPublicProject,
current, current,
menu, menu,
getProjectList, getProjectList,
......
...@@ -200,7 +200,10 @@ export default function MySelect(props: IProps) { ...@@ -200,7 +200,10 @@ export default function MySelect(props: IProps) {
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<FormControl fullWidth={fullWidth} variant={variant} error={error}> <FormControl fullWidth={fullWidth} variant={variant} error={error}>
{isTitle ? ( {isTitle ? (
<InputLabel id="demo-simple-select-label"> <InputLabel
id="demo-simple-select-label"
sx={{ color: "rgba(194, 198, 204, 1)" }}
>
{title || "请选择"} {title || "请选择"}
</InputLabel> </InputLabel>
) : null} ) : null}
......
...@@ -28,6 +28,7 @@ type IMoveFileProps = { ...@@ -28,6 +28,7 @@ type IMoveFileProps = {
const UpLoaderFile = observer((props: IMoveFileProps) => { const UpLoaderFile = observer((props: IMoveFileProps) => {
const { path, list, uploaderDialogOpen, setUploaderDialogOpen } = props; const { path, list, uploaderDialogOpen, setUploaderDialogOpen } = props;
console.log(path);
const { fileListStore } = useStores(); const { fileListStore } = useStores();
const message = useMessage(); const message = useMessage();
...@@ -41,6 +42,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => { ...@@ -41,6 +42,7 @@ const UpLoaderFile = observer((props: IMoveFileProps) => {
const currentProjectStore = toJS(useGlobalStore("currentProjectStore")); const currentProjectStore = toJS(useGlobalStore("currentProjectStore"));
const uploadInfoStore = toJS(useGlobalStore("fileListStore")); const uploadInfoStore = toJS(useGlobalStore("fileListStore"));
console.log(uploadInfoStore);
const { uploadFile } = UseTusUpload(uploadInfoStore); const { uploadFile } = UseTusUpload(uploadInfoStore);
const onDrop = useCallback( const onDrop = useCallback(
......
...@@ -40,11 +40,15 @@ ...@@ -40,11 +40,15 @@
padding: 16px 24px; padding: 16px 24px;
border: 1px solid #ebedf0; border: 1px solid #ebedf0;
border-right: none; border-right: none;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
} }
.codeBox { .codeBox {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
} }
.codeTitle { .codeTitle {
background-color: rgba(230, 233, 237, 1); background-color: rgba(230, 233, 237, 1);
...@@ -53,6 +57,7 @@ ...@@ -53,6 +57,7 @@
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
font-weight: 550; font-weight: 550;
border-top-right-radius: 4px;
} }
.code { .code {
background-color: rgba(247, 248, 250, 1); background-color: rgba(247, 248, 250, 1);
...@@ -64,12 +69,35 @@ ...@@ -64,12 +69,35 @@
line-height: 22px; line-height: 22px;
font-weight: 550; font-weight: 550;
margin-bottom: 8px; margin-bottom: 8px;
position: relative;
}
.zipText {
color: rgba(138, 144, 153, 1);
font-weight: 400;
} }
.required { .required {
color: rgba(255, 78, 78, 1); color: rgba(255, 78, 78, 1);
} }
.download {
position: absolute;
right: 0;
cursor: pointer;
color: rgba(19, 112, 255, 1);
font-weight: 400;
}
.formItem { .formItem {
position: relative; position: relative;
margin-bottom: 24px;
}
.uploadBox {
border-radius: 4px;
border: 1px dashed #dde1e6;
height: 153px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.formItemHaveHelperText {
margin-bottom: 10px; margin-bottom: 10px;
} }
import { useState } from "react"; import { useEffect, useState, useCallback } from "react";
import MyInput from "@/components/mui/MyInput"; import MyInput from "@/components/mui/MyInput";
import MySelect from "@/components/mui/MySelect"; import MySelect from "@/components/mui/MySelect";
import MyButton from "@/components/mui/MyButton"; import MyButton from "@/components/mui/MyButton";
import style from "./index.module.css"; import style from "./index.module.css";
import useMyRequest from "@/hooks/useMyRequest";
import { urlToken } from "@/api/fileserver/raysyncApi";
import * as tus from "tus-js-client";
import { useDropzone } from "react-dropzone";
import {
getPublicEnv,
getPublicProject,
getDataFileToken,
} from "@/api/project_api";
import classNames from "classnames";
import { getTokenInfo } from "@/utils/util";
type IAddEnvironmentProps = { type IAddEnvironmentProps = {
// addOpen: boolean; // addOpen: boolean;
...@@ -10,14 +21,128 @@ type IAddEnvironmentProps = { ...@@ -10,14 +21,128 @@ type IAddEnvironmentProps = {
const AddEnvironment = (props: IAddEnvironmentProps) => { const AddEnvironment = (props: IAddEnvironmentProps) => {
// const { addOpen } = props; // const { addOpen } = props;
const [taskType, setTaskType] = useState<"BATCH" | "FOLOW">("BATCH"); let tokenInfo = getTokenInfo();
const [publicPrijectId, setPublicPrijectId] = useState("");
const [publicZoneId, setPublicZoneId] = useState("");
const [fileToken, setFileToken] = useState("");
const [taskType, setTaskType] = useState<"BATCH" | "FLOW">("BATCH");
const [];
const [name, setName] = useState(""); const [name, setName] = useState("");
const [baseEnvId, setBaseEnvId] = useState(""); const [baseEnvId, setBaseEnvId] = useState("");
const [envList, setEnvList] = useState<Array<any>>([]);
const [nameHelper, setNameHelper] = useState({ const [nameHelper, setNameHelper] = useState({
error: false, error: false,
text: "30字符以内,仅限字母、数字、中文", text: "30字符以内,仅限字母、数字、中文",
}); });
const [desc, setDesc] = useState(""); const [desc, setDesc] = useState("");
const onDrop = useCallback(
(acceptedFiles: any) => {
console.log(acceptedFiles);
const fileInfo = acceptedFiles[0];
const { fileName, path, size, file } = fileInfo;
const url =
"https://fileserver.cloudam.cn" +
"/parallelupload/" +
urlToken(fileToken, publicPrijectId);
let headers = {
username: publicPrijectId,
token: tokenInfo?.access_token || "",
filetoken: fileToken,
share: false,
project: true,
};
let upload = new tus.Upload(fileInfo, {
endpoint: url,
parallelUploads: 1,
chunkSize: 5 * 1024 * 1024,
metadata: {
filepath: "/",
},
retryDelays: [0, 3000, 5000, 10000, 20000],
headers: headers,
onError: function (error: string) {
console.log("Failed because: " + error);
},
onProgress: function (bytesUploaded: number, bytesTotal: number) {
console.log(bytesUploaded);
console.log(bytesTotal);
// var percentage = (bytesUploaded / bytesTotal) * 100;
// const json = {
// name: upload.file.name,
// bytesUploaded: bytesUploaded,
// bytesTotal: bytesTotal,
// percentage: percentage,
// startTime: timeId,
// isSuspend: false,
// endTime: new Date().getTime(),
// bytesUploaded2: bytesUploaded,
// id: timeId,
// statusMsg: "正在上传",
// upload,
// dir: "/ProjectData/",
// };
// uploadInfoStore?.setUploadInfo(item.id, {
// ...item,
// info: json,
// });
},
onSuccess: function () {
console.log("3154");
// const json = {
// id: timeId,
// percentage: 100,
// startTime: timeId,
// endTime: new Date().getTime() + 1000,
// statusMsg: "上传成功",
// upload,
// };
// uploadInfoStore?.setUploadInfoList(item.id, json);
// callBack && callBack(upload, filepath);
},
});
upload.start();
},
[fileToken, publicPrijectId, tokenInfo?.access_token]
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
const { run: getPublicEnvFn } = useMyRequest(getPublicEnv, {
onSuccess: (res: any) => {
console.log(res);
let arr = res.map((item: any) => {
return {
label: item.title,
value: item.id,
};
});
setEnvList(arr);
},
});
const { run: getPublicProjectFn } = useMyRequest(getPublicProject, {
onSuccess: (res: any) => {
console.log(res);
setPublicPrijectId(res[0].id);
setPublicZoneId(res[0].zoneId);
getDataFileTokenFn({ id: res[0].id });
},
});
const { run: getDataFileTokenFn } = useMyRequest(getDataFileToken, {
onSuccess: (res: any) => {
console.log(res);
setFileToken(res.data);
},
});
useEffect(() => {
getPublicProjectFn();
}, [getPublicProjectFn]);
useEffect(() => {
getPublicEnvFn({ taskType });
}, [getPublicEnvFn, taskType]);
const handleNameChange = (e: any) => { const handleNameChange = (e: any) => {
console.log(e); console.log(e);
...@@ -39,12 +164,18 @@ const AddEnvironment = (props: IAddEnvironmentProps) => { ...@@ -39,12 +164,18 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
<div className={style.label}> <div className={style.label}>
环境名称<span className={style.required}>*</span> 环境名称<span className={style.required}>*</span>
</div> </div>
<div className={style.formItem}> <div
className={classNames({
[style.formItem]: true,
[style.formItemHaveHelperText]: nameHelper.text,
})}
>
<MyInput <MyInput
value={name} value={name}
onChange={handleNameChange} onChange={handleNameChange}
error={nameHelper.error} error={nameHelper.error}
helperText={nameHelper.text} helperText={nameHelper.text}
placeholder="给环境起个名称"
></MyInput> ></MyInput>
</div> </div>
<div className={style.label}> <div className={style.label}>
...@@ -54,7 +185,7 @@ const AddEnvironment = (props: IAddEnvironmentProps) => { ...@@ -54,7 +185,7 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
<MyInput <MyInput
value={desc} value={desc}
id="desc" id="desc"
label="项目描述" // label="项目描述"
multiline multiline
rows={4} rows={4}
placeholder="请输入项目描述" placeholder="请输入项目描述"
...@@ -77,17 +208,23 @@ const AddEnvironment = (props: IAddEnvironmentProps) => { ...@@ -77,17 +208,23 @@ const AddEnvironment = (props: IAddEnvironmentProps) => {
</div> </div>
<div className={style.formItem}> <div className={style.formItem}>
<MySelect <MySelect
options={[]} options={envList}
fullWidth fullWidth
placeholder="请选择基础环境"
value={baseEnvId} value={baseEnvId}
></MySelect> ></MySelect>
</div> </div>
<div className={style.label}> <div className={style.label}>
上传环境压缩包<span className={style.zipText}>(.zip)</span> 上传环境压缩包<span className={style.zipText}>(.zip)</span>
<span className={style.required}>*</span> <span className={style.required}>*</span>
<span className={style.download}>下载模板</span>
</div>
<div className={style.formItem}>
<div className={style.uploadBox} {...getRootProps()}>
<input {...getInputProps()} />
<span>点击选择环境包或将文件</span>
<span>拖到此处上传</span>
</div>
</div> </div>
<div className={style.formItem}>uploader</div>
</div> </div>
<div className={style.codeBox}> <div className={style.codeBox}>
<div className={style.codeTitle}> <div className={style.codeTitle}>
......
...@@ -7,7 +7,7 @@ import MyButton from "@/components/mui/MyButton"; ...@@ -7,7 +7,7 @@ import MyButton from "@/components/mui/MyButton";
import AddEnvironment from "./AddEnvironment"; import AddEnvironment from "./AddEnvironment";
const UserResourcesEnvironment = () => { const UserResourcesEnvironment = () => {
const [addOpen, setAddopen] = useState(false); const [addOpen, setAddopen] = useState(true);
return ( return (
<div className={style.environment}> <div className={style.environment}>
<div className={style.top}> <div className={style.top}>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment