1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 14:08:06 +08:00

feat: 迁移缓存清理代码 (#3186)

This commit is contained in:
ssongliu 2023-12-05 15:50:10 +08:00 committed by GitHub
parent 58b6a2de32
commit 1a400e7f81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 271 additions and 256 deletions

View File

@ -203,3 +203,34 @@ func (b *BaseApi) CheckDNS(c *gin.Context) {
helper.SuccessWithData(c, data) helper.SuccessWithData(c, data)
} }
// @Tags Device
// @Summary Scan system
// @Description 扫描系统垃圾文件
// @Success 200
// @Security ApiKeyAuth
// @Router /toolbox/scan [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"扫描系统垃圾文件","formatEN":"scan System Junk Files"}
func (b *BaseApi) ScanSystem(c *gin.Context) {
helper.SuccessWithData(c, deviceService.Scan())
}
// @Tags Device
// @Summary Clean system
// @Description 清理系统垃圾文件
// @Accept json
// @Param request body []dto.Clean true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /toolbox/clean [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理系统垃圾文件","formatEN":"Clean system junk files"}
func (b *BaseApi) SystemClean(c *gin.Context) {
var req []dto.Clean
if err := helper.CheckBind(&req, c); err != nil {
return
}
deviceService.Clean(req)
helper.SuccessWithData(c, nil)
}

View File

@ -251,37 +251,6 @@ func (b *BaseApi) CleanMonitor(c *gin.Context) {
helper.SuccessWithData(c, nil) helper.SuccessWithData(c, nil)
} }
// @Tags System Setting
// @Summary Scan system
// @Description 扫描系统垃圾文件
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/scan [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"扫描系统垃圾文件","formatEN":"scan System Junk Files"}
func (b *BaseApi) ScanSystem(c *gin.Context) {
helper.SuccessWithData(c, settingService.SystemScan())
}
// @Tags System Setting
// @Summary System clean
// @Description 清理系统垃圾文件
// @Accept json
// @Param request body []dto.Clean true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/clean [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清理系统垃圾文件","formatEN":"Clean system junk files"}
func (b *BaseApi) SystemClean(c *gin.Context) {
var req []dto.Clean
if err := helper.CheckBind(&req, c); err != nil {
return
}
settingService.SystemClean(req)
helper.SuccessWithData(c, nil)
}
// @Tags System Setting // @Tags System Setting
// @Summary Load mfa info // @Summary Load mfa info
// @Description 获取 mfa 信息 // @Description 获取 mfa 信息

View File

