1 Commits

Author SHA1 Message Date
zhengkunwang223
201e0562b6 style: 修改 dark 主题样式 2023-07-13 16:31:04 +08:00
23 changed files with 93 additions and 157 deletions

View File

@@ -11,7 +11,6 @@ import (
"github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd" "github.com/1Panel-dev/1Panel/backend/utils/cmd"
@@ -81,11 +80,11 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
temPathWithName := tmpPath + "/" + website.Alias temPathWithName := tmpPath + "/" + website.Alias
if !fileOp.Stat(tmpPath+"/website.json") || !fileOp.Stat(temPathWithName+".conf") || !fileOp.Stat(temPathWithName+".web.tar.gz") { if !fileOp.Stat(tmpPath+"/website.json") || !fileOp.Stat(temPathWithName+".conf") || !fileOp.Stat(temPathWithName+".web.tar.gz") {
return buserr.WithDetail(constant.ErrBackupExist, ".conf or .web.tar.gz", nil) return errors.New("the wrong recovery package does not have .conf or .web.tar.gz files")
} }
if website.Type == constant.Deployment { if website.Type == constant.Deployment {
if !fileOp.Stat(temPathWithName + ".app.tar.gz") { if !fileOp.Stat(temPathWithName + ".app.tar.gz") {
return buserr.WithDetail(constant.ErrBackupExist, ".app.tar.gz", nil) return errors.New("the wrong recovery package does not have .app.tar.gz files")
} }
} }
var oldWebsite model.Website var oldWebsite model.Website
@@ -96,9 +95,8 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
if err := json.Unmarshal(websiteJson, &oldWebsite); err != nil { if err := json.Unmarshal(websiteJson, &oldWebsite); err != nil {
return fmt.Errorf("unmarshal app.json failed, err: %v", err) return fmt.Errorf("unmarshal app.json failed, err: %v", err)
} }
if oldWebsite.Alias != website.Alias || oldWebsite.Type != website.Type || oldWebsite.ID != website.ID {
if err := checkValidOfWebsite(&oldWebsite, website); err != nil { return errors.New("the current backup file does not match the application")
return err
} }
isOk := false isOk := false
@@ -157,7 +155,6 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
return errors.New(string(stdout)) return errors.New(string(stdout))
} }
oldWebsite.ID = website.ID
if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil { if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil {
global.LOG.Errorf("handle save website data failed, err: %v", err) global.LOG.Errorf("handle save website data failed, err: %v", err)
return err return err
@@ -215,29 +212,3 @@ func handleWebsiteBackup(website *model.Website, backupDir, fileName string) err
return nil return nil
} }
func checkValidOfWebsite(oldWebsite, website *model.Website) error {
if oldWebsite.Alias != website.Alias || oldWebsite.Type != website.Type {
return buserr.WithDetail(constant.ErrBackupMatch, fmt.Sprintf("oldName: %s, oldType: %v", oldWebsite.Alias, oldWebsite.Type), nil)
}
if oldWebsite.AppInstallID != 0 {
app, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
if err != nil {
return buserr.WithDetail(constant.ErrBackupMatch, "app", nil)
}
if app.App.Type != "website" {
return buserr.WithDetail(constant.ErrBackupMatch, fmt.Sprintf("appType: %s", app.App.Type), nil)
}
}
if oldWebsite.RuntimeID != 0 {
if _, err := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID)); err != nil {
return buserr.WithDetail(constant.ErrBackupMatch, "runtime", nil)
}
}
if oldWebsite.WebsiteSSLID != 0 {
if _, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(website.WebsiteSSLID)); err != nil {
return buserr.WithDetail(constant.ErrBackupMatch, "ssl", nil)
}
}
return nil
}

View File

@@ -359,10 +359,10 @@ func (u *CronjobService) handleCutWebsiteLog(cronjob *model.Cronjob, startTime t
wg.Done() wg.Done()
return return
} }
websiteLogDir := path.Join(baseDir, website.Alias, "log") websiteLogDir := path.Join(baseDir, website.PrimaryDomain, "log")
srcAccessLogPath := path.Join(websiteLogDir, "access.log") srcAccessLogPath := path.Join(websiteLogDir, "access.log")
srcErrorLogPath := path.Join(websiteLogDir, "error.log") srcErrorLogPath := path.Join(websiteLogDir, "error.log")
dstLogDir := path.Join(global.CONF.System.Backup, "log", "website", website.Alias) dstLogDir := path.Join(global.CONF.System.Backup, "log", "website", website.PrimaryDomain)
if !fileOp.Stat(dstLogDir) { if !fileOp.Stat(dstLogDir) {
_ = os.MkdirAll(dstLogDir, 0755) _ = os.MkdirAll(dstLogDir, 0755)
} }

View File

