diff --git a/backend/app/api/v1/clam.go b/backend/app/api/v1/clam.go index 6f26f2904..f6a3428b2 100644 --- a/backend/app/api/v1/clam.go +++ b/backend/app/api/v1/clam.go @@ -210,18 +210,18 @@ func (b *BaseApi) UpdateFile(c *gin.Context) { // @Summary Delete clam // @Description 删除扫描规则 // @Accept json -// @Param request body dto.BatchDeleteReq true "request" +// @Param request body dto.ClamDelete true "request" // @Success 200 // @Security ApiKeyAuth // @Router /toolbox/clam/del [post] // @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"clams","output_column":"name","output_value":"names"}],"formatZH":"删除扫描规则 [names]","formatEN":"delete clam [names]"} func (b *BaseApi) DeleteClam(c *gin.Context) { - var req dto.BatchDeleteReq + var req dto.ClamDelete if err := helper.CheckBindAndValidate(&req, c); err != nil { return } - if err := clamService.Delete(req.Ids); err != nil { + if err := clamService.Delete(req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } diff --git a/backend/app/dto/clam.go b/backend/app/dto/clam.go index f2059d1aa..a526d64fd 100644 --- a/backend/app/dto/clam.go +++ b/backend/app/dto/clam.go @@ -14,10 +14,12 @@ type ClamInfo struct { ID uint `json:"id"` CreatedAt time.Time `json:"createdAt"` - Name string `json:"name"` - Path string `json:"path"` - LastHandleDate string `json:"lastHandleDate"` - Description string `json:"description"` + Name string `json:"name"` + Path string `json:"path"` + InfectedStrategy string `json:"infectedStrategy"` + InfectedDir string `json:"infectedDir"` + LastHandleDate string `json:"lastHandleDate"` + Description string `json:"description"` } type ClamLogSearch struct { @@ -38,15 +40,25 @@ type ClamLog struct { } type ClamCreate struct { - Name string `json:"name"` - Path string `json:"path"` - Description string `json:"description"` + Name string `json:"name"` + Path string `json:"path"` + InfectedStrategy string `json:"infectedStrategy"` + InfectedDir string `json:"infectedDir"` + Description string `json:"description"` } type ClamUpdate struct { ID uint `json:"id"` - Name string `json:"name"` - Path string `json:"path"` - Description string `json:"description"` + Name string `json:"name"` + Path string `json:"path"` + InfectedStrategy string `json:"infectedStrategy"` + InfectedDir string `json:"infectedDir"` + Description string `json:"description"` +} + +type ClamDelete struct { + RemoveResult bool `json:"removeResult"` + RemoveInfected bool `json:"removeInfected"` + Ids []uint `json:"ids" validate:"required"` } diff --git a/backend/app/model/clam.go b/backend/app/model/clam.go index fcd440178..044c7bb31 100644 --- a/backend/app/model/clam.go +++ b/backend/app/model/clam.go @@ -3,7 +3,9 @@ package model type Clam struct { BaseModel - Name string `gorm:"type:varchar(64);not null" json:"name"` - Path string `gorm:"type:varchar(64);not null" json:"path"` - Description string `gorm:"type:varchar(64);not null" json:"description"` + Name string `gorm:"type:varchar(64);not null" json:"name"` + Path string `gorm:"type:varchar(64);not null" json:"path"` + InfectedStrategy string `gorm:"type:varchar(64)" json:"infectedStrategy"` + InfectedDir string `gorm:"type:varchar(64)" json:"infectedDir"` + Description string `gorm:"type:varchar(64)" json:"description"` } diff --git a/backend/app/service/clam.go b/backend/app/service/clam.go index 21cb5d5a4..8efd5ea70 100644 --- a/backend/app/service/clam.go +++ b/backend/app/service/clam.go @@ -26,7 +26,7 @@ import ( const ( clamServiceNameCentOs = "clamd@scan.service" clamServiceNameUbuntu = "clamav-daemon.service" - scanDir = "scan-result" + resultDir = "clamav" ) type ClamService struct { @@ -39,7 +39,7 @@ type IClamService interface { SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) Create(req dto.ClamCreate) error Update(req dto.ClamUpdate) error - Delete(ids []uint) error + Delete(req dto.ClamDelete) error HandleOnce(req dto.OperateByID) error LoadFile(req dto.OperationWithName) (string, error) UpdateFile(req dto.UpdateByNameAndFile) error @@ -154,15 +154,21 @@ func (f *ClamService) Update(req dto.ClamUpdate) error { return nil } -func (u *ClamService) Delete(ids []uint) error { - if len(ids) == 1 { - clam, _ := clamRepo.Get(commonRepo.WithByID(ids[0])) +func (u *ClamService) Delete(req dto.ClamDelete) error { + for _, id := range req.Ids { + clam, _ := clamRepo.Get(commonRepo.WithByID(id)) if clam.ID == 0 { - return constant.ErrRecordNotFound + continue + } + if req.RemoveResult { + _ = os.RemoveAll(path.Join(global.CONF.System.DataDir, resultDir, clam.Name)) } - return clamRepo.Delete(commonRepo.WithByID(ids[0])) + if req.RemoveInfected { + _ = os.RemoveAll(path.Join(clam.InfectedDir, "1panel-infected", clam.Name)) + } + return clamRepo.Delete(commonRepo.WithByID(id)) } - return clamRepo.Delete(commonRepo.WithIdsIn(ids)) + return nil } func (u *ClamService) HandleOnce(req dto.OperateByID) error { @@ -173,12 +179,30 @@ func (u *ClamService) HandleOnce(req dto.OperateByID) error { if cmd.CheckIllegal(clam.Path) { return buserr.New(constant.ErrCmdIllegal) } - logFile := path.Join(global.CONF.System.DataDir, scanDir, clam.Name, time.Now().Format(constant.DateTimeSlimLayout)) + timeNow := time.Now().Format(constant.DateTimeSlimLayout) + logFile := path.Join(global.CONF.System.DataDir, resultDir, clam.Name, timeNow) if _, err := os.Stat(path.Dir(logFile)); err != nil { _ = os.MkdirAll(path.Dir(logFile), os.ModePerm) } go func() { - cmd := exec.Command("clamdscan", "--fdpass", clam.Path, "-l", logFile) + strategy := "" + switch clam.InfectedStrategy { + case "remove": + strategy = "--remove" + case "move": + dir := path.Join(clam.InfectedDir, "1panel-infected", clam.Name, timeNow) + strategy = "--move=" + dir + if _, err := os.Stat(dir); err != nil { + _ = os.MkdirAll(dir, os.ModePerm) + } + case "copy": + dir := path.Join(clam.InfectedDir, "1panel-infected", clam.Name, timeNow) + strategy = "--copy=" + dir + if _, err := os.Stat(dir); err != nil { + _ = os.MkdirAll(dir, os.ModePerm) + } + } + cmd := exec.Command("clamdscan", "--fdpass", strategy, clam.Path, "-l", logFile) _, _ = cmd.CombinedOutput() }() return nil @@ -226,7 +250,7 @@ func (u *ClamService) LoadRecords(req dto.ClamLogSearch) (int64, interface{}, er var datas []dto.ClamLog for i := 0; i < len(records); i++ { - item := loadResultFromLog(path.Join(global.CONF.System.DataDir, scanDir, clam.Name, records[i])) + item := loadResultFromLog(path.Join(global.CONF.System.DataDir, resultDir, clam.Name, records[i])) datas = append(datas, item) } return int64(total), datas, nil @@ -237,7 +261,7 @@ func (u *ClamService) CleanRecord(req dto.OperateByID) error { if clam.ID == 0 { return constant.ErrRecordNotFound } - pathItem := path.Join(global.CONF.System.DataDir, scanDir, clam.Name) + pathItem := path.Join(global.CONF.System.DataDir, resultDir, clam.Name) _ = os.RemoveAll(pathItem) return nil } @@ -319,7 +343,7 @@ func (u *ClamService) UpdateFile(req dto.UpdateByNameAndFile) error { func loadFileByName(name string) []string { var logPaths []string - pathItem := path.Join(global.CONF.System.DataDir, scanDir, name) + pathItem := path.Join(global.CONF.System.DataDir, resultDir, name) _ = filepath.Walk(pathItem, func(path string, info os.FileInfo, err error) error { if err != nil { return nil diff --git a/backend/init/migration/migrations/v_1_10.go b/backend/init/migration/migrations/v_1_10.go index ba5b21e66..61de816ef 100644 --- a/backend/init/migration/migrations/v_1_10.go +++ b/backend/init/migration/migrations/v_1_10.go @@ -270,7 +270,7 @@ var AddShellColumn = &gormigrate.Migration{ } var AddClam = &gormigrate.Migration{ - ID: "20240624-add-clam", + ID: "20240701-add-clam", Migrate: func(tx *gorm.DB) error { if err := tx.AutoMigrate(&model.Clam{}); err != nil { return err diff --git a/backend/utils/terminal/ws_local_session.go b/backend/utils/terminal/ws_local_session.go index fb8271994..1a7a99adf 100644 --- a/backend/utils/terminal/ws_local_session.go +++ b/backend/utils/terminal/ws_local_session.go @@ -72,7 +72,7 @@ func (sws *LocalWsSession) masterWrite(data []byte) error { func (sws *LocalWsSession) receiveWsMsg(exitCh chan bool) { defer func() { if r := recover(); r != nil { - global.LOG.Errorf("[xpack] A panic occurred during receive ws message, error message: %v", r) + global.LOG.Errorf("A panic occurred during receive ws message, error message: %v", r) } }() wsConn := sws.wsConn diff --git a/backend/utils/terminal/ws_session.go b/backend/utils/terminal/ws_session.go index c0e72a761..2d66fab2f 100644 --- a/backend/utils/terminal/ws_session.go +++ b/backend/utils/terminal/ws_session.go @@ -118,7 +118,7 @@ func (sws *LogicSshWsSession) Start(quitChan chan bool) { func (sws *LogicSshWsSession) receiveWsMsg(exitCh chan bool) { defer func() { if r := recover(); r != nil { - global.LOG.Errorf("[xpack] A panic occurred during receive ws message, error message: %v", r) + global.LOG.Errorf("[A panic occurred during receive ws message, error message: %v", r) } }() wsConn := sws.wsConn diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index da34f97a7..5c8d07047 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -1585,6 +1585,12 @@ const docTemplate = `{ } } }, + "/containers/download/log": { + "post": { + "description": "下载容器日志", + "responses": {} + } + }, "/containers/image": { "get": { "security": [ @@ -11155,7 +11161,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.BatchDeleteReq" + "$ref": "#/definitions/dto.ClamDelete" } } ], @@ -15460,6 +15466,12 @@ const docTemplate = `{ "description": { "type": "string" }, + "infectedDir": { + "type": "string" + }, + "infectedStrategy": { + "type": "string" + }, "name": { "type": "string" }, @@ -15468,6 +15480,26 @@ const docTemplate = `{ } } }, + "dto.ClamDelete": { + "type": "object", + "required": [ + "ids" + ], + "properties": { + "ids": { + "type": "array", + "items": { + "type": "integer" + } + }, + "removeInfected": { + "type": "boolean" + }, + "removeResult": { + "type": "boolean" + } + } + }, "dto.ClamLogSearch": { "type": "object", "required": [ @@ -15501,6 +15533,12 @@ const docTemplate = `{ "id": { "type": "integer" }, + "infectedDir": { + "type": "string" + }, + "infectedStrategy": { + "type": "string" + }, "name": { "type": "string" }, @@ -20116,6 +20154,9 @@ const docTemplate = `{ "domains": { "type": "string" }, + "execShell": { + "type": "boolean" + }, "expireDate": { "type": "string" }, @@ -20152,6 +20193,9 @@ const docTemplate = `{ "pushDir": { "type": "boolean" }, + "shell": { + "type": "string" + }, "skipDNS": { "type": "boolean" }, @@ -21663,6 +21707,9 @@ const docTemplate = `{ "domains": { "type": "string" }, + "execShell": { + "type": "boolean" + }, "id": { "type": "integer" }, @@ -21683,6 +21730,9 @@ const docTemplate = `{ "renew": { "type": "boolean" }, + "shell": { + "type": "string" + }, "sslID": { "type": "integer" }, @@ -22242,6 +22292,9 @@ const docTemplate = `{ "dnsAccountId": { "type": "integer" }, + "execShell": { + "type": "boolean" + }, "id": { "type": "integer" }, @@ -22266,6 +22319,9 @@ const docTemplate = `{ "pushDir": { "type": "boolean" }, + "shell": { + "type": "string" + }, "skipDNS": { "type": "boolean" } @@ -22318,6 +22374,9 @@ const docTemplate = `{ "dnsAccountId": { "type": "integer" }, + "execShell": { + "type": "boolean" + }, "id": { "type": "integer" }, @@ -22342,6 +22401,9 @@ const docTemplate = `{ "pushDir": { "type": "boolean" }, + "shell": { + "type": "string" + }, "skipDNS": { "type": "boolean" } @@ -22786,9 +22848,15 @@ const docTemplate = `{ "$ref": "#/definitions/response.FileTree" } }, + "extension": { + "type": "string" + }, "id": { "type": "string" }, + "isDir": { + "type": "boolean" + }, "name": { "type": "string" }, diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index 422f0270d..02a221629 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -1578,6 +1578,12 @@ } } }, + "/containers/download/log": { + "post": { + "description": "下载容器日志", + "responses": {} + } + }, "/containers/image": { "get": { "security": [ @@ -11148,7 +11154,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.BatchDeleteReq" + "$ref": "#/definitions/dto.ClamDelete" } } ], @@ -15453,6 +15459,12 @@ "description": { "type": "string" }, + "infectedDir": { + "type": "string" + }, + "infectedStrategy": { + "type": "string" + }, "name": { "type": "string" }, @@ -15461,6 +15473,26 @@ } } }, + "dto.ClamDelete": { + "type": "object", + "required": [ + "ids" + ], + "properties": { + "ids": { + "type": "array", + "items": { + "type": "integer" + } + }, + "removeInfected": { + "type": "boolean" + }, + "removeResult": { + "type": "boolean" + } + } + }, "dto.ClamLogSearch": { "type": "object", "required": [ @@ -15494,6 +15526,12 @@ "id": { "type": "integer" }, + "infectedDir": { + "type": "string" + }, + "infectedStrategy": { + "type": "string" + }, "name": { "type": "string" }, @@ -20109,6 +20147,9 @@ "domains": { "type": "string" }, + "execShell": { + "type": "boolean" + }, "expireDate": { "type": "string" }, @@ -20145,6 +20186,9 @@ "pushDir": { "type": "boolean" }, + "shell": { + "type": "string" + }, "skipDNS": { "type": "boolean" }, @@ -21656,6 +21700,9 @@ "domains": { "type": "string" }, + "execShell": { + "type": "boolean" + }, "id": { "type": "integer" }, @@ -21676,6 +21723,9 @@ "renew": { "type": "boolean" }, + "shell": { + "type": "string" + }, "sslID": { "type": "integer" }, @@ -22235,6 +22285,9 @@ "dnsAccountId": { "type": "integer" }, + "execShell": { + "type": "boolean" + }, "id": { "type": "integer" }, @@ -22259,6 +22312,9 @@ "pushDir": { "type": "boolean" }, + "shell": { + "type": "string" + }, "skipDNS": { "type": "boolean" } @@ -22311,6 +22367,9 @@ "dnsAccountId": { "type": "integer" }, + "execShell": { + "type": "boolean" + }, "id": { "type": "integer" }, @@ -22335,6 +22394,9 @@ "pushDir": { "type": "boolean" }, + "shell": { + "type": "string" + }, "skipDNS": { "type": "boolean" } @@ -22779,9 +22841,15 @@ "$ref": "#/definitions/response.FileTree" } }, + "extension": { + "type": "string" + }, "id": { "type": "string" }, + "isDir": { + "type": "boolean" + }, "name": { "type": "string" }, diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index 66a8b0fce..4698ac49c 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -229,11 +229,28 @@ definitions: properties: description: type: string + infectedDir: + type: string + infectedStrategy: + type: string name: type: string path: type: string type: object + dto.ClamDelete: + properties: + ids: + items: + type: integer + type: array + removeInfected: + type: boolean + removeResult: + type: boolean + required: + - ids + type: object dto.ClamLogSearch: properties: clamID: @@ -256,6 +273,10 @@ definitions: type: string id: type: integer + infectedDir: + type: string + infectedStrategy: + type: string name: type: string path: @@ -3368,6 +3389,8 @@ definitions: type: integer domains: type: string + execShell: + type: boolean expireDate: type: string id: @@ -3392,6 +3415,8 @@ definitions: type: string pushDir: type: boolean + shell: + type: string skipDNS: type: boolean startDate: @@ -4401,6 +4426,8 @@ definitions: type: string domains: type: string + execShell: + type: boolean id: type: integer keyType: @@ -4416,6 +4443,8 @@ definitions: type: boolean renew: type: boolean + shell: + type: string sslID: type: integer time: @@ -4793,6 +4822,8 @@ definitions: type: boolean dnsAccountId: type: integer + execShell: + type: boolean id: type: integer keyType: @@ -4809,6 +4840,8 @@ definitions: type: string pushDir: type: boolean + shell: + type: string skipDNS: type: boolean required: @@ -4844,6 +4877,8 @@ definitions: type: boolean dnsAccountId: type: integer + execShell: + type: boolean id: type: integer keyType: @@ -4860,6 +4895,8 @@ definitions: type: string pushDir: type: boolean + shell: + type: string skipDNS: type: boolean required: @@ -5162,8 +5199,12 @@ definitions: items: $ref: '#/definitions/response.FileTree' type: array + extension: + type: string id: type: string + isDir: + type: boolean name: type: string path: @@ -6414,6 +6455,10 @@ paths: summary: Load docker status tags: - Container Docker + /containers/download/log: + post: + description: 下载容器日志 + responses: {} /containers/image: get: description: 获取镜像名称列表 @@ -12471,7 +12516,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.BatchDeleteReq' + $ref: '#/definitions/dto.ClamDelete' responses: "200": description: OK diff --git a/frontend/src/api/interface/toolbox.ts b/frontend/src/api/interface/toolbox.ts index 9160bd03f..2c033c92b 100644 --- a/frontend/src/api/interface/toolbox.ts +++ b/frontend/src/api/interface/toolbox.ts @@ -118,7 +118,7 @@ export namespace Toolbox { } export interface ClamBaseInfo { - version: string; + version: string; isActive: boolean; isExist: boolean; } @@ -126,18 +126,24 @@ export namespace Toolbox { id: number; name: string; path: string; + infectedStrategy: string; + infectedDir: string; lastHandleDate: string; description: string; } export interface ClamCreate { name: string; path: string; + infectedStrategy: string; + infectedDir: string; description: string; } export interface ClamUpdate { id: number; name: string; path: string; + infectedStrategy: string; + infectedDir: string; description: string; } export interface ClamSearchLog extends ReqPage { diff --git a/frontend/src/api/modules/toolbox.ts b/frontend/src/api/modules/toolbox.ts index bc893b759..0c43add65 100644 --- a/frontend/src/api/modules/toolbox.ts +++ b/frontend/src/api/modules/toolbox.ts @@ -135,7 +135,7 @@ export const createClam = (params: Toolbox.ClamCreate) => { export const updateClam = (params: Toolbox.ClamUpdate) => { return http.post(`/toolbox/clam/update`, params); }; -export const deleteClam = (params: { ids: number[] }) => { +export const deleteClam = (params: { ids: number[]; removeResult: boolean; removeInfected: boolean }) => { return http.post(`/toolbox/clam/del`, params); }; export const handleClamScan = (id: number) => { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 23a8d0597..9935c3924 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1066,18 +1066,36 @@ const message = { }, clam: { clam: 'Virus Scan', + clamHelper: + 'The minimum recommended configuration for ClamAV is: 3 GiB of RAM or more, single-core CPU with 2.0 GHz or higher, and at least 5 GiB of available hard disk space.', noClam: 'ClamAV service not detected, please refer to the official documentation for installation!', notStart: 'ClamAV service is currently not running, please start it first!', - clamCreate: 'Create Scan Rule', + removeResult: 'Delete Report Files', + removeResultHelper: 'Delete report files generated during task execution to free up storage space.', + removeInfected: 'Delete Virus Files', + removeInfectedHelper: + 'Delete virus files detected during the task to ensure server security and normal operation.', + clamCreate: 'Create Scan Rules', + infectedStrategy: 'Virus Strategy', + remove: 'Delete', + removeHelper: 'Delete virus files, choose carefully!', + move: 'Move', + moveHelper: 'Move virus files to specified directory', + copy: 'Copy', + copyHelper: 'Copy virus files to specified directory', + none: 'Do Nothing', + noneHelper: 'Take no action on virus files', + scanDir: 'Scan Directory', + infectedDir: 'Infected Directory', scanDate: 'Scan Date', - scanTime: 'Elapsed Time', - scannedFiles: 'Number of Scanned Files', - infectedFiles: 'Number of Infected Files', + scanTime: 'Time Taken', + scannedFiles: 'Scanned Files', + infectedFiles: 'Infected Files', log: 'Details', clamConf: 'Scan Configuration', - clamLog: 'Scan Log', - freshClam: 'Virus Database Refresh Configuration', - freshClamLog: 'Virus Database Refresh Log', + clamLog: 'Scan Logs', + freshClam: 'Update Virus Definitions', + freshClamLog: 'Update Virus Definitions Logs', }, }, logs: { diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 0d77f031d..b3d359829 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1008,9 +1008,26 @@ const message = { }, clam: { clam: '病毒掃描', + clamHelper: + 'ClamAV 的最低建議配置為:3 GiB 以上的 RAM,2.0 GHz 以上的單核 CPU,以及至少 5 GiB 的可用硬盤空間。', noClam: '未檢測到 ClamAV 服務,請參考官方文檔進行安裝!', - notStart: '目前沒有運行 ClamAV 服務,請先啟動!', + notStart: '當前未 ClamAV 服務,請先開啟!', + removeResult: '刪除報告文件', + removeResultHelper: '刪除任務執行過程中生成的報告文件,以清理存儲空間。', + removeInfected: '刪除病毒文件', + removeInfectedHelper: '刪除任務檢測到的病毒文件,以確保伺服器的安全和正常運行。', clamCreate: '創建掃描規則', + infectedStrategy: '病毒策略', + remove: '刪除', + removeHelper: '刪除病毒文件,請謹慎選擇!', + move: '移動', + moveHelper: '將病毒文件移動到指定目錄下', + copy: '複製', + copyHelper: '將病毒文件複製到指定目錄下', + none: '不操作', + noneHelper: '不對病毒文件採取任何操作', + scanDir: '掃描目錄', + infectedDir: '病毒目錄', scanDate: '掃描時間', scanTime: '耗時', scannedFiles: '掃描文件數', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index eb7c7336e..8604a1764 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1009,9 +1009,26 @@ const message = { }, clam: { clam: '病毒扫描', + clamHelper: + 'ClamAV 的最低建议配置为:3 GiB 以上的 RAM,2.0 GHz 以上的单核 CPU,以及至少 5 GiB 的可用硬盘空间。', noClam: '未检测到 ClamAV 服务,请参考官方文档进行安装!', notStart: '当前未 ClamAV 服务,请先开启!', + removeResult: '删除报告文件', + removeResultHelper: '删除任务执行过程中生成的报告文件,以清理存储空间。', + removeInfected: '删除病毒文件', + removeInfectedHelper: '删除任务检测到的病毒文件,以确保服务器的安全和正常运行。', clamCreate: '创建扫描规则', + infectedStrategy: '病毒策略', + remove: '删除', + removeHelper: '删除病毒文件,请谨慎选择!', + move: '移动', + moveHelper: '将病毒文件移动到指定目录下', + copy: '复制', + copyHelper: '将病毒文件复制到指定目录下', + none: '不操作', + noneHelper: '不对病毒文件采取任何操作', + scanDir: '扫描目录', + infectedDir: '病毒目录', scanDate: '扫描时间', scanTime: '耗时', scannedFiles: '扫描文件数', diff --git a/frontend/src/views/toolbox/clam/index.vue b/frontend/src/views/toolbox/clam/index.vue index bc3ce2df0..045fbd1d9 100644 --- a/frontend/src/views/toolbox/clam/index.vue +++ b/frontend/src/views/toolbox/clam/index.vue @@ -1,6 +1,21 @@