From af3e358a6a837da1de811e45327b7147b983e150 Mon Sep 17 00:00:00 2001 From: whyour Date: Thu, 27 Feb 2025 00:45:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=AE=BE=E7=BD=AE=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=97=B6=E5=8C=BA=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/system.ts | 18 ++ back/config/util.ts | 18 +- back/data/system.ts | 1 + back/services/system.ts | 23 +- shell/update.sh | 3 + src/locales/en-US.json | 3 +- src/locales/zh-CN.json | 3 +- src/pages/setting/index.less | 10 + src/pages/setting/other.tsx | 31 +++ src/utils/const.ts | 451 ++++++++++++++++++++++++++++++++++- 10 files changed, 556 insertions(+), 5 deletions(-) diff --git a/back/api/system.ts b/back/api/system.ts index c6376344..01f39818 100644 --- a/back/api/system.ts +++ b/back/api/system.ts @@ -396,4 +396,22 @@ export default (app: Router) => { } }, ); + + route.put( + '/config/timezone', + celebrate({ + body: Joi.object({ + timezone: Joi.string().allow('').allow(null), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + try { + const systemService = Container.get(SystemService); + const result = await systemService.updateTimezone(req.body); + res.send(result); + } catch (e) { + return next(e); + } + }, + ); }; diff --git a/back/config/util.ts b/back/config/util.ts index 17536f6d..47e3c923 100644 --- a/back/config/util.ts +++ b/back/config/util.ts @@ -527,7 +527,7 @@ export function safeJSONParse(value?: string) { try { return JSON.parse(value); } catch (error) { - Logger.error('[JSON.parse失败]', error); + Logger.error('[safeJSONParse失败]', error); return {}; } } @@ -542,3 +542,19 @@ export async function rmPath(path: string) { Logger.error('[rmPath失败]', error); } } + +export async function setSystemTimezone(timezone: string): Promise { + try { + if (!(await fileExist(`/usr/share/zoneinfo/${timezone}`))) { + throw new Error('Invalid timezone'); + } + + await promiseExec(`ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime`); + await promiseExec(`echo "${timezone}" > /etc/timezone`); + + return true; + } catch (error) { + Logger.error('[setSystemTimezone失败]', error); + return false; + } +} diff --git a/back/data/system.ts b/back/data/system.ts index efa9d22f..e63d42e7 100644 --- a/back/data/system.ts +++ b/back/data/system.ts @@ -37,6 +37,7 @@ export interface SystemConfigInfo { nodeMirror?: string; pythonMirror?: string; linuxMirror?: string; + timezone?: string; } export interface LoginLogInfo { diff --git a/back/services/system.ts b/back/services/system.ts index 047d5622..80be9afd 100644 --- a/back/services/system.ts +++ b/back/services/system.ts @@ -16,6 +16,7 @@ import { promiseExec, readDirs, rmPath, + setSystemTimezone, } from '../config/util'; import { DependenceModel, @@ -50,7 +51,10 @@ export default class SystemService { public async getSystemConfig() { const doc = await this.getDb({ type: AuthDataType.systemConfig }); - return doc; + return { + ...doc, + info: { ...doc.info, timezone: doc.info?.timezone || 'Asia/Shanghai' }, + }; } private async updateAuthDb(payload: SystemInfo): Promise { @@ -471,4 +475,21 @@ export default class SystemService { await rmPath(path.join(config.systemLogPath, log.title)); } } + + public async updateTimezone(info: SystemModelInfo) { + if (!info.timezone) { + info.timezone = 'Asia/Shanghai'; + } + const oDoc = await this.getSystemConfig(); + await this.updateAuthDb({ + ...oDoc, + info: { ...oDoc.info, ...info }, + }); + const success = await setSystemTimezone(info.timezone); + if (success) { + return { code: 200, data: info }; + } else { + return { code: 400, message: '设置时区失败' }; + } + } } diff --git a/shell/update.sh b/shell/update.sh index d8cabafd..ef56db1c 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -543,6 +543,9 @@ main() { resettfa) eval update_auth_config "\\\"twoFactorActivated\\\":false" "禁用两步验证" $cmd ;; + resetpwd) + eval update_auth_config "\\\"password\\\":\\\"$p2\\\"" "重置密码" $cmd + ;; *) eval echo -e "命令输入错误...\\\n" $cmd eval usage $cmd diff --git a/src/locales/en-US.json b/src/locales/en-US.json index 84f4fc02..522ae8ae 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -500,5 +500,6 @@ "如果恢复失败,可进入容器执行": "If recovery fails, you can enter the container and execute", "常规定时": "Normal Timing", "手动运行": "Manual Run", - "开机运行": "Boot Run" + "开机运行": "Boot Run", + "时区": "Timezone" } diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 1acd1cb1..d6059568 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -500,6 +500,7 @@ "如果恢复失败,可进入容器执行": "如果恢复失败,可进入容器执行", "常规定时": "常规定时", "手动运行": "手动运行", - "开机运行": "开机运行" + "开机运行": "开机运行", + "时区": "时区" } \ No newline at end of file diff --git a/src/pages/setting/index.less b/src/pages/setting/index.less index 1346f9ba..f25d9ce3 100644 --- a/src/pages/setting/index.less +++ b/src/pages/setting/index.less @@ -32,3 +32,13 @@ display: flex; gap: 40px; } + +.ql-container-wrapper.ql-setting-container { + .ant-tabs-tabpane > div { + padding-left: 2px; + } + + .ant-tabs-tabpane > .ant-form { + padding-left: 2px; + } +} diff --git a/src/pages/setting/other.tsx b/src/pages/setting/other.tsx index 84583a98..b8a04e95 100644 --- a/src/pages/setting/other.tsx +++ b/src/pages/setting/other.tsx @@ -23,10 +23,12 @@ import Countdown from 'antd/lib/statistic/Countdown'; import useProgress from './progress'; import pick from 'lodash/pick'; import { disableBody } from '@/utils'; +import { TIMEZONES } from '@/utils/const'; const dataMap = { 'log-remove-frequency': 'logRemoveFrequency', 'cron-concurrency': 'cronConcurrency', + timezone: 'timezone', }; const Other = ({ @@ -37,6 +39,7 @@ const Other = ({ const [systemConfig, setSystemConfig] = useState<{ logRemoveFrequency?: number | null; cronConcurrency?: number | null; + timezone?: string | null; }>(); const [form] = Form.useForm(); const [exportLoading, setExportLoading] = useState(false); @@ -252,6 +255,34 @@ const Other = ({ + + +