preference scan edit complete

This commit is contained in:
Simba
2020-07-12 01:59:32 +08:00
parent b0029661e0
commit 00429b1f73
11 changed files with 439 additions and 46 deletions
+11 -1
View File
@@ -187,7 +187,17 @@ let LangEn = {
engineRegPlaceHolder: "eghttps://xxx.xxx.xxx?url={url}",
engineSuffixPlaceHolder: "suffix can not be null, split by comma, look like: doc,ppt,xls",
previewCurrent: "preview in current page",
previewOpen: "preview in new page"
previewOpen: "preview in new page",
editScan: "Edit Scan disk",
enableScan: "Enable Scan disk",
disabledScan: "Disabled Scan disk",
scanCron: "Regularly Scan disk",
cron: "Cron expression",
cronValidate: "Cron expression can not be null",
scanScope: "Scan scope",
scanUsers: "Scan users",
chooseUsers: "Fuzzy search users",
chooseUsersValidate: "choose one more user"
},
share: {
shareDetail: "Share Detail",
+10
View File
@@ -189,6 +189,16 @@ let LangZh = {
engineSuffixPlaceHolder: '输入后缀,使用逗号分隔,不用带. 例如:doc,ppt,xls',
previewCurrent: "本站预览",
previewOpen: "新标签打开",
editScan: "设置磁盘扫描",
enableScan: "开启磁盘扫描",
disabledScan: "暂未开启磁盘扫描",
scanCron: "定时扫描",
cron: "cron表达式",
cronValidate: "cron表达式不能为空",
scanScope: "扫描范围",
scanUsers: "扫描用户",
chooseUsers: "模糊搜索用户",
chooseUsersValidate: "请选择至少一个用户"
},
share: {
shareDetail: "分享详情",
+19 -2
View File
@@ -2,6 +2,7 @@ import SafeUtil from '../../util/SafeUtil';
import BaseEntity from '../base/BaseEntity';
import PreviewConfig from "./model/PreviewConfig";
import JsonUtil from "../../util/JsonUtil";
import ScanConfig from "./model/ScanConfig";
export default class Preference extends BaseEntity {
@@ -10,6 +11,8 @@ export default class Preference extends BaseEntity {
static URL_API_PREFERENCE_FETCH = '/api/preference/fetch'
static URL_API_SYSTEM_CLEANUP = '/api/preference/system/cleanup'
static URL_API_PREFERENCE_EDIT_PREVIEW_CONFIG = '/api/preference/edit/preview/config'
static URL_API_PREFERENCE_EDIT_SCAN = '/api/preference/edit/scan/config'
//网站名称
name: string = ""
@@ -32,6 +35,8 @@ export default class Preference extends BaseEntity {
allowRegister: boolean = false
//预览配置
previewConfig: PreviewConfig = new PreviewConfig()
//扫描磁盘配置
scanConfig: ScanConfig = new ScanConfig()
//后台版本
version: string | null = null
@@ -51,7 +56,7 @@ export default class Preference extends BaseEntity {
super.assign(obj);
this.assignEntity("previewConfig", PreviewConfig)
this.assignEntity("scanConfig", ScanConfig)
}
getForm(): any {
@@ -65,7 +70,8 @@ export default class Preference extends BaseEntity {
downloadDirMaxSize: this.downloadDirMaxSize,
defaultTotalSizeLimit: this.defaultTotalSizeLimit,
allowRegister: this.allowRegister,
previewConfig: JsonUtil.toJson(this.previewConfig.getForm())
previewConfig: JsonUtil.toJson(this.previewConfig.getForm()),
scanConfig: JsonUtil.toJson(this.scanConfig.getForm())
};
}
@@ -120,6 +126,17 @@ export default class Preference extends BaseEntity {
}
httpSaveScan(successCallback?: any, errorCallback?: any, finalCallback?: any) {
const that = this
this.httpPost(Preference.URL_API_PREFERENCE_EDIT_SCAN, this.getForm(), function(response: any) {
that.assign(response.data.data);
SafeUtil.safeCallback(successCallback)(response);
}, errorCallback, finalCallback);
}
}
@@ -0,0 +1,40 @@
/**
* 扫描配置
*/
import { LabeledValue } from 'antd/lib/select';
import Base from "../../base/Base";
import { ScanScopeType } from "./ScanScopeType";
import { ScanCronType } from "./ScanCronType";
export default class ScanConfig extends Base {
// 是否开启
enable: boolean = false;
// cron表达式 定时任务用
cron: string | null = null;
// 扫描磁盘开启范围(全部用户 or 局部用户)
scope: ScanScopeType = ScanScopeType.ALL;
// 开启扫描磁盘功能的用户们
usernames: string[] = [];
// 前端辅助字段
cronType: string | null = null;
users: LabeledValue[] = [];
constructor() {
super();
}
assign(obj: any) {
super.assign(obj);
}
getForm(): any {
return {
enable: this.enable,
scope: this.scope,
cron: this.cronType === ScanCronType.CUSTOM ? this.cron : this.cronType,
usernames: this.usernames,
};
}
}
@@ -0,0 +1,48 @@
import SelectionOption from "../../base/option/SelectionOption";
enum ScanCronType {
TEN_SECONDS = "TEN_SECONDS",
THIRTY_SECONDS = "THIRTY_SECONDS",
MINUTE = "MINUTE",
HOUR = "HOUR",
CUSTOM = "CUSTOM",
}
const ScanCronTypes: ScanCronType[] = Object.keys(ScanCronType).map(
(k) => k as ScanCronType
);
const ScanCronTypeMap: { [key in keyof typeof ScanCronType]: SelectionOption } = {
TEN_SECONDS: {
name: "每十秒",
value: "@every 10s",
},
THIRTY_SECONDS: {
name: "每三十秒",
value: "@every 30s",
},
MINUTE: {
name: "每分钟",
value: "@every 1m",
},
HOUR: {
name: "每小时",
value: "0 * * * *",
},
CUSTOM: {
name: "自定义",
value: "CUSTOM",
},
};
const ScanCronTypeList: SelectionOption[] = [];
ScanCronTypes.forEach((type: ScanCronType) => {
ScanCronTypeList.push(ScanCronTypeMap[type]);
});
const ScanCronTypeValueList: string[] = [];
ScanCronTypes.forEach((type: ScanCronType) => {
ScanCronTypeValueList.push(ScanCronTypeMap[type].value);
});
export { ScanCronType, ScanCronTypeMap, ScanCronTypeList, ScanCronTypeValueList };
@@ -0,0 +1,28 @@
import SelectionOption from "../../base/option/SelectionOption";
enum ScanScopeType {
ALL = "ALL",
CUSTOM = "CUSTOM",
}
const ScanScopeTypes: ScanScopeType[] = Object.keys(ScanScopeType).map(
(k) => k as ScanScopeType
);
const ScanScopeTypeMap: { [key in keyof typeof ScanScopeType]: SelectionOption } = {
ALL: {
name: "全部用户",
value: "ALL",
},
CUSTOM: {
name: "局部用户",
value: "CUSTOM",
},
};
let ScanScopeTypeList: SelectionOption[] = [];
ScanScopeTypes.forEach((type: ScanScopeType) => {
ScanScopeTypeList.push(ScanScopeTypeMap[type]);
});
export { ScanScopeType, ScanScopeTypeMap, ScanScopeTypeList };
+2
View File
@@ -15,6 +15,7 @@ import UserAuthentication from './user/Authentication';
import PreferenceIndex from './preference/Index';
import PreferenceEdit from './preference/Edit';
import PreferenceEngineEdit from './preference/PreviewEngineEdit';
import PreferenceScanEdit from './preference/ScanEdit';
import DashboardIndex from './dashboard/Index';
import InstallIndex from './install/Index';
@@ -141,6 +142,7 @@ class RawFrame extends TankComponent<IProps, IState> {
<Route path="/preference/index" component={PreferenceIndex}/>
<Route path="/preference/edit" component={PreferenceEdit}/>
<Route path="/preference/engine/edit" component={PreferenceEngineEdit}/>
<Route path="/preference/scan/edit" component={PreferenceScanEdit}/>
<Route path="/matter/detail/:uuid" component={MatterDetail}/>
<Route exact path="/matter" render={() =>
+65 -42
View File
@@ -5,7 +5,7 @@ import TankComponent from "../../common/component/TankComponent";
import User from "../../common/model/user/User";
import Moon from "../../common/model/global/Moon";
import TankTitle from "../widget/TankTitle";
import { Button, Tooltip, Tag, Divider, Empty } from "antd";
import { Button, Divider, Empty, Tag, Tooltip } from "antd";
import { EditOutlined, ThunderboltOutlined } from "@ant-design/icons";
import InfoCell from "../widget/InfoCell";
import Preference from "../../common/model/preference/Preference";
@@ -15,6 +15,10 @@ import ImagePreviewer from "../widget/previewer/ImagePreviewer";
import Lang from "../../common/model/global/Lang";
import SingleTextModal from "../widget/SingleTextModal";
import MessageBoxUtil from "../../common/util/MessageBoxUtil";
import {
ScanScopeType,
ScanScopeTypeMap,
} from "../../common/model/preference/model/ScanScopeType";
interface IProps extends RouteComponentProps {}
@@ -60,7 +64,11 @@ export default class Index extends TankComponent<IProps, IState> {
}
render() {
const { previewEngines } = this.preference.previewConfig;
const {
previewConfig: { previewEngines },
scanConfig,
} = this.preference;
console.log(scanConfig);
return (
<div className="page-preference-index">
@@ -77,7 +85,6 @@ export default class Index extends TankComponent<IProps, IState> {
</TankTitle>
<TankContentCard>
<div className="basic-info">
<header>
<p className="title">{Lang.t("preference.basic")}</p>
@@ -118,15 +125,15 @@ export default class Index extends TankComponent<IProps, IState> {
</InfoCell>
<InfoCell name={Lang.t("preference.copyright")}>
<span
dangerouslySetInnerHTML={{ __html: this.preference.copyright }}
/>
<span
dangerouslySetInnerHTML={{ __html: this.preference.copyright }}
/>
</InfoCell>
<InfoCell name={Lang.t("preference.extraInfo")}>
<span
dangerouslySetInnerHTML={{ __html: this.preference.record }}
/>
<span
dangerouslySetInnerHTML={{ __html: this.preference.record }}
/>
</InfoCell>
<InfoCell name={Lang.t("preference.zipMaxNumLimit")}>
@@ -158,40 +165,39 @@ export default class Index extends TankComponent<IProps, IState> {
<div className="preview-info">
<header>
<p className="title">
{Lang.t("preference.preview")}
</p>
<p className="title">{Lang.t("preference.preview")}</p>
<Link to={"/preference/engine/edit"}>
<Button type={"primary"} icon={<EditOutlined />}>
{Lang.t("edit")}
</Button>
</Link>
</header>
<div className="content">
{
previewEngines.length ? previewEngines.map((engines, index) => (
{previewEngines.length ? (
previewEngines.map((engines, index) => (
<div key={index} className="relative mb10 engine-box">
<Tooltip title={Lang.t("preference.enginePreview")}>
{engines.previewInSite ? (
<Tag className="preview-tip" color="warning">
{Lang.t("preference.previewCurrent")}
</Tag>
) : (
<Tag className="preview-tip" color="success">
{Lang.t("preference.previewOpen")}
</Tag>
)}
</Tooltip>
<InfoCell name={Lang.t("preference.engineReg")}>
{engines.url}
</InfoCell>
<InfoCell name={Lang.t("preference.engineSuffix")}>
{engines.extensions}
</InfoCell>
<Tooltip title={Lang.t("preference.enginePreview")}>
{engines.previewInSite ? (
<Tag className="preview-tip" color="warning">
{Lang.t("preference.previewCurrent")}
</Tag>
) : (
<Tag className="preview-tip" color="success">
{Lang.t("preference.previewOpen")}
</Tag>
)}
</Tooltip>
<InfoCell name={Lang.t("preference.engineReg")}>
{engines.url}
</InfoCell>
<InfoCell name={Lang.t("preference.engineSuffix")}>
{engines.extensions}
</InfoCell>
</div>
)) : <Empty description={Lang.t("preference.noEngine")} />
}
))
) : (
<Empty description={Lang.t("preference.noEngine")} />
)}
</div>
</div>
@@ -199,17 +205,34 @@ export default class Index extends TankComponent<IProps, IState> {
<div className="scan-info">
<header>
<p className="title">
{Lang.t("preference.scan")}
</p>
<Button type={"primary"} icon={<EditOutlined />}>
{Lang.t("edit")}
</Button>
<p className="title">{Lang.t("preference.scan")}</p>
<Link to={"/preference/scan/edit"}>
<Button type={"primary"} icon={<EditOutlined />}>
{Lang.t("edit")}
</Button>
</Link>
</header>
<div className="content">
{scanConfig.enable ? (
<>
<InfoCell name={Lang.t("preference.scanCron")}>
{scanConfig.cron}
</InfoCell>
<InfoCell name={Lang.t("preference.scanScope")}>
{ScanScopeTypeMap[scanConfig.scope].name}
</InfoCell>
{scanConfig.scope === ScanScopeType.CUSTOM && (
<InfoCell name={Lang.t("preference.scanUsers")}>
{scanConfig.usernames.join(", ")}
</InfoCell>
)}
</>
) : (
<Empty description={Lang.t("preference.disabledScan")} />
)}
</div>
</div>
</TankContentCard>
</div>
);
}
@@ -62,7 +62,6 @@ export default class PreviewEngineEdit extends TankComponent<IProps, IState> {
{...layout}
name="preview-engine"
ref={this.formRef}
initialValues={preference.getForm()}
onFinish={this.finish}
onValuesChange={this.updateUI}
>
View File
+216
View File
@@ -0,0 +1,216 @@
import React from "react";
import { RouteComponentProps } from "react-router-dom";
import "./ScanEdit.less";
import TankComponent from "../../common/component/TankComponent";
import Preference from "../../common/model/preference/Preference";
import Moon from "../../common/model/global/Moon";
import Lang from "../../common/model/global/Lang";
import TankTitle from "../widget/TankTitle";
import TankContentCard from "../widget/TankContentCard";
import { Button, Form, Input, Select, Spin, Switch } from "antd";
import { FormInstance } from "antd/lib/form";
import { SaveOutlined } from "@ant-design/icons";
import MessageBoxUtil from "../../common/util/MessageBoxUtil";
import Sun from "../../common/model/global/Sun";
import {
ScanScopeType,
ScanScopeTypeList,
} from "../../common/model/preference/model/ScanScopeType";
import {
ScanCronType,
ScanCronTypeList,
ScanCronTypeValueList,
} from "../../common/model/preference/model/ScanCronType";
import Pager from "../../common/model/base/Pager";
import User from "../../common/model/user/User";
import SortDirection from "../../common/model/base/SortDirection";
interface IProps extends RouteComponentProps {}
interface IState {}
export default class ScanEdit extends TankComponent<IProps, IState> {
formRef = React.createRef<FormInstance>();
preference: Preference = Moon.getSingleton().preference;
pager: Pager<User> = new Pager<User>(this, User, 10);
constructor(props: IProps) {
super(props);
this.preference.detailLoading = true;
}
componentDidMount() {
this.preference.httpFetch(() => {
this.preference.detailLoading = false;
// 给前端辅助字段赋值
this.preference.scanConfig.cronType = this.preference.scanConfig.cron;
if (
!ScanCronTypeValueList.includes(this.preference.scanConfig.cronType!)
) {
this.preference.scanConfig.cronType = ScanCronType.CUSTOM;
}
if (this.preference.scanConfig.scope !== ScanScopeType.ALL) {
this.preference.scanConfig.users = this.preference.scanConfig.usernames.map(
(name: string) => ({
label: name,
value: name,
})
);
}
this.updateUI();
});
}
finish = (values: any) => {
if (values.scope === ScanScopeType.ALL) {
this.preference.scanConfig.assign(values);
} else {
this.preference.scanConfig.assign({
...values,
usernames: values.users.map((item: any) => item.value),
});
}
this.preference.httpSaveScan(function () {
MessageBoxUtil.success(Lang.t("operationSuccess"));
Sun.updateFrame();
Sun.navigateTo("/preference/index");
});
};
changeEnableScan = (value: boolean) => {
this.preference.scanConfig.enable = value;
this.updateUI();
};
changeCronType = (value: ScanCronType) => {
this.preference.scanConfig.cronType = value;
this.updateUI();
};
changeScopeType = (value: ScanScopeType) => {
this.preference.scanConfig.scope = value;
this.updateUI();
};
fetchUser = (value: any) => {
this.pager.resetFilter();
this.pager.setFilterValue("orderCreateTime", SortDirection.DESC);
this.pager.setFilterValue("username", value);
this.pager.httpList();
};
render() {
const { preference, pager } = this;
const layout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};
return (
<div className="preference-scan-edit">
<TankTitle name={Lang.t("preference.editScan")} />
<TankContentCard loading={preference.detailLoading}>
<Form
{...layout}
name="preview-engine"
ref={this.formRef}
initialValues={preference.scanConfig}
onFinish={this.finish}
onValuesChange={() => this.updateUI}
>
<Form.Item
label={Lang.t("preference.enableScan")}
valuePropName="checked"
name="enable"
>
<Switch onChange={this.changeEnableScan} />
</Form.Item>
{preference.scanConfig.enable && (
<>
<Form.Item
label={Lang.t("preference.scanCron")}
name="cronType"
>
<Select onChange={this.changeCronType}>
{ScanCronTypeList.map((option) => (
<Select.Option key={option.value} value={option.value}>
{option.name}
</Select.Option>
))}
</Select>
</Form.Item>
{preference.scanConfig.cronType === ScanCronType.CUSTOM && (
<Form.Item
label={Lang.t("preference.cron")}
name="cron"
rules={[
{
required: true,
message: Lang.t("preference.cronValidate"),
},
]}
>
<Input />
</Form.Item>
)}
<Form.Item label={Lang.t("preference.scanScope")} name="scope">
<Select onChange={this.changeScopeType}>
{ScanScopeTypeList.map((option) => (
<Select.Option key={option.value} value={option.value}>
{option.name}
</Select.Option>
))}
</Select>
</Form.Item>
{preference.scanConfig.scope === ScanScopeType.CUSTOM && (
<Form.Item
label={Lang.t("preference.scanUsers")}
name="users"
rules={[
{
required: true,
message: Lang.t("preference.chooseUsersValidate"),
},
]}
>
<Select
mode="multiple"
labelInValue
placeholder={Lang.t("preference.chooseUsers")}
notFoundContent={
pager.loading ? <Spin size="small" /> : null
}
filterOption={false}
onSearch={this.fetchUser}
style={{ width: "100%" }}
>
{pager.data.map((user: User) => (
<Select.Option
key={user.username!}
value={user.username!}
>
{user.username}
</Select.Option>
))}
</Select>
</Form.Item>
)}
</>
)}
<div className="text-right">
<Button type="primary" htmlType="submit" icon={<SaveOutlined />}>
{Lang.t("save")}
</Button>
</div>
</Form>
</TankContentCard>
</div>
);
}
}