@@ -76,29 +76,29 @@ func loadDiskIO() {
if io2.Name == io1.Name { if io2.Name == io1.Name {
var itemIO model.MonitorIO var itemIO model.MonitorIO
itemIO.Name = io1.Name itemIO.Name = io1.Name
if io2.ReadBytes != 0 && io1.ReadBytes != 0 && io2.ReadBytes > io1.ReadBytes { if io2.ReadBytes != 0 && io1.ReadBytes != 0 {
itemIO.Read = uint64(float64(io2.ReadBytes-io1.ReadBytes) / 60) itemIO.Read = uint64(float64(io2.ReadBytes-io1.ReadBytes) / 60)
} }
if io2.WriteBytes != 0 && io1.WriteBytes != 0 && io2.WriteBytes > io1.WriteBytes { if io2.WriteBytes != 0 && io1.WriteBytes != 0 {
itemIO.Write = uint64(float64(io2.WriteBytes-io1.WriteBytes) / 60) itemIO.Write = uint64(float64(io2.WriteBytes-io1.WriteBytes) / 60)
} }
if io2.ReadCount != 0 && io1.ReadCount != 0 && io2.ReadCount > io1.ReadCount { if io2.ReadCount != 0 && io1.ReadCount != 0 {
itemIO.Count = uint64(float64(io2.ReadCount-io1.ReadCount) / 60) itemIO.Count = uint64(float64(io2.ReadCount-io1.ReadCount) / 60)
} }
writeCount := uint64(0) writeCount := uint64(0)
if io2.WriteCount != 0 && io1.WriteCount != 0 && io2.WriteCount > io1.WriteCount { if io2.WriteCount != 0 && io1.WriteCount != 0 {
writeCount = uint64(float64(io2.WriteCount-io1.WriteCount) / 60) writeCount = uint64(float64(io2.WriteCount-io1.WriteCount) / 60)
} }
if writeCount > itemIO.Count { if writeCount > itemIO.Count {
itemIO.Count = writeCount itemIO.Count = writeCount
} }
if io2.ReadTime != 0 && io1.ReadTime != 0 && io2.ReadTime > io1.ReadTime { if io2.ReadTime != 0 && io1.ReadTime != 0 {
itemIO.Time = uint64(float64(io2.ReadTime-io1.ReadTime) / 60) itemIO.Time = uint64(float64(io2.ReadTime-io1.ReadTime) / 60)
} }
writeTime := uint64(0) writeTime := uint64(0)
if io2.WriteTime != 0 && io1.WriteTime != 0 && io2.WriteTime > io1.WriteTime { if io2.WriteTime != 0 && io1.WriteTime != 0 {
writeTime = uint64(float64(io2.WriteTime-io1.WriteTime) / 60) writeTime = uint64(float64(io2.WriteTime-io1.WriteTime) / 60)
} }
if writeTime > itemIO.Time { if writeTime > itemIO.Time {
@@ -128,10 +128,10 @@ func loadNetIO() {
var itemNet model.MonitorNetwork var itemNet model.MonitorNetwork
itemNet.Name = net1.Name itemNet.Name = net1.Name
if net2.BytesSent != 0 && net1.BytesSent != 0 && net2.BytesSent > net1.BytesSent { if net2.BytesSent != 0 && net1.BytesSent != 0 {
itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / 60 itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / 60
} }
if net2.BytesRecv != 0 && net1.BytesRecv != 0 && net2.BytesRecv > net1.BytesRecv { if net2.BytesRecv != 0 && net1.BytesRecv != 0 {
itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / 60 itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / 60
} }
netList = append(netList, itemNet) netList = append(netList, itemNet)
@@ -145,13 +145,21 @@ func loadNetIO() {
if net2.Name == net1.Name { if net2.Name == net1.Name {
var itemNet model.MonitorNetwork var itemNet model.MonitorNetwork
itemNet.Name = net1.Name itemNet.Name = net1.Name
if net2.BytesSent != 0 && net1.BytesSent != 0 && net2.BytesSent > net1.BytesSent { if net2.BytesSent != 0 && net1.BytesSent != 0 {
itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / 60 itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / 60
} }
if itemNet.Up > 10485760 {
itemNet.Up = 0
global.LOG.Errorf("net2: %v, net1: %v, BytesSent: %v \n", net2.BytesSent, net1.BytesSent, float64(net2.BytesSent-net1.BytesSent)/1024/60)
}
if net2.BytesRecv != 0 && net1.BytesRecv != 0 && net2.BytesRecv > net1.BytesRecv { if net2.BytesRecv != 0 && net1.BytesRecv != 0 {
itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / 60 itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / 60
} }
if itemNet.Down > 10485760 {
itemNet.Down = 0
global.LOG.Errorf("net2: %v, net1: %v, BytesRecv: %v \n", net2.BytesRecv, net1.BytesRecv, float64(net2.BytesRecv-net1.BytesRecv)/1024/60)
}
netList = append(netList, itemNet) netList = append(netList, itemNet)
break break
} }

View File

@@ -536,10 +536,6 @@ func opWebsite(website *model.Website, operate string) error {
if files.NewFileOp().Stat(absoluteRewritePath) { if files.NewFileOp().Stat(absoluteRewritePath) {
server.UpdateDirective("include", []string{rewriteInclude}) server.UpdateDirective("include", []string{rewriteInclude})
} }
rootIndex := path.Join("/www/sites", website.Alias, "index")
if website.SiteDir != "/" {
rootIndex = path.Join(rootIndex, website.SiteDir)
}
switch website.Type { switch website.Type {
case constant.Deployment: case constant.Deployment:
server.RemoveDirective("root", nil) server.RemoveDirective("root", nil)
@@ -550,11 +546,12 @@ func opWebsite(website *model.Website, operate string) error {
proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort) proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort)
server.UpdateRootProxy([]string{proxy}) server.UpdateRootProxy([]string{proxy})
case constant.Static: case constant.Static:
server.UpdateRoot(rootIndex) server.UpdateRoot(path.Join("/www/sites", website.Alias, "index"))
server.UpdateRootLocation() server.UpdateRootLocation()
case constant.Proxy: case constant.Proxy:
server.RemoveDirective("root", nil) server.RemoveDirective("root", nil)
case constant.Runtime: case constant.Runtime:
rootIndex := path.Join("/www/sites", website.Alias, "index")
server.UpdateRoot(rootIndex) server.UpdateRoot(rootIndex)
localPath := "" localPath := ""
if website.ProxyType == constant.RuntimeProxyUnix { if website.ProxyType == constant.RuntimeProxyUnix {

View File

@@ -68,8 +68,6 @@ var (
ErrGroupIsUsed = "ErrGroupIsUsed" ErrGroupIsUsed = "ErrGroupIsUsed"
ErrUsernameIsExist = "ErrUsernameIsExist" ErrUsernameIsExist = "ErrUsernameIsExist"
ErrUsernameIsNotExist = "ErrUsernameIsNotExist" ErrUsernameIsNotExist = "ErrUsernameIsNotExist"
ErrBackupMatch = "ErrBackupMatch"
ErrBackupExist = "ErrBackupExist"
) )
// ssl // ssl

View File

@@ -59,8 +59,6 @@ ErrDomainIsExist: "Domain is already exist"
ErrAliasIsExist: "Alias is already exist" ErrAliasIsExist: "Alias is already exist"
ErrAppDelete: 'Other Website use this App' ErrAppDelete: 'Other Website use this App'
ErrGroupIsUsed: 'The group is in use and cannot be deleted' ErrGroupIsUsed: 'The group is in use and cannot be deleted'
ErrBackupMatch: 'the backup file does not match the current partial data of the website: {{ .detail}}"'
ErrBackupExist: 'the backup file corresponds to a portion of the original data that does not exist: {{ .detail}}"'
#ssl #ssl
ErrSSLCannotDelete: "The certificate is being used by the website and cannot be removed" ErrSSLCannotDelete: "The certificate is being used by the website and cannot be removed"

View File

@@ -59,8 +59,6 @@ ErrDomainIsExist: "域名已存在"
ErrAliasIsExist: "代號已存在" ErrAliasIsExist: "代號已存在"
ErrAppDelete: '其他網站使用此應用,無法刪除' ErrAppDelete: '其他網站使用此應用,無法刪除'
ErrGroupIsUsed: '分組正在使用中,無法刪除' ErrGroupIsUsed: '分組正在使用中,無法刪除'
ErrBackupMatch: '該備份文件與當前網站部分數據不匹配: {{ .detail}}"'
ErrBackupExist: '該備份文件對應部分原數據不存在: {{ .detail}}"'
#ssl #ssl
ErrSSLCannotDelete: "證書正在被網站使用,無法刪除" ErrSSLCannotDelete: "證書正在被網站使用,無法刪除"

View File

@@ -59,8 +59,6 @@ ErrDomainIsExist: "域名已存在"
ErrAliasIsExist: "代号已存在" ErrAliasIsExist: "代号已存在"
ErrAppDelete: '其他网站使用此应用,无法删除' ErrAppDelete: '其他网站使用此应用,无法删除'
ErrGroupIsUsed: '分组正在使用中,无法删除' ErrGroupIsUsed: '分组正在使用中,无法删除'
ErrBackupMatch: '该备份文件与当前网站部分数据不匹配 {{ .detail}}"'
ErrBackupExist: '该备份文件对应部分源数据不存在 {{ .detail}}"'
#ssl #ssl
ErrSSLCannotDelete: "证书正在被网站使用,无法删除" ErrSSLCannotDelete: "证书正在被网站使用,无法删除"

View File

@@ -174,7 +174,7 @@ const checkLinuxName = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) { if (value === '' || typeof value === 'undefined' || value == null) {
callback(new Error(i18n.global.t('commons.rule.linuxName', ['/\\:*?\'"<>|']))); callback(new Error(i18n.global.t('commons.rule.linuxName', ['/\\:*?\'"<>|'])));
} else { } else {
const reg = /^[^/\\\"'|<>?*]{1,128}$/; const reg = /^[^/\\\"'|<>?*]{1,30}$/;
if (!reg.test(value) && value !== '') { if (!reg.test(value) && value !== '') {
callback(new Error(i18n.global.t('commons.rule.linuxName', ['/\\:*?\'"<>|']))); callback(new Error(i18n.global.t('commons.rule.linuxName', ['/\\:*?\'"<>|'])));
} else { } else {
@@ -402,7 +402,7 @@ const checkParamSimple = (rule: any, value: any, callback: any) => {
if (value === '' || typeof value === 'undefined' || value == null) { if (value === '' || typeof value === 'undefined' || value == null) {
callback(); callback();
} else { } else {
const reg = /^[a-z0-9][a-z0-9]{1,128}$/; const reg = /^[a-z0-9][a-z0-9]{1,64}$/;
if (!reg.test(value) && value !== '') { if (!reg.test(value) && value !== '') {
callback(new Error(i18n.global.t('commons.rule.paramSimple'))); callback(new Error(i18n.global.t('commons.rule.paramSimple')));
} else { } else {

View File

@@ -159,7 +159,6 @@ const message = {
complexityPassword: complexityPassword:
'Longer than eight characters and contains at least two combinations of letters, digits, and special characters', 'Longer than eight characters and contains at least two combinations of letters, digits, and special characters',
commonPassword: 'Please enter a password with more than 6 characters', commonPassword: 'Please enter a password with more than 6 characters',
linuxName: 'Length 1-128, the name cannot contain symbols such as {0}',
email: 'Email format error', email: 'Email format error',
number: 'Please enter the correct number', number: 'Please enter the correct number',
integer: 'Please enter the correct positive integer', integer: 'Please enter the correct positive integer',
@@ -181,7 +180,7 @@ const message = {
'Supports letters, numbers, underscores, hyphens and dots, cannot end with hyphen- or dot.1-127', 'Supports letters, numbers, underscores, hyphens and dots, cannot end with hyphen- or dot.1-127',
disableFunction: 'Only support letters and,', disableFunction: 'Only support letters and,',
leechExts: 'Only support letters, numbers and,', leechExts: 'Only support letters, numbers and,',
paramSimple: 'Support lowercase letters and numbers, length 1-128', paramSimple: 'Support lowercase letters and numbers, length 1-64',
}, },
res: { res: {
paramError: 'The request failed, please try again later!', paramError: 'The request failed, please try again later!',
@@ -356,7 +355,7 @@ const message = {
threadCacheHitHelper: 'If it is too low, increase thread_cache_size', threadCacheHitHelper: 'If it is too low, increase thread_cache_size',
indexHit: 'Index hit', indexHit: 'Index hit',
indexHitHelper: 'If it is too low, increase key_buffer_size', indexHitHelper: 'If it is too low, increase key_buffer_size',
innodbIndexHit: 'Innodb index hit rate', innodbIndexHit: 'Innodb 索引命中率',
innodbIndexHitHelper: 'If it is too low, increase innodb_buffer_pool_size', innodbIndexHitHelper: 'If it is too low, increase innodb_buffer_pool_size',
cacheHit: 'Querying the Cache Hit', cacheHit: 'Querying the Cache Hit',
cacheHitHelper: 'If it is too low, increase query_cache_size', cacheHitHelper: 'If it is too low, increase query_cache_size',
@@ -444,8 +443,7 @@ const message = {
localIP: 'Local IP', localIP: 'Local IP',
}, },
container: { container: {
create: 'Create container', createContainer: 'Create container',
edit: 'Edit container',
updateContaienrHelper: updateContaienrHelper:
'Container editing requires rebuilding the container. Any data that has not been persisted will be lost. Do you want to continue?', 'Container editing requires rebuilding the container. Any data that has not been persisted will be lost. Do you want to continue?',
containerList: 'Container list', containerList: 'Container list',
@@ -651,13 +649,13 @@ const message = {
startIn: ' to start', startIn: ' to start',
}, },
cronjob: { cronjob: {
cronTask: 'Cronjob', cronTask: 'Task',
changeStatus: 'Change status', changeStatus: 'Change status',
disableMsg: disableMsg:
'Stopping the scheduled task will result in the task no longer automatically executing. Do you want to continue?', 'Stopping the scheduled task will result in the task no longer automatically executing. Do you want to continue?',
enableMsg: enableMsg:
'Enabling the scheduled task will allow the task to automatically execute on a regular basis. Do you want to continue?', 'Enabling the scheduled task will allow the task to automatically execute on a regular basis. Do you want to continue?',
taskType: 'Cronjob type', taskType: 'Task type',
record: 'Records', record: 'Records',
shell: 'Shell script', shell: 'Shell script',
containerCheckBox: 'In container (no need to enter the container command)', containerCheckBox: 'In container (no need to enter the container command)',
@@ -675,7 +673,7 @@ const message = {
syncDate: 'Synchronization time ', syncDate: 'Synchronization time ',
releaseMemory: 'Free memory', releaseMemory: 'Free memory',
curl: 'Access URL', curl: 'Access URL',
taskName: 'Cronjob name', taskName: 'Task name',
cronSpec: 'Lifecycle', cronSpec: 'Lifecycle',
cronSpecHelper: 'Enter the correct execution period', cronSpecHelper: 'Enter the correct execution period',
cleanHelper: cleanHelper:
@@ -712,7 +710,7 @@ const message = {
sunday: 'Sunday', sunday: 'Sunday',
shellContent: 'Script content', shellContent: 'Script content',
errRecord: 'Incorrect logging', errRecord: 'Incorrect logging',
errHandle: 'Cronjob execution failure', errHandle: 'Task execution failure',
noRecord: 'The execution did not generate any logs', noRecord: 'The execution did not generate any logs',
cleanData: 'Clean data', cleanData: 'Clean data',
cleanDataHelper: 'Delete the backup file generated during this task.', cleanDataHelper: 'Delete the backup file generated during this task.',
@@ -1019,7 +1017,7 @@ const message = {
entranceInputHelper: 'When the security entry is set to blank, the security entry is cancelled.', entranceInputHelper: 'When the security entry is set to blank, the security entry is cancelled.',
randomGenerate: 'Random', randomGenerate: 'Random',
expirationTime: 'Expiration Time', expirationTime: 'Expiration Time',
unSetting: 'Unset', unSetting: 'Not Set',
noneSetting: noneSetting:
'Set the expiration time for the panel password. After the expiration, you need to reset the password', 'Set the expiration time for the panel password. After the expiration, you need to reset the password',
expirationHelper: 'If the password expiration time is [0] days, the password expiration function is disabled', expirationHelper: 'If the password expiration time is [0] days, the password expiration function is disabled',
@@ -1319,7 +1317,7 @@ const message = {
startHelper: startHelper:
'After enabling the site, users can access the content of the site normally, do you want to continue? ', 'After enabling the site, users can access the content of the site normally, do you want to continue? ',
sitePath: 'Website Directory', sitePath: 'Website Directory',
siteAlias: 'Site Alias', siteAlias: 'Site Path Name',
primaryPath: 'Main directory', primaryPath: 'Main directory',
folderTitle: 'The main directory of the website mainly contains four folders', folderTitle: 'The main directory of the website mainly contains four folders',
wafFolder: 'Firewall Rules', wafFolder: 'Firewall Rules',
@@ -1419,11 +1417,11 @@ const message = {
'The password is asymmetrically encrypted and cannot be echoed. Editing needs to reset the password', 'The password is asymmetrically encrypted and cannot be echoed. Editing needs to reset the password',
antiLeech: 'Anti-leech', antiLeech: 'Anti-leech',
extends: 'Extension', extends: 'Extension',
browserCache: 'Cache', browserCache: 'browser cache',
leechLog: 'Record anti-leech log', leechLog: 'Record anti-leech log',
accessDomain: 'Allowed domains', accessDomain: 'Allowed domain names',
leechReturn: 'Response resource', leechReturn: 'Response resource',
noneRef: 'Allow empty source', noneRef: 'Allow the source to be empty',
disable: 'not enabled', disable: 'not enabled',
disableLeechHelper: 'Whether to disable the anti-leech', disableLeechHelper: 'Whether to disable the anti-leech',
disableLeech: 'Disable anti-leech', disableLeech: 'Disable anti-leech',
@@ -1501,8 +1499,6 @@ const message = {
acmeHelper: 'Acme account is used to apply for free certificates', acmeHelper: 'Acme account is used to apply for free certificates',
}, },
firewall: { firewall: {
create: 'Create rule',
edit: 'Edit rule',
notSupport: notSupport:
'No system firewall detected (firewalld or ufw). Please refer to the official documentation for installation.', 'No system firewall detected (firewalld or ufw). Please refer to the official documentation for installation.',
ccDeny: 'CC Protection', ccDeny: 'CC Protection',
@@ -1618,8 +1614,7 @@ const message = {
laddr: 'Source address/port', laddr: 'Source address/port',
raddr: 'Destination address/port', raddr: 'Destination address/port',
stopProcess: 'End', stopProcess: 'End',
stopProcessWarn: 'Are you sure you want to end this process (PID:{0})? ', stopProcessWarn: 'Are you sure you want to end this process (PID:{0})? This operation cannot be rolled back',
processName: 'ProcessName',
}, },
}; };

View File

@@ -159,7 +159,7 @@ const message = {
volumeName: '支持英文數字.-和_,長度2-30', volumeName: '支持英文數字.-和_,長度2-30',
complexityPassword: '請輸入長度大於 8 位且包含字母數字特殊字符至少兩項的密碼組合', complexityPassword: '請輸入長度大於 8 位且包含字母數字特殊字符至少兩項的密碼組合',
commonPassword: '請輸入 6 位以上長度密碼', commonPassword: '請輸入 6 位以上長度密碼',
linuxName: '長度1-128名稱不能含有{0}等符號', linuxName: '長度1-30名稱不能含有{0}等符號',
email: '請輸入正確的郵箱', email: '請輸入正確的郵箱',
number: '請輸入正確的數字', number: '請輸入正確的數字',
integer: '請輸入正確的正整數', integer: '請輸入正確的正整數',
@@ -179,7 +179,7 @@ const message = {
containerName: '支持字母數字下劃線連字符和點,不能以連字符-或點.結尾,長度1-127', containerName: '支持字母數字下劃線連字符和點,不能以連字符-或點.結尾,長度1-127',
disableFunction: '僅支持字母和,', disableFunction: '僅支持字母和,',
leechExts: '僅支持字母數字和,', leechExts: '僅支持字母數字和,',
paramSimple: '支持小寫字母和數字,長度 1-128', paramSimple: '支持小寫字母和數字,長度1-64',
}, },
res: { res: {
paramError: '請求失敗,請稍後重試!', paramError: '請求失敗,請稍後重試!',
@@ -1530,8 +1530,7 @@ const message = {
laddr: '源地址/端口', laddr: '源地址/端口',
raddr: '目標地址/端口', raddr: '目標地址/端口',
stopProcess: '結束', stopProcess: '結束',
stopProcessWarn: '是否確定結束此進程 (PID:{0})', stopProcessWarn: '是否確定結束此進程 (PID:{0})此操作不可回滾',
processName: '進程名稱',
}, },
}; };
export default { export default {

View File

@@ -159,7 +159,7 @@ const message = {
volumeName: '支持英文数字.-和_,长度2-30', volumeName: '支持英文数字.-和_,长度2-30',
complexityPassword: '请输入长度大于 8 位且包含字母数字特殊字符至少两项的密码组合', complexityPassword: '请输入长度大于 8 位且包含字母数字特殊字符至少两项的密码组合',
commonPassword: '请输入 6 位以上长度密码', commonPassword: '请输入 6 位以上长度密码',
linuxName: '长度1-128名称不能含有{0}等符号', linuxName: '长度1-30名称不能含有{0}等符号',
email: '请输入正确的邮箱', email: '请输入正确的邮箱',
number: '请输入正确的数字', number: '请输入正确的数字',
integer: '请输入正确的正整数', integer: '请输入正确的正整数',
@@ -179,7 +179,7 @@ const message = {
containerName: '支持字母数字下划线连字符和点,不能以连字符-或点.结尾,长度1-127', containerName: '支持字母数字下划线连字符和点,不能以连字符-或点.结尾,长度1-127',
disableFunction: '仅支持字母和,', disableFunction: '仅支持字母和,',
leechExts: '仅支持字母数字和,', leechExts: '仅支持字母数字和,',
paramSimple: '支持小写字母和数字,长度1-128', paramSimple: '支持小写字母和数字,长度1-64',
}, },
res: { res: {
paramError: '请求失败,请稍后重试!', paramError: '请求失败,请稍后重试!',
@@ -1538,7 +1538,7 @@ const message = {
laddr: '源地址/端口', laddr: '源地址/端口',
raddr: '目标地址/端口', raddr: '目标地址/端口',
stopProcess: '结束', stopProcess: '结束',
stopProcessWarn: '是否确定结束此进程 (PID:{0})', stopProcessWarn: '是否确定结束此进程 (PID:{0})此操作不可回滚',
processName: '进程名称', processName: '进程名称',
}, },
}; };

View File

@@ -1,21 +1,9 @@
html.dark { html.dark {
--el-box-shadow-light: 0px 0px 4px rgba(0, 0, 0, 0.1) !important;
--el-border-color-lighter: #1d2023;
--el-fill-color-blank: #111417;
--el-bg-color: rgba(0, 11, 21, 1);
// --el-text-color-primary: #999999;
--el-text-color-regular: #bbbfc4 !important;
--el-fill-color-light: #111417;
--el-border-color: #303438;
--el-bg-color-overlay: rgba(0, 11, 21, 1);
--el-border-color-light: #1d2023;
// * menu
--el-menu-bg-color: #111417 !important;
--el-menu-item-bg-color: #111417;
--el-menu-text-color: #ffffff;
--el-menu-item-bg-color-active: rgb(44, 45, 46);
// * panel-admin // * panel-admin
--panel-bg-color: #1f1f1f;
--panel-border-color: #363b3f;
--panel-main-txt-color: #ebebeb;
--panel-text-color: rgb(174, 166, 153); --panel-text-color: rgb(174, 166, 153);
--panel-border: 1px solid #1d2023; --panel-border: 1px solid #1d2023;
--panel-border-color: #394c5e; --panel-border-color: #394c5e;
@@ -29,12 +17,28 @@ html.dark {
--panel-path-bg: #2f3030; --panel-path-bg: #2f3030;
--panel-button-disabled: #5a5a5a; --panel-button-disabled: #5a5a5a;
--el-box-shadow-light: 0px 0px 4px rgba(0, 0, 0, 0.1) !important;
--el-border-color-lighter: #1d2023;
--el-fill-color-blank: var(--panel-bg-color);
--el-bg-color: rgba(0, 11, 21, 1);
// --el-text-color-primary: #999999;
--el-text-color-regular: #bbbfc4 !important;
--el-fill-color-light: var(--panel-bg-color);
--el-border-color: #303438;
--el-bg-color-overlay: rgba(0, 11, 21, 1);
--el-border-color-light: #1d2023;
// * menu
--el-menu-bg-color: var(--panel-bg-color) !important;
--el-menu-item-bg-color: var(--panel-bg-color);
--el-menu-text-color: var(--panel-main-txt-color);
--el-menu-item-bg-color-active: rgb(44, 45, 46);
.el-tag.el-tag--info { .el-tag.el-tag--info {
--el-tag-bg-color: rgb(49, 51, 51); --el-tag-bg-color: rgb(49, 51, 51);
--el-tag-border-color: rgb(64, 67, 67); --el-tag-border-color: rgb(64, 67, 67);
} }
.el-tag.el-tag--light { .el-tag.el-tag--light {
--el-tag-bg-color: #111417; --el-tag-bg-color: var(--panel-bg-color);
--el-tag-border-color: var(--el-color-primary); --el-tag-border-color: var(--el-color-primary);
} }
.el-tag.el-tag--success { .el-tag.el-tag--success {
@@ -44,9 +48,9 @@ html.dark {
--el-tag-border-color: var(--el-color-danger); --el-tag-border-color: var(--el-color-danger);
} }
.el-card { .el-card {
--el-card-bg-color: #111417; --el-card-bg-color: var(--panel-bg-color);
color: #ffffff; color: var(--panel-main-txt-color);
border: 1px solid var(--el-card-border-color) !important; border: 1px solid var(--panel-border-color) !important;
} }
.el-table { .el-table {
@@ -84,7 +88,7 @@ html.dark {
--w-e-textarea-color: #eeeeee; --w-e-textarea-color: #eeeeee;
.md-editor-dark { .md-editor-dark {
--md-bk-color: #111417; --md-bk-color: var(--panel-bg-color);
} }
// * 以下为自定义暗黑模式内容 // * 以下为自定义暗黑模式内容
@@ -98,7 +102,7 @@ html.dark {
transition: background-color 1000s ease-out 0.5s; transition: background-color 1000s ease-out 0.5s;
} }
.el-input__wrapper { .el-input__wrapper {
background-color: #ffffff; background-color: var(--panel-main-txt-color);
box-shadow: 0 0 0 1px #dcdfe6 inset; box-shadow: 0 0 0 1px #dcdfe6 inset;
} }
.el-input__inner { .el-input__inner {
@@ -131,18 +135,18 @@ html.dark {
} }
&.is-active { &.is-active {
background: var(--el-color-primary); background: var(--el-color-primary);
color: #ffffff; color: var(--panel-main-txt-color);
&:hover { &:hover {
.el-icon { .el-icon {
color: #ffffff !important; color: var(--panel-main-txt-color) !important;
} }
span { span {
color: #ffffff !important; color: var(--panel-main-txt-color) !important;
} }
} }
&::before { &::before {
background: #ffffff; background: var(--panel-main-txt-color);
} }
} }
} }
@@ -171,7 +175,7 @@ html.dark {
.mobile-header { .mobile-header {
background-color: var(--panel-main-bg-color) !important; background-color: var(--panel-main-bg-color) !important;
border-bottom: var(--panel-border); border-bottom: var(--panel-border);
color: #ffffff; color: var(--panel-main-txt-color);
} }
} }
.system-label { .system-label {
@@ -183,7 +187,7 @@ html.dark {
background: none; background: none;
} }
.el-radio-button__original-radio:checked + .el-radio-button__inner { .el-radio-button__original-radio:checked + .el-radio-button__inner {
color: #ffffff; color: var(--panel-main-txt-color);
box-shadow: none !important; box-shadow: none !important;
} }
} }
@@ -240,7 +244,7 @@ html.dark {
transition: background-color 1000s ease-out 0.5s; transition: background-color 1000s ease-out 0.5s;
} }
.el-avatar { .el-avatar {
--el-avatar-bg-color: #111417 !important; --el-avatar-bg-color: var(--panel-bg-color) !important;
box-shadow: 0px 0px 4px rgba(0, 94, 235, 0.1); box-shadow: 0px 0px 4px rgba(0, 94, 235, 0.1);
border: 0.5px solid #1f2022; border: 0.5px solid #1f2022;
} }
@@ -306,10 +310,4 @@ html.dark {
background-color: rgb(56, 59, 59); background-color: rgb(56, 59, 59);
color: var(--el-color-warning); color: var(--el-color-warning);
} }
.el-dropdown-menu__item.is-disabled {
color: var(--panel-button-disabled);
}
.el-date-editor .el-range-separator {
color: var(--panel-button-disabled);
}
} }

View File

@@ -21,7 +21,7 @@
:type="activeTag === item.key ? 'primary' : ''" :type="activeTag === item.key ? 'primary' : ''"
:plain="activeTag !== item.key" :plain="activeTag !== item.key"
> >
{{ language == 'zh' || language == 'tw' ? item.name : item.key }} {{ item.name }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -271,7 +271,6 @@ import { getAge } from '@/utils/util';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { toFolder } from '@/global/business'; import { toFolder } from '@/global/business';
import { useI18n } from 'vue-i18n';
const data = ref<any>(); const data = ref<any>();
const loading = ref(false); const loading = ref(false);
@@ -309,8 +308,6 @@ const router = useRouter();
const activeName = ref(i18n.global.t('app.installed')); const activeName = ref(i18n.global.t('app.installed'));
const mode = ref('installed'); const mode = ref('installed');
const language = useI18n().locale.value;
const sync = () => { const sync = () => {
syncLoading.value = true; syncLoading.value = true;
SyncInstalledApp() SyncInstalledApp()

View File

@@ -66,7 +66,7 @@
fix fix
:formatter="dateFormat" :formatter="dateFormat"
/> />
<fu-table-operations width="200px" :buttons="buttons" :label="$t('commons.table.operate')" /> <fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" />
</ComplexTable> </ComplexTable>
</template> </template>
</LayoutContent> </LayoutContent>

View File

@@ -80,7 +80,7 @@
<el-table-column :label="$t('cronjob.cronSpec')" :min-width="120"> <el-table-column :label="$t('cronjob.cronSpec')" :min-width="120">
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.specType.indexOf('N') === -1 || row.specType === 'perWeek'"> <span v-if="row.specType.indexOf('N') === -1 || row.specType === 'perWeek'">
{{ $t('cronjob.' + row.specType) }}&nbsp; {{ $t('cronjob.' + row.specType) }}
</span> </span>
<span v-else>{{ $t('cronjob.per') }}</span> <span v-else>{{ $t('cronjob.per') }}</span>
<span v-if="row.specType === 'perMonth'"> <span v-if="row.specType === 'perMonth'">
@@ -123,7 +123,7 @@
</template> </template>
</el-table-column> </el-table-column>
<fu-table-operations <fu-table-operations
width="300px" width="200px"
:buttons="buttons" :buttons="buttons"
:ellipsis="10" :ellipsis="10"
:label="$t('commons.table.operate')" :label="$t('commons.table.operate')"

View File

@@ -126,7 +126,7 @@
<div v-if="chartOption === 'io'" style="margin-top: 40px" class="mobile-monitor-chart"> <div v-if="chartOption === 'io'" style="margin-top: 40px" class="mobile-monitor-chart">
<v-charts <v-charts
height="360px" height="305px"
id="ioChart" id="ioChart"
type="line" type="line"
:option="chartsOption['ioChart']" :option="chartsOption['ioChart']"
@@ -136,7 +136,7 @@
</div> </div>
<div v-if="chartOption === 'network'" style="margin-top: 40px" class="mobile-monitor-chart"> <div v-if="chartOption === 'network'" style="margin-top: 40px" class="mobile-monitor-chart">
<v-charts <v-charts
height="360px" height="305px"
id="networkChart" id="networkChart"
type="line" type="line"
:option="chartsOption['networkChart']" :option="chartsOption['networkChart']"

View File

@@ -156,7 +156,7 @@
:ellipsis="3" :ellipsis="3"
:buttons="buttons" :buttons="buttons"
:label="$t('commons.table.operate')" :label="$t('commons.table.operate')"
min-width="300" min-width="200"
fixed="right" fixed="right"
fix fix
/> />

View File

@@ -424,10 +424,6 @@ function initCharts(chartName: string, xDatas: any, yDatas: any, yTitle: string,
}, },
legend: { legend: {
data: chartName === 'loadNetworkChart' && [i18n.global.t('monitor.up'), i18n.global.t('monitor.down')], data: chartName === 'loadNetworkChart' && [i18n.global.t('monitor.up'), i18n.global.t('monitor.down')],
textStyle: {
color: '#646A73',
},
icon: 'circle',
}, },
grid: { grid: {
left: getSideWidth(chartName == 'loadNetworkChart'), left: getSideWidth(chartName == 'loadNetworkChart'),
@@ -485,10 +481,6 @@ function initLoadCharts(item: Monitor.MonitorData) {
'15 ' + i18n.global.t('commons.units.minute'), '15 ' + i18n.global.t('commons.units.minute'),
i18n.global.t('monitor.resourceUsage'), i18n.global.t('monitor.resourceUsage'),
], ],
textStyle: {
color: '#646A73',
},
icon: 'circle',
}, },
grid: { left: '7%', right: '7%', bottom: '20%' }, grid: { left: '7%', right: '7%', bottom: '20%' },
xAxis: { xAxis: {
@@ -646,10 +638,6 @@ function initIOCharts(item: Monitor.MonitorData) {
i18n.global.t('monitor.readWriteCount'), i18n.global.t('monitor.readWriteCount'),
i18n.global.t('monitor.readWriteTime'), i18n.global.t('monitor.readWriteTime'),
], ],
textStyle: {
color: '#646A73',
},
icon: 'circle',
}, },
grid: { left: getSideWidth(true), right: getSideWidth(true), bottom: '20%' }, grid: { left: getSideWidth(true), right: getSideWidth(true), bottom: '20%' },
xAxis: { xAxis: {
@@ -771,21 +759,12 @@ function changeChartSize() {
echarts.getInstanceByDom(document.getElementById('loadNetworkChart') as HTMLElement)?.resize(); echarts.getInstanceByDom(document.getElementById('loadNetworkChart') as HTMLElement)?.resize();
} }
function disposeChart() {
echarts.getInstanceByDom(document.getElementById('loadLoadChart') as HTMLElement)?.dispose();
echarts.getInstanceByDom(document.getElementById('loadCPUChart') as HTMLElement)?.dispose();
echarts.getInstanceByDom(document.getElementById('loadMemoryChart') as HTMLElement)?.dispose();
echarts.getInstanceByDom(document.getElementById('loadIOChart') as HTMLElement)?.dispose();
echarts.getInstanceByDom(document.getElementById('loadNetworkChart') as HTMLElement)?.dispose();
}
onMounted(() => { onMounted(() => {
zoomStart.value = dateFormatWithoutYear(new Date(new Date().setHours(0, 0, 0, 0))); zoomStart.value = dateFormatWithoutYear(new Date(new Date().setHours(0, 0, 0, 0)));
loadNetworkOptions(); loadNetworkOptions();
window.addEventListener('resize', changeChartSize); window.addEventListener('resize', changeChartSize);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
disposeChart();
window.removeEventListener('resize', changeChartSize); window.removeEventListener('resize', changeChartSize);
}); });
</script> </script>

View File

@@ -54,7 +54,7 @@
<el-col :span="1"><br /></el-col> <el-col :span="1"><br /></el-col>
<el-col :xs="24" :sm="20" :md="20" :lg="10" :xl="10"> <el-col :xs="24" :sm="20" :md="20" :lg="10" :xl="10">
<el-form :model="form" label-position="left" ref="formRef" label-width="120px"> <el-form :model="form" label-position="left" ref="formRef" label-width="120px">
<el-form-item :label="$t('commons.table.port')" prop="port"> <el-form-item :label="$t('ssh.port')" prop="port">
<el-input disabled v-model.number="form.port"> <el-input disabled v-model.number="form.port">
<template #append> <template #append>
<el-button @click="onChangePort" icon="Setting"> <el-button @click="onChangePort" icon="Setting">

View File

@@ -8,12 +8,12 @@
size="30%" size="30%"
> >
<template #header> <template #header>
<DrawerHeader :header="$t('commons.table.port')" :back="handleClose" /> <DrawerHeader :header="$t('ssh.port')" :back="handleClose" />
</template> </template>
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading"> <el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
<el-row type="flex" justify="center"> <el-row type="flex" justify="center">
<el-col :span="22"> <el-col :span="22">
<el-form-item :label="$t('commons.table.port')" prop="port" :rules="Rules.port"> <el-form-item :label="$t('ssh.port')" prop="port" :rules="Rules.port">
<el-input clearable v-model.number="form.port" /> <el-input clearable v-model.number="form.port" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -63,7 +63,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
formEl.validate(async (valid) => { formEl.validate(async (valid) => {
if (!valid) return; if (!valid) return;
ElMessageBox.confirm( ElMessageBox.confirm(
i18n.global.t('ssh.sshChangeHelper', [i18n.global.t('commons.table.port'), form.port]), i18n.global.t('ssh.sshChangeHelper', [i18n.global.t('ssh.port'), form.port]),
i18n.global.t('ssh.sshChange'), i18n.global.t('ssh.sshChange'),
{ {
confirmButtonText: i18n.global.t('commons.button.confirm'), confirmButtonText: i18n.global.t('commons.button.confirm'),

View File

@@ -7,7 +7,7 @@
:rules="rules" :rules="rules"
ref="leechRef" ref="leechRef"
label-position="right" label-position="right"
label-width="180px" label-width="120px"
class="moblie-form" class="moblie-form"
> >
<el-form-item :label="$t('website.enableOrNot')"> <el-form-item :label="$t('website.enableOrNot')">

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-row :gutter="20" v-loading="loading"> <el-row :gutter="20" v-loading="loading">
<el-col :xs="24" :sm="18" :md="8" :lg="8" :xl="8"> <el-col :xs="24" :sm="18" :md="8" :lg="8" :xl="8">
<el-form ref="websiteForm" label-position="right" label-width="150px" :model="form" :rules="rules"> <el-form ref="websiteForm" label-position="right" label-width="80px" :model="form" :rules="rules">
<el-form-item :label="$t('website.primaryDomain')" prop="primaryDomain"> <el-form-item :label="$t('website.primaryDomain')" prop="primaryDomain">
<el-input v-model="form.primaryDomain" disabled></el-input> <el-input v-model="form.primaryDomain" disabled></el-input>
</el-form-item> </el-form-item>