@ -584,7 +584,7 @@ func (u *CronjobService) handleSnapshot(cronjob *model.Cronjob, startTime time.T
} }
func (u *CronjobService) handleSystemClean() (string, error) { func (u *CronjobService) handleSystemClean() (string, error) {
return NewISettingService().SystemCleanForCronjob() return NewIDeviceService().CleanForCronjob()
} }
func (u *CronjobService) handleSystemLog(cronjob model.Cronjob, startTime time.Time) (string, error) { func (u *CronjobService) handleSystemLog(cronjob model.Cronjob, startTime time.Time) (string, error) {

View File

@ -37,6 +37,10 @@ type IDeviceService interface {
LoadTimeZone() ([]string, error) LoadTimeZone() ([]string, error)
CheckDNS(key, value string) (bool, error) CheckDNS(key, value string) (bool, error)
LoadConf(name string) (string, error) LoadConf(name string) (string, error)
Scan() dto.CleanData
Clean(req []dto.Clean)
CleanForCronjob() (string, error)
} }
func NewIDeviceService() IDeviceService { func NewIDeviceService() IDeviceService {

View File

@ -33,7 +33,7 @@ const (
taskPath = "1panel/task" taskPath = "1panel/task"
) )
func (u *SettingService) SystemScan() dto.CleanData { func (u *DeviceService) Scan() dto.CleanData {
var ( var (
SystemClean dto.CleanData SystemClean dto.CleanData
treeData []dto.CleanTree treeData []dto.CleanTree
@ -133,7 +133,7 @@ func (u *SettingService) SystemScan() dto.CleanData {
return SystemClean return SystemClean
} }
func (u *SettingService) SystemClean(req []dto.Clean) { func (u *DeviceService) Clean(req []dto.Clean) {
size := uint64(0) size := uint64(0)
restart := false restart := false
for _, item := range req { for _, item := range req {
@ -235,7 +235,7 @@ func (u *SettingService) SystemClean(req []dto.Clean) {
continue continue
} }
for _, file := range files { for _, file := range files {
if file.Name() == "1Panel.log" { if file.Name() == "1Panel.log" || file.IsDir() {
continue continue
} }
dropFileOrDir(path.Join(global.CONF.System.BaseDir, logPath, file.Name())) dropFileOrDir(path.Join(global.CONF.System.BaseDir, logPath, file.Name()))
@ -276,7 +276,7 @@ func (u *SettingService) SystemClean(req []dto.Clean) {
} }
} }
func (u *SettingService) SystemCleanForCronjob() (string, error) { func (u *DeviceService) CleanForCronjob() (string, error) {
logs := "" logs := ""
size := int64(0) size := int64(0)
fileCount := 0 fileCount := 0
@ -541,7 +541,7 @@ func loadTreeWithAllFile(isCheck bool, originalPath, treeType, pathItem string,
return lists return lists
} }
for _, file := range files { for _, file := range files {
if treeType == "system_log" && file.Name() == "1Panel.log" { if treeType == "system_log" && (file.Name() == "1Panel.log" || file.IsDir()) {
continue continue
} }
if (treeType == "upload" || treeType == "download") && file.IsDir() && (file.Name() == "app" || file.Name() == "database" || file.Name() == "website" || file.Name() == "directory") { if (treeType == "upload" || treeType == "download") && file.IsDir() && (file.Name() == "app" || file.Name() == "database" || file.Name() == "website" || file.Name() == "directory") {

View File

@ -6,7 +6,6 @@ import (
"encoding/json" "encoding/json"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"net" "net"
"os" "os"
"path" "path"
@ -14,6 +13,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
"github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/constant"
@ -38,10 +39,6 @@ type ISettingService interface {
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
LoadFromCert() (*dto.SSLInfo, error) LoadFromCert() (*dto.SSLInfo, error)
HandlePasswordExpired(c *gin.Context, old, new string) error HandlePasswordExpired(c *gin.Context, old, new string) error
SystemScan() dto.CleanData
SystemClean(req []dto.Clean)
SystemCleanForCronjob() (string, error)
} }
func NewISettingService() ISettingService { func NewISettingService() ISettingService {

View File

@ -32,8 +32,6 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
settingRouter.POST("/monitor/clean", baseApi.CleanMonitor) settingRouter.POST("/monitor/clean", baseApi.CleanMonitor)
settingRouter.POST("/mfa", baseApi.LoadMFA) settingRouter.POST("/mfa", baseApi.LoadMFA)
settingRouter.POST("/mfa/bind", baseApi.MFABind) settingRouter.POST("/mfa/bind", baseApi.MFABind)
settingRouter.POST("/scan", baseApi.ScanSystem)
settingRouter.POST("/clean", baseApi.SystemClean)
settingRouter.POST("/snapshot", baseApi.CreateSnapshot) settingRouter.POST("/snapshot", baseApi.CreateSnapshot)
settingRouter.POST("/snapshot/status", baseApi.LoadSnapShotStatus) settingRouter.POST("/snapshot/status", baseApi.LoadSnapShotStatus)

View File

@ -26,6 +26,9 @@ func (s *ToolboxRouter) InitToolboxRouter(Router *gin.RouterGroup) {
toolboxRouter.POST("/device/check/dns", baseApi.CheckDNS) toolboxRouter.POST("/device/check/dns", baseApi.CheckDNS)
toolboxRouter.POST("/device/conf", baseApi.LoadDeviceConf) toolboxRouter.POST("/device/conf", baseApi.LoadDeviceConf)
toolboxRouter.POST("/scan", baseApi.ScanSystem)
toolboxRouter.POST("/clean", baseApi.SystemClean)
toolboxRouter.GET("/fail2ban/base", baseApi.LoadFail2BanBaseInfo) toolboxRouter.GET("/fail2ban/base", baseApi.LoadFail2BanBaseInfo)
toolboxRouter.GET("/fail2ban/load/conf", baseApi.LoadFail2BanConf) toolboxRouter.GET("/fail2ban/load/conf", baseApi.LoadFail2BanConf)
toolboxRouter.POST("/fail2ban/search", baseApi.SearchFail2Ban) toolboxRouter.POST("/fail2ban/search", baseApi.SearchFail2Ban)

View File

@ -1,5 +1,5 @@
// Package docs GENERATED BY SWAG; DO NOT EDIT // Code generated by swaggo/swag. DO NOT EDIT.
// This file was generated by swaggo/swag
package docs package docs
import "github.com/swaggo/swag" import "github.com/swaggo/swag"
@ -9212,49 +9212,6 @@ const docTemplate = `{
} }
} }
}, },
"/settings/clean": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "清理系统垃圾文件",
"consumes": [
"application/json"
],
"tags": [
"System Setting"
],
"summary": "System clean",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.Clean"
}
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "Clean system junk files",
"formatZH": "清理系统垃圾文件",
"paramKeys": []
}
}
},
"/settings/expired/handle": { "/settings/expired/handle": {
"post": { "post": {
"security": [ "security": [
@ -9501,32 +9458,6 @@ const docTemplate = `{
} }
} }
}, },
"/settings/scan": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "扫描系统垃圾文件",
"tags": [
"System Setting"
],
"summary": "Scan system",
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "scan System Junk Files",
"formatZH": "扫描系统垃圾文件",
"paramKeys": []
}
}
},
"/settings/search": { "/settings/search": {
"post": { "post": {
"security": [ "security": [
@ -10127,6 +10058,49 @@ const docTemplate = `{
} }
} }
}, },
"/toolbox/clean": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "清理系统垃圾文件",
"consumes": [
"application/json"
],
"tags": [
"Device"
],
"summary": "Clean system",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.Clean"
}
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "Clean system junk files",
"formatZH": "清理系统垃圾文件",
"paramKeys": []
}
}
},
"/toolbox/device/base": { "/toolbox/device/base": {
"get": { "get": {
"security": [ "security": [
@ -10644,6 +10618,32 @@ const docTemplate = `{
} }
} }
}, },
"/toolbox/scan": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "扫描系统垃圾文件",
"tags": [
"Device"
],
"summary": "Scan system",
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "scan System Junk Files",
"formatZH": "扫描系统垃圾文件",
"paramKeys": []
}
}
},
"/websites": { "/websites": {
"post": { "post": {
"security": [ "security": [
@ -14850,6 +14850,9 @@ const docTemplate = `{
"localTime": { "localTime": {
"type": "string" "type": "string"
}, },
"maxSize": {
"type": "integer"
},
"ntp": { "ntp": {
"type": "string" "type": "string"
}, },

View File

@ -9205,49 +9205,6 @@
} }
} }
}, },
"/settings/clean": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "清理系统垃圾文件",
"consumes": [
"application/json"
],
"tags": [
"System Setting"
],
"summary": "System clean",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.Clean"
}
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "Clean system junk files",
"formatZH": "清理系统垃圾文件",
"paramKeys": []
}
}
},
"/settings/expired/handle": { "/settings/expired/handle": {
"post": { "post": {
"security": [ "security": [
@ -9494,32 +9451,6 @@
} }
} }
}, },
"/settings/scan": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "扫描系统垃圾文件",
"tags": [
"System Setting"
],
"summary": "Scan system",
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "scan System Junk Files",
"formatZH": "扫描系统垃圾文件",
"paramKeys": []
}
}
},
"/settings/search": { "/settings/search": {
"post": { "post": {
"security": [ "security": [
@ -10120,6 +10051,49 @@
} }
} }
}, },
"/toolbox/clean": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "清理系统垃圾文件",
"consumes": [
"application/json"
],
"tags": [
"Device"
],
"summary": "Clean system",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.Clean"
}
}
}
],
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "Clean system junk files",
"formatZH": "清理系统垃圾文件",
"paramKeys": []
}
}
},
"/toolbox/device/base": { "/toolbox/device/base": {
"get": { "get": {
"security": [ "security": [
@ -10637,6 +10611,32 @@
} }
} }
}, },
"/toolbox/scan": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "扫描系统垃圾文件",
"tags": [
"Device"
],
"summary": "Scan system",
"responses": {
"200": {
"description": "OK"
}
},
"x-panel-log": {
"BeforeFunctions": [],
"bodyKeys": [],
"formatEN": "scan System Junk Files",
"formatZH": "扫描系统垃圾文件",
"paramKeys": []
}
}
},
"/websites": { "/websites": {
"post": { "post": {
"security": [ "security": [
@ -14843,6 +14843,9 @@
"localTime": { "localTime": {
"type": "string" "type": "string"
}, },
"maxSize": {
"type": "integer"
},
"ntp": { "ntp": {
"type": "string" "type": "string"
}, },

View File

@ -987,6 +987,8 @@ definitions:
type: array type: array
localTime: localTime:
type: string type: string
maxSize:
type: integer
ntp: ntp:
type: string type: string
swapDetails: swapDetails:
@ -10610,34 +10612,6 @@ paths:
formatEN: 'update system bind info => ipv6: [ipv6], 监听 IP: [bindAddress]' formatEN: 'update system bind info => ipv6: [ipv6], 监听 IP: [bindAddress]'
formatZH: '修改系统监听信息 => ipv6: [ipv6], 监听 IP: [bindAddress]' formatZH: '修改系统监听信息 => ipv6: [ipv6], 监听 IP: [bindAddress]'
paramKeys: [] paramKeys: []
/settings/clean:
post:
consumes:
- application/json
description: 清理系统垃圾文件
parameters:
- description: request
in: body
name: request
required: true
schema:
items:
$ref: '#/definitions/dto.Clean'
type: array
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: System clean
tags:
- System Setting
x-panel-log:
BeforeFunctions: []
bodyKeys: []
formatEN: Clean system junk files
formatZH: 清理系统垃圾文件
paramKeys: []
/settings/expired/handle: /settings/expired/handle:
post: post:
consumes: consumes:
@ -10795,23 +10769,6 @@ paths:
formatEN: update system port => [serverPort] formatEN: update system port => [serverPort]
formatZH: 修改系统端口 => [serverPort] formatZH: 修改系统端口 => [serverPort]
paramKeys: [] paramKeys: []
/settings/scan:
post:
description: 扫描系统垃圾文件
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Scan system
tags:
- System Setting
x-panel-log:
BeforeFunctions: []
bodyKeys: []
formatEN: scan System Junk Files
formatZH: 扫描系统垃圾文件
paramKeys: []
/settings/search: /settings/search:
post: post:
description: 加载系统配置信息 description: 加载系统配置信息
@ -11192,6 +11149,34 @@ paths:
formatEN: upgrade service => [version] formatEN: upgrade service => [version]
formatZH: 更新系统 => [version] formatZH: 更新系统 => [version]
paramKeys: [] paramKeys: []
/toolbox/clean:
post:
consumes:
- application/json
description: 清理系统垃圾文件
parameters:
- description: request
in: body
name: request
required: true
schema:
items:
$ref: '#/definitions/dto.Clean'
type: array
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Clean system
tags:
- Device
x-panel-log:
BeforeFunctions: []
bodyKeys: []
formatEN: Clean system junk files
formatZH: 清理系统垃圾文件
paramKeys: []
/toolbox/device/base: /toolbox/device/base:
get: get:
description: 获取设备基础信息 description: 获取设备基础信息
@ -11514,6 +11499,23 @@ paths:
summary: Update fail2ban conf by file summary: Update fail2ban conf by file
tags: tags:
- Fail2ban - Fail2ban
/toolbox/scan:
post:
description: 扫描系统垃圾文件
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Scan system
tags:
- Device
x-panel-log:
BeforeFunctions: []
bodyKeys: []
formatEN: scan System Junk Files
formatZH: 扫描系统垃圾文件
paramKeys: []
/websites: /websites:
post: post:
consumes: consumes:

View File

@ -87,23 +87,6 @@ export namespace Setting {
interval: string; interval: string;
} }
export interface CleanData {
systemClean: Array<CleanTree>;
uploadClean: Array<CleanTree>;
downloadClean: Array<CleanTree>;
systemLogClean: Array<CleanTree>;
}
export interface CleanTree {
id: string;
label: string;
children: Array<CleanTree>;
type: string;
name: string;
size: number;
isCheck: boolean;
isRecommend: boolean;
}
export interface SnapshotCreate { export interface SnapshotCreate {
id: number; id: number;
from: string; from: string;

View File

@ -31,6 +31,23 @@ export namespace Toolbox {
zones: Array<string>; zones: Array<string>;
} }
export interface CleanData {
systemClean: Array<CleanTree>;
uploadClean: Array<CleanTree>;
downloadClean: Array<CleanTree>;
systemLogClean: Array<CleanTree>;
}
export interface CleanTree {
id: string;
label: string;
children: Array<CleanTree>;
type: string;
name: string;
size: number;
isCheck: boolean;
isRecommend: boolean;
}
export interface Fail2banBaseInfo { export interface Fail2banBaseInfo {
isEnable: boolean; isEnable: boolean;
isActive: boolean; isActive: boolean;

View File

@ -47,13 +47,6 @@ export const handleExpired = (param: Setting.PasswordUpdate) => {
return http.post(`/settings/expired/handle`, param); return http.post(`/settings/expired/handle`, param);
}; };
export const scanSystem = () => {
return http.post<Setting.CleanData>(`/settings/scan`, {});
};
export const cleanSystem = (param: any) => {
return http.post(`/settings/clean`, param);
};
export const loadTimeZone = () => { export const loadTimeZone = () => {
return http.get<Array<string>>(`/settings/time/option`); return http.get<Array<string>>(`/settings/time/option`);
}; };

View File

@ -33,6 +33,14 @@ export const loadDeviceConf = (name: string) => {
return http.post(`/toolbox/device/conf`, { name: name }); return http.post(`/toolbox/device/conf`, { name: name });
}; };
// clean
export const scan = () => {
return http.post<Toolbox.CleanData>(`/toolbox/scan`, {});
};
export const clean = (param: any) => {
return http.post(`/toolbox/clean`, param);
};
// fail2ban // fail2ban
export const getFail2banBase = () => { export const getFail2banBase = () => {
return http.get<Toolbox.Fail2banBaseInfo>(`/toolbox/fail2ban/base`); return http.get<Toolbox.Fail2banBaseInfo>(`/toolbox/fail2ban/base`);

View File

@ -192,6 +192,9 @@ const loadDetail = (log: string) => {
if (log.indexOf('[get]') !== -1) { if (log.indexOf('[get]') !== -1) {
log = log.replace('[get]', '[' + i18n.global.t('commons.button.get') + ']'); log = log.replace('[get]', '[' + i18n.global.t('commons.button.get') + ']');
} }
if (log.indexOf('[operate]') !== -1) {
log = log.replace('[operate]', '[' + i18n.global.t('commons.table.operate') + ']');
}
if (log.indexOf('[UserName]') !== -1) { if (log.indexOf('[UserName]') !== -1) {
return log.replace('[UserName]', '[' + i18n.global.t('commons.login.username') + ']'); return log.replace('[UserName]', '[' + i18n.global.t('commons.login.username') + ']');
} }

View File

@ -228,7 +228,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { computeSize } from '@/utils/util'; import { computeSize } from '@/utils/util';
import { cleanSystem, scanSystem, getSettingInfo } from '@/api/modules/setting'; import { getSettingInfo } from '@/api/modules/setting';
import { clean, scan } from '@/api/modules/toolbox';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
@ -270,7 +271,7 @@ const form = reactive({
const scanData = async () => { const scanData = async () => {
loading.value = true; loading.value = true;
await scanSystem() await scan()
.then((res) => { .then((res) => {
loading.value = false; loading.value = false;
selectSize.value = 0; selectSize.value = 0;
@ -321,7 +322,7 @@ const onSubmitClean = async () => {
break; break;
} }
} }
await cleanSystem(submitCleans.value) await clean(submitCleans.value)
.then(() => { .then(() => {
form.lastCleanSize = selectSize.value + ''; form.lastCleanSize = selectSize.value + '';
form.lastCleanData = submitCleans.value.length + ''; form.lastCleanData = submitCleans.value.length + '';