mirror of
https://github.com/cloudreve/frontend.git
synced 2025-12-31 18:22:53 +00:00
七牛存储策略添加
This commit is contained in:
parent
197a46e146
commit
67a6f3faab
|
|
@ -7,10 +7,12 @@ import Select from "@material-ui/core/Select";
|
|||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import {useDispatch} from "react-redux";
|
||||
import {toggleSnackbar} from "../../../actions";
|
||||
import FormHelperText from "@material-ui/core/FormHelperText";
|
||||
|
||||
export default function DomainInput({onChange,value,required,label}){
|
||||
const [domain,setDomain] = useState("");
|
||||
const [protocol,setProtocol] = useState("https://");
|
||||
const [error,setError] = useState();
|
||||
|
||||
useState(()=>{
|
||||
if (value.startsWith("https://")){
|
||||
|
|
@ -22,12 +24,21 @@ export default function DomainInput({onChange,value,required,label}){
|
|||
}
|
||||
},[value]);
|
||||
|
||||
useEffect(()=>{
|
||||
if(protocol === "http://" && window.location.protocol === "https:"){
|
||||
setError("您当前站点启用了 HTTPS ,此处选择 HTTP 可能会导致无法连接。")
|
||||
}else{
|
||||
setError("")
|
||||
}
|
||||
},[protocol])
|
||||
|
||||
return (
|
||||
<FormControl>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
{label}
|
||||
</InputLabel>
|
||||
<Input
|
||||
error={error !== ""}
|
||||
value={domain}
|
||||
onChange={e=>{
|
||||
setDomain(e.target.value);
|
||||
|
|
@ -59,6 +70,7 @@ export default function DomainInput({onChange,value,required,label}){
|
|||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
{error !== "" && <FormHelperText error={error !== ""}>{error}</FormHelperText>}
|
||||
</FormControl>
|
||||
)
|
||||
}
|
||||
|
|
@ -47,22 +47,27 @@ const policies = [
|
|||
{
|
||||
name:"七牛",
|
||||
img:"qiniu.png",
|
||||
path:"/admin/policy/add/qiniu",
|
||||
},
|
||||
{
|
||||
name:"阿里云 OSS",
|
||||
img:"oss.png",
|
||||
path:"/admin/policy/add/soo",
|
||||
},
|
||||
{
|
||||
name:"又拍云",
|
||||
img:"upyun.png",
|
||||
path:"/admin/policy/add/upyun",
|
||||
},
|
||||
{
|
||||
name:"腾讯云 COS",
|
||||
img:"upyun.png",
|
||||
path:"/admin/policy/add/cos",
|
||||
},
|
||||
{
|
||||
name:"OneDrive",
|
||||
img:"onedrive.png",
|
||||
path:"/admin/policy/add/onedrive",
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import Paper from "@material-ui/core/Paper";
|
|||
import {useParams} from "react-router";
|
||||
import LocalGuide from "./Guid/LocalGuide";
|
||||
import RemoteGuide from "./Guid/RemoteGuide";
|
||||
import QiniuGuide from "./Guid/QiniuGuide";
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
|
|
@ -29,6 +30,7 @@ export default function AddPolicyParent( ) {
|
|||
<Paper square className={classes.content}>
|
||||
{type==="local"&&<LocalGuide/>}
|
||||
{type==="remote"&&<RemoteGuide/>}
|
||||
{type==="qiniu"&&<QiniuGuide/>}
|
||||
</Paper>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,972 @@
|
|||
import { lighten, makeStyles } from "@material-ui/core/styles";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import Stepper from "@material-ui/core/Stepper";
|
||||
import StepLabel from "@material-ui/core/StepLabel";
|
||||
import Step from "@material-ui/core/Step";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { changeSubTitle, toggleSnackbar } from "../../../../actions";
|
||||
import Link from "@material-ui/core/Link";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import Input from "@material-ui/core/Input";
|
||||
import RadioGroup from "@material-ui/core/RadioGroup";
|
||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||
import Radio from "@material-ui/core/Radio";
|
||||
import Collapse from "@material-ui/core/Collapse";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import API from "../../../../middleware/Api";
|
||||
import MagicVar from "../../Dialogs/MagicVar";
|
||||
import DomainInput from "../../Common/DomainInput";
|
||||
import SizeInput from "../../Common/SizeInput";
|
||||
import { useHistory } from "react-router";
|
||||
import Alert from "@material-ui/lab/Alert";
|
||||
import {getNumber, randomStr} from "../../../../untils";
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
stepContent: {
|
||||
padding: "16px 32px 16px 32px"
|
||||
},
|
||||
form: {
|
||||
maxWidth: 400,
|
||||
marginTop: 20
|
||||
},
|
||||
formContainer: {
|
||||
[theme.breakpoints.up("md")]: {
|
||||
padding: "0px 24px 0 24px"
|
||||
}
|
||||
},
|
||||
subStepContainer: {
|
||||
display: "flex",
|
||||
marginBottom: 20,
|
||||
padding: 10,
|
||||
transition: theme.transitions.create("background-color", {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.leavingScreen
|
||||
}),
|
||||
"&:focus-within": {
|
||||
backgroundColor: theme.palette.background.default
|
||||
}
|
||||
},
|
||||
stepNumber: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
backgroundColor: lighten(theme.palette.secondary.light, 0.2),
|
||||
color: theme.palette.secondary.contrastText,
|
||||
textAlign: "center",
|
||||
borderRadius: " 50%"
|
||||
},
|
||||
stepNumberContainer: {
|
||||
marginRight: 10
|
||||
},
|
||||
stepFooter: {
|
||||
marginTop: 32
|
||||
},
|
||||
button: {
|
||||
marginRight: theme.spacing(1)
|
||||
}
|
||||
}));
|
||||
|
||||
const steps = [
|
||||
{
|
||||
title: "存储空间",
|
||||
optional: false
|
||||
},
|
||||
{
|
||||
title: "上传路径",
|
||||
optional: false
|
||||
},
|
||||
{
|
||||
title: "直链设置",
|
||||
optional: false
|
||||
},
|
||||
{
|
||||
title: "上传限制",
|
||||
optional: false
|
||||
},
|
||||
{
|
||||
title: "完成",
|
||||
optional: false
|
||||
}
|
||||
];
|
||||
|
||||
export default function RemoteGuide() {
|
||||
const classes = useStyles();
|
||||
const history = useHistory();
|
||||
|
||||
const [activeStep, setActiveStep] = useState(0);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [skipped, setSkipped] = React.useState(new Set());
|
||||
const [magicVar, setMagicVar] = useState("");
|
||||
const [useCDN, setUseCDN] = useState("false");
|
||||
const [policy, setPolicy] = useState({
|
||||
Type: "qiniu",
|
||||
Name: "",
|
||||
SecretKey: "",
|
||||
AccessKey: "",
|
||||
BaseURL: "",
|
||||
IsPrivate: "true",
|
||||
DirNameRule: "uploads/{year}/{month}/{day}",
|
||||
AutoRename: "true",
|
||||
FileNameRule: "{randomkey8}_{originname}",
|
||||
IsOriginLinkEnable: "false",
|
||||
MaxSize: "0",
|
||||
OptionsSerialized: {
|
||||
file_type: "",
|
||||
mimetype:"",
|
||||
}
|
||||
});
|
||||
|
||||
const handleChange = name => event => {
|
||||
setPolicy({
|
||||
...policy,
|
||||
[name]: event.target.value
|
||||
});
|
||||
};
|
||||
|
||||
const handleOptionChange = name => event => {
|
||||
setPolicy({
|
||||
...policy,
|
||||
OptionsSerialized: {
|
||||
...policy.OptionsSerialized,
|
||||
[name]: event.target.value
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isStepSkipped = step => {
|
||||
return skipped.has(step);
|
||||
};
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const ToggleSnackbar = useCallback(
|
||||
(vertical, horizontal, msg, color) =>
|
||||
dispatch(toggleSnackbar(vertical, horizontal, msg, color)),
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const testSlave = () => {
|
||||
setLoading(true);
|
||||
|
||||
// 测试路径是否可用
|
||||
API.post("/admin/policy/test/slave", {
|
||||
server: policy.Server,
|
||||
secret: policy.SecretKey
|
||||
})
|
||||
.then(response => {
|
||||
ToggleSnackbar("top", "right", "通信正常", "success");
|
||||
})
|
||||
.catch(error => {
|
||||
ToggleSnackbar("top", "right", error.message, "error");
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const submitPolicy = e => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
|
||||
let policyCopy = { ...policy };
|
||||
policyCopy.OptionsSerialized = { ...policyCopy.OptionsSerialized };
|
||||
|
||||
// 类型转换
|
||||
policyCopy.AutoRename = policyCopy.AutoRename === "true";
|
||||
policyCopy.IsOriginLinkEnable =
|
||||
policyCopy.IsOriginLinkEnable === "true";
|
||||
policyCopy.IsPrivate = policyCopy.IsPrivate === "true";
|
||||
policyCopy.MaxSize = parseInt(policyCopy.MaxSize);
|
||||
policyCopy.OptionsSerialized.file_type = policyCopy.OptionsSerialized.file_type.split(
|
||||
","
|
||||
);
|
||||
if (
|
||||
policyCopy.OptionsSerialized.file_type.length === 1 &&
|
||||
policyCopy.OptionsSerialized.file_type[0] === ""
|
||||
) {
|
||||
policyCopy.OptionsSerialized.file_type = [];
|
||||
}
|
||||
|
||||
API.post("/admin/policy", {
|
||||
policy: policyCopy
|
||||
})
|
||||
.then(response => {
|
||||
ToggleSnackbar("top", "right", "存储策略已添加", "success");
|
||||
setActiveStep(5);
|
||||
})
|
||||
.catch(error => {
|
||||
ToggleSnackbar("top", "right", error.message, "error");
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography variant={"h6"}>添加七牛存储策略</Typography>
|
||||
<Stepper activeStep={activeStep}>
|
||||
{steps.map((label, index) => {
|
||||
const stepProps = {};
|
||||
const labelProps = {};
|
||||
if (label.optional) {
|
||||
labelProps.optional = (
|
||||
<Typography variant="caption">可选</Typography>
|
||||
);
|
||||
}
|
||||
if (isStepSkipped(index)) {
|
||||
stepProps.completed = false;
|
||||
}
|
||||
return (
|
||||
<Step key={label.title} {...stepProps}>
|
||||
<StepLabel {...labelProps}>{label.title}</StepLabel>
|
||||
</Step>
|
||||
);
|
||||
})}
|
||||
</Stepper>
|
||||
|
||||
{activeStep === 0 && (
|
||||
<form
|
||||
className={classes.stepContent}
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
setActiveStep(1);
|
||||
}}
|
||||
>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>0</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
在使用七牛存储策略前,请确保您在 参数设置 - 站点信息
|
||||
- 站点URL 中填写的 地址与实际相符,并且
|
||||
<strong>能够被外网正常访问</strong>。
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>1</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
前往
|
||||
<Link
|
||||
href={"https://portal.qiniu.com/create"}
|
||||
target={"_blank"}
|
||||
>
|
||||
七牛控制面板
|
||||
</Link>
|
||||
创建对象存储资源。
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>2</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
在下方填写您在七牛创建存储空间时指定的“存储空间名称”:
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
存储空间名称
|
||||
</InputLabel>
|
||||
<Input
|
||||
required
|
||||
value={policy.BucketName}
|
||||
onChange={handleChange("BucketName")}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>3</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
在下方选择您创建的空间类型,推荐选择“私有空间”以获得更高的安全性,私有空间无法开启“获取直链”功能。
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl required component="fieldset">
|
||||
<RadioGroup
|
||||
required
|
||||
value={policy.IsPrivate}
|
||||
onChange={handleChange("IsPrivate")}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value={"true"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="私有"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={"false"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="公有"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>4</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
填写您为存储空间绑定的 CDN 加速域名。
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<DomainInput
|
||||
value={policy.BaseURL}
|
||||
onChange={handleChange("BaseURL")}
|
||||
required
|
||||
label={"CDN 加速域名"}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>5</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
在七牛控制面板进入 个人中心 -
|
||||
密钥管理,在下方填写获得到的 AK、SK。
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
AK
|
||||
</InputLabel>
|
||||
<Input
|
||||
required
|
||||
value={policy.AccessKey}
|
||||
onChange={handleChange("AccessKey")}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
SK
|
||||
</InputLabel>
|
||||
<Input
|
||||
required
|
||||
value={policy.SecretKey}
|
||||
onChange={handleChange("SecretKey")}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.stepFooter}>
|
||||
<Button
|
||||
disabled={loading}
|
||||
type={"submit"}
|
||||
variant={"contained"}
|
||||
color={"primary"}
|
||||
>
|
||||
下一步
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{activeStep === 1 && (
|
||||
<form
|
||||
className={classes.stepContent}
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
setActiveStep(2);
|
||||
}}
|
||||
>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>1</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
请在下方输入文件的存储目录路径,可以为绝对路径或相对路径(相对于
|
||||
从机的
|
||||
Cloudreve)。路径中可以使用魔法变量,文件在上传时会自动替换这些变量为相应值;
|
||||
可用魔法变量可参考{" "}
|
||||
<Link
|
||||
color={"secondary"}
|
||||
href={"javascript:void()"}
|
||||
onClick={() => setMagicVar("path")}
|
||||
>
|
||||
路径魔法变量列表
|
||||
</Link>{" "}
|
||||
。
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
存储目录
|
||||
</InputLabel>
|
||||
<Input
|
||||
required
|
||||
value={policy.DirNameRule}
|
||||
onChange={handleChange("DirNameRule")}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>2</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
是否需要对存储的物理文件进行重命名?此处的重命名不会影响最终呈现给用户的
|
||||
文件名。文件名也可使用魔法变量,
|
||||
可用魔法变量可参考{" "}
|
||||
<Link
|
||||
color={"secondary"}
|
||||
href={"javascript:void()"}
|
||||
onClick={() => setMagicVar("file")}
|
||||
>
|
||||
文件名魔法变量列表
|
||||
</Link>{" "}
|
||||
。
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl required component="fieldset">
|
||||
<RadioGroup
|
||||
aria-label="gender"
|
||||
name="gender1"
|
||||
value={policy.AutoRename}
|
||||
onChange={handleChange("AutoRename")}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value={"true"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="开启重命名"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={"false"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="不开启"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
|
||||
<Collapse in={policy.AutoRename === "true"}>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
命名规则
|
||||
</InputLabel>
|
||||
<Input
|
||||
required={
|
||||
policy.AutoRename === "true"
|
||||
}
|
||||
value={policy.FileNameRule}
|
||||
onChange={handleChange(
|
||||
"FileNameRule"
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</Collapse>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.stepFooter}>
|
||||
<Button
|
||||
color={"default"}
|
||||
className={classes.button}
|
||||
onClick={() => setActiveStep(0)}
|
||||
>
|
||||
上一步
|
||||
</Button>
|
||||
<Button
|
||||
disabled={loading}
|
||||
type={"submit"}
|
||||
variant={"contained"}
|
||||
color={"primary"}
|
||||
>
|
||||
下一步
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{activeStep === 2 && (
|
||||
<form
|
||||
className={classes.stepContent}
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
setActiveStep(3);
|
||||
}}
|
||||
>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>1</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
是否允许获取文件永久直链?
|
||||
<br />
|
||||
开启后,用户可以请求获得能直接访问到文件内容的直链,适用于图床应用或自用。
|
||||
</Typography>
|
||||
|
||||
<div className={classes.form}>
|
||||
<FormControl required component="fieldset">
|
||||
<RadioGroup
|
||||
required
|
||||
value={policy.IsOriginLinkEnable}
|
||||
onChange={e=>{
|
||||
if (policy.IsPrivate === "true" && e.target.value==="true"){
|
||||
ToggleSnackbar("top", "right","私有空间无法开启此功能", "warning");
|
||||
return
|
||||
}
|
||||
handleChange(
|
||||
"IsOriginLinkEnable"
|
||||
)(e)
|
||||
}}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value={"true"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="允许"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={"false"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="禁止"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.stepFooter}>
|
||||
<Button
|
||||
color={"default"}
|
||||
className={classes.button}
|
||||
onClick={() => setActiveStep(1)}
|
||||
>
|
||||
上一步
|
||||
</Button>{" "}
|
||||
<Button
|
||||
disabled={loading}
|
||||
type={"submit"}
|
||||
variant={"contained"}
|
||||
color={"primary"}
|
||||
>
|
||||
下一步
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{activeStep === 3 && (
|
||||
<form
|
||||
className={classes.stepContent}
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
setActiveStep(4);
|
||||
}}
|
||||
>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>1</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
是否限制上传的单文件大小?
|
||||
</Typography>
|
||||
|
||||
<div className={classes.form}>
|
||||
<FormControl required component="fieldset">
|
||||
<RadioGroup
|
||||
required
|
||||
value={
|
||||
policy.MaxSize === "0"
|
||||
? "false"
|
||||
: "true"
|
||||
}
|
||||
onChange={e => {
|
||||
if (e.target.value === "true") {
|
||||
setPolicy({
|
||||
...policy,
|
||||
MaxSize: "10485760"
|
||||
});
|
||||
} else {
|
||||
setPolicy({
|
||||
...policy,
|
||||
MaxSize: "0"
|
||||
});
|
||||
}
|
||||
}}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value={"true"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="限制"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={"false"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="不限制"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Collapse in={policy.MaxSize !== "0"}>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>2</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
输入限制:
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<SizeInput
|
||||
value={policy.MaxSize}
|
||||
onChange={handleChange("MaxSize")}
|
||||
min={0}
|
||||
max={9223372036854775807}
|
||||
label={"单文件大小限制"}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>
|
||||
{policy.MaxSize !== "0" ? "3" : "2"}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
是否限制上传文件扩展名?
|
||||
</Typography>
|
||||
|
||||
<div className={classes.form}>
|
||||
<FormControl required component="fieldset">
|
||||
<RadioGroup
|
||||
required
|
||||
value={
|
||||
policy.OptionsSerialized
|
||||
.file_type === ""
|
||||
? "false"
|
||||
: "true"
|
||||
}
|
||||
onChange={e => {
|
||||
if (e.target.value === "true") {
|
||||
setPolicy({
|
||||
...policy,
|
||||
OptionsSerialized: {
|
||||
...policy.OptionsSerialized,
|
||||
file_type:
|
||||
"jpg,png,mp4,zip,rar"
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setPolicy({
|
||||
...policy,
|
||||
OptionsSerialized: {
|
||||
...policy.OptionsSerialized,
|
||||
file_type: ""
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value={"true"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="限制"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={"false"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="不限制"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Collapse in={policy.OptionsSerialized.file_type !== ""}>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>
|
||||
{policy.MaxSize !== "0" ? "4" : "3"}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
输入允许上传的文件扩展名,多个请以半角逗号 ,
|
||||
隔开
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
扩展名列表
|
||||
</InputLabel>
|
||||
<Input
|
||||
value={
|
||||
policy.OptionsSerialized
|
||||
.file_type
|
||||
}
|
||||
onChange={handleOptionChange(
|
||||
"file_type"
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>
|
||||
{getNumber(3,[
|
||||
policy.MaxSize !== "0",
|
||||
policy.OptionsSerialized.file_type !== "",
|
||||
])}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
是否限制上传文件 MimeType?
|
||||
</Typography>
|
||||
|
||||
<div className={classes.form}>
|
||||
<FormControl required component="fieldset">
|
||||
<RadioGroup
|
||||
required
|
||||
value={
|
||||
policy.OptionsSerialized
|
||||
.mimetype === ""
|
||||
? "false"
|
||||
: "true"
|
||||
}
|
||||
onChange={e => {
|
||||
if (e.target.value === "true") {
|
||||
setPolicy({
|
||||
...policy,
|
||||
OptionsSerialized: {
|
||||
...policy.OptionsSerialized,
|
||||
mimetype:
|
||||
"image/*"
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setPolicy({
|
||||
...policy,
|
||||
OptionsSerialized: {
|
||||
...policy.OptionsSerialized,
|
||||
mimetype: ""
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value={"true"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="限制"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={"false"}
|
||||
control={
|
||||
<Radio color={"primary"} />
|
||||
}
|
||||
label="不限制"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Collapse in={policy.OptionsSerialized.mimetype !== ""}>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}>
|
||||
<div className={classes.stepNumber}>
|
||||
{getNumber(4,[
|
||||
policy.MaxSize !== "0",
|
||||
policy.OptionsSerialized.file_type !== "",
|
||||
])}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
输入允许上传的 MimeType,多个请以半角逗号 ,
|
||||
隔开。七牛服务器会侦测文件内容以判断 MimeType,再用判断值跟指定值进行匹配,匹配成功则允许上传
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
MimeType 列表
|
||||
</InputLabel>
|
||||
<Input
|
||||
value={
|
||||
policy.OptionsSerialized
|
||||
.mimetype
|
||||
}
|
||||
onChange={handleOptionChange(
|
||||
"mimetype"
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Collapse>
|
||||
|
||||
<div className={classes.stepFooter}>
|
||||
<Button
|
||||
color={"default"}
|
||||
className={classes.button}
|
||||
onClick={() => setActiveStep(2)}
|
||||
>
|
||||
上一步
|
||||
</Button>{" "}
|
||||
<Button
|
||||
disabled={loading}
|
||||
type={"submit"}
|
||||
variant={"contained"}
|
||||
color={"primary"}
|
||||
>
|
||||
下一步
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{activeStep === 4 && (
|
||||
<form className={classes.stepContent} onSubmit={submitPolicy}>
|
||||
<div className={classes.subStepContainer}>
|
||||
<div className={classes.stepNumberContainer}></div>
|
||||
<div className={classes.subStepContent}>
|
||||
<Typography variant={"body2"}>
|
||||
最后一步,为此存储策略命名:
|
||||
</Typography>
|
||||
<div className={classes.form}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor="component-helper">
|
||||
存储策略名
|
||||
</InputLabel>
|
||||
<Input
|
||||
required
|
||||
value={policy.Name}
|
||||
onChange={handleChange("Name")}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.stepFooter}>
|
||||
<Button
|
||||
color={"default"}
|
||||
className={classes.button}
|
||||
onClick={() => setActiveStep(3)}
|
||||
>
|
||||
上一步
|
||||
</Button>{" "}
|
||||
<Button
|
||||
disabled={loading}
|
||||
type={"submit"}
|
||||
variant={"contained"}
|
||||
color={"primary"}
|
||||
>
|
||||
完成
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
{activeStep === 5 && (
|
||||
<>
|
||||
<form className={classes.stepContent}>
|
||||
<Typography>存储策略已添加!</Typography>
|
||||
<Typography variant={"body2"} color={"textSecondary"}>
|
||||
要使用此存储策略,请到用户组管理页面,为相应用户组绑定此存储策略。
|
||||
</Typography>
|
||||
</form>
|
||||
<div className={classes.stepFooter}>
|
||||
<Button
|
||||
color={"primary"}
|
||||
className={classes.button}
|
||||
onClick={() => history.push("/admin/policy")}
|
||||
>
|
||||
返回存储策略列表
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<MagicVar
|
||||
open={magicVar === "file"}
|
||||
isFile
|
||||
onClose={() => setMagicVar("")}
|
||||
/>
|
||||
<MagicVar
|
||||
open={magicVar === "path"}
|
||||
onClose={() => setMagicVar("")}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -179,4 +179,13 @@ export function randomStr(length) {
|
|||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getNumber(base,conditions){
|
||||
conditions.forEach(v=>{
|
||||
if(v){
|
||||
base++
|
||||
}
|
||||
})
|
||||
return base
|
||||
}
|
||||
Loading…
Reference in New Issue