diff --git a/src/common/model/global/i18n/LangEn.ts b/src/common/model/global/i18n/LangEn.ts index 885aa0f..56d94d2 100644 --- a/src/common/model/global/i18n/LangEn.ts +++ b/src/common/model/global/i18n/LangEn.ts @@ -187,7 +187,17 @@ let LangEn = { engineRegPlaceHolder: "eg:https://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", diff --git a/src/common/model/global/i18n/LangZh.ts b/src/common/model/global/i18n/LangZh.ts index eb4d166..63b8231 100644 --- a/src/common/model/global/i18n/LangZh.ts +++ b/src/common/model/global/i18n/LangZh.ts @@ -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: "分享详情", diff --git a/src/common/model/preference/Preference.ts b/src/common/model/preference/Preference.ts index 0dbab84..d829efe 100644 --- a/src/common/model/preference/Preference.ts +++ b/src/common/model/preference/Preference.ts @@ -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); + + } } diff --git a/src/common/model/preference/model/ScanConfig.ts b/src/common/model/preference/model/ScanConfig.ts new file mode 100644 index 0000000..fbc88ad --- /dev/null +++ b/src/common/model/preference/model/ScanConfig.ts @@ -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, + }; + } +} diff --git a/src/common/model/preference/model/ScanCronType.ts b/src/common/model/preference/model/ScanCronType.ts new file mode 100644 index 0000000..b188fce --- /dev/null +++ b/src/common/model/preference/model/ScanCronType.ts @@ -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 }; diff --git a/src/common/model/preference/model/ScanScopeType.ts b/src/common/model/preference/model/ScanScopeType.ts new file mode 100644 index 0000000..269df9d --- /dev/null +++ b/src/common/model/preference/model/ScanScopeType.ts @@ -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 }; diff --git a/src/pages/Frame.tsx b/src/pages/Frame.tsx index faa0ebb..9717d11 100644 --- a/src/pages/Frame.tsx +++ b/src/pages/Frame.tsx @@ -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 { + diff --git a/src/pages/preference/Index.tsx b/src/pages/preference/Index.tsx index 1cc4dcc..5a0f167 100644 --- a/src/pages/preference/Index.tsx +++ b/src/pages/preference/Index.tsx @@ -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 { } render() { - const { previewEngines } = this.preference.previewConfig; + const { + previewConfig: { previewEngines }, + scanConfig, + } = this.preference; + console.log(scanConfig); return (
@@ -77,7 +85,6 @@ export default class Index extends TankComponent { -

{Lang.t("preference.basic")}

@@ -118,15 +125,15 @@ export default class Index extends TankComponent { - + - + @@ -158,40 +165,39 @@ export default class Index extends TankComponent {
-

- {Lang.t("preference.preview")} -

+

{Lang.t("preference.preview")}

-
- { - previewEngines.length ? previewEngines.map((engines, index) => ( + {previewEngines.length ? ( + previewEngines.map((engines, index) => (
- - {engines.previewInSite ? ( - - {Lang.t("preference.previewCurrent")} - - ) : ( - - {Lang.t("preference.previewOpen")} - - )} - - - {engines.url} - - - {engines.extensions} - + + {engines.previewInSite ? ( + + {Lang.t("preference.previewCurrent")} + + ) : ( + + {Lang.t("preference.previewOpen")} + + )} + + + {engines.url} + + + {engines.extensions} +
- )) : - } + )) + ) : ( + + )}
@@ -199,17 +205,34 @@ export default class Index extends TankComponent {
-

- {Lang.t("preference.scan")} -

- +

{Lang.t("preference.scan")}

+ + +
+
+ {scanConfig.enable ? ( + <> + + {scanConfig.cron} + + + {ScanScopeTypeMap[scanConfig.scope].name} + + {scanConfig.scope === ScanScopeType.CUSTOM && ( + + {scanConfig.usernames.join(", ")} + + )} + + ) : ( + + )} +
- -
); } diff --git a/src/pages/preference/PreviewEngineEdit.tsx b/src/pages/preference/PreviewEngineEdit.tsx index a8df02f..72eafe4 100644 --- a/src/pages/preference/PreviewEngineEdit.tsx +++ b/src/pages/preference/PreviewEngineEdit.tsx @@ -62,7 +62,6 @@ export default class PreviewEngineEdit extends TankComponent { {...layout} name="preview-engine" ref={this.formRef} - initialValues={preference.getForm()} onFinish={this.finish} onValuesChange={this.updateUI} > diff --git a/src/pages/preference/ScanEdit.less b/src/pages/preference/ScanEdit.less new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/preference/ScanEdit.tsx b/src/pages/preference/ScanEdit.tsx new file mode 100644 index 0000000..f2df3a6 --- /dev/null +++ b/src/pages/preference/ScanEdit.tsx @@ -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 { + formRef = React.createRef(); + + preference: Preference = Moon.getSingleton().preference; + pager: Pager = new Pager(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 ( +
+ + +
this.updateUI} + > + + + + {preference.scanConfig.enable && ( + <> + + + + {preference.scanConfig.cronType === ScanCronType.CUSTOM && ( + + + + )} + + + + {preference.scanConfig.scope === ScanScopeType.CUSTOM && ( + + + + )} + + )} +
+ +
+
+
+
+ ); + } +}