mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-27 12:39:01 +08:00
fix: 系统时间同步样式修改 (#1123)
This commit is contained in:
parent
b979c2574c
commit
be6b7157f4
@ -205,23 +205,22 @@ func (b *BaseApi) LoadTimeZone(c *gin.Context) {
|
||||
// @Summary Sync system time
|
||||
// @Description 系统时间同步
|
||||
// @Accept json
|
||||
// @Param request body dto.SyncTimeZone true "request"
|
||||
// @Param request body dto.SyncTime true "request"
|
||||
// @Success 200 {string} ntime
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/time/sync [post]
|
||||
// @x-panel-log {"bodyKeys":["ntpSite", "timeZone"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步[ntpSite]-[timeZone]","formatEN":"sync system time [ntpSite]-[timeZone]"}
|
||||
// @x-panel-log {"bodyKeys":["ntpSite"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步[ntpSite]","formatEN":"sync system time [ntpSite]"}
|
||||
func (b *BaseApi) SyncTime(c *gin.Context) {
|
||||
var req dto.SyncTimeZone
|
||||
var req dto.SyncTime
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
ntime, err := settingService.SyncTime(req)
|
||||
if err != nil {
|
||||
if err := settingService.SyncTime(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, ntime.Format("2006-01-02 15:04:05 MST -0700"))
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
|
@ -111,9 +111,8 @@ type UpgradeInfo struct {
|
||||
ReleaseNote string `json:"releaseNote"`
|
||||
}
|
||||
|
||||
type SyncTimeZone struct {
|
||||
NtpSite string `json:"ntpSite"`
|
||||
TimeZone string `json:"timeZone"`
|
||||
type SyncTime struct {
|
||||
NtpSite string `json:"ntpSite"`
|
||||
}
|
||||
|
||||
type Upgrade struct {
|
||||
|
@ -35,7 +35,7 @@ type ISettingService interface {
|
||||
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
|
||||
LoadFromCert() (*dto.SSLInfo, error)
|
||||
HandlePasswordExpired(c *gin.Context, old, new string) error
|
||||
SyncTime(req dto.SyncTimeZone) (time.Time, error)
|
||||
SyncTime(req dto.SyncTime) error
|
||||
}
|
||||
|
||||
func NewISettingService() ISettingService {
|
||||
@ -72,46 +72,49 @@ func (u *SettingService) LoadTimeZone() ([]string, error) {
|
||||
}
|
||||
|
||||
func (u *SettingService) Update(key, value string) error {
|
||||
if key == "ExpirationDays" {
|
||||
if err := settingRepo.Update(key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
switch key {
|
||||
case "ExpirationDays":
|
||||
timeout, _ := strconv.Atoi(value)
|
||||
if err := settingRepo.Update("ExpirationTime", time.Now().AddDate(0, 0, timeout).Format("2006-01-02 15:04:05")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if key == "BindDomain" {
|
||||
case "BindDomain":
|
||||
global.CONF.System.BindDomain = value
|
||||
}
|
||||
if key == "AllowIPs" {
|
||||
case "AllowIPs":
|
||||
global.CONF.System.AllowIPs = value
|
||||
}
|
||||
if err := settingRepo.Update(key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
if key == "UserName" {
|
||||
case "TimeZone":
|
||||
if err := ntp.UpdateSystemTimeZone(value); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
_, err := cmd.Exec("systemctl restart 1panel.service")
|
||||
if err != nil {
|
||||
global.LOG.Errorf("restart system for new time zone failed, err: %v", err)
|
||||
}
|
||||
}()
|
||||
case "UserName", "Password":
|
||||
_ = global.SESSION.Clean()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *SettingService) SyncTime(req dto.SyncTimeZone) (time.Time, error) {
|
||||
func (u *SettingService) SyncTime(req dto.SyncTime) error {
|
||||
if err := settingRepo.Update("NtpSite", req.NtpSite); err != nil {
|
||||
return err
|
||||
}
|
||||
ntime, err := ntp.GetRemoteTime(req.NtpSite)
|
||||
if err != nil {
|
||||
return ntime, err
|
||||
return err
|
||||
}
|
||||
|
||||
ts := ntime.Format("2006-01-02 15:04:05")
|
||||
if err := ntp.UpdateSystemTime(ts, req.TimeZone); err != nil {
|
||||
return ntime, err
|
||||
if err := ntp.UpdateSystemTime(ts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := settingRepo.Update("TimeZone", req.TimeZone); err != nil {
|
||||
return ntime, err
|
||||
}
|
||||
if err := settingRepo.Update("NtpSite", req.NtpSite); err != nil {
|
||||
return ntime, err
|
||||
}
|
||||
|
||||
return ntime, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *SettingService) UpdatePort(port uint) error {
|
||||
|
@ -348,7 +348,7 @@ var AddBindAndAllowIPs = &gormigrate.Migration{
|
||||
if err := tx.Create(&model.Setting{Key: "TimeZone", Value: common.LoadTimeZone()}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "NtpSite", Value: "pool.ntp.org:123"}).Error; err != nil {
|
||||
if err := tx.Create(&model.Setting{Key: "NtpSite", Value: "pool.ntp.org"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -31,7 +31,7 @@ type packet struct {
|
||||
}
|
||||
|
||||
func GetRemoteTime(site string) (time.Time, error) {
|
||||
conn, err := net.Dial("udp", site)
|
||||
conn, err := net.Dial("udp", site+":123")
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("failed to connect: %v", err)
|
||||
}
|
||||
@ -59,15 +59,10 @@ func GetRemoteTime(site string) (time.Time, error) {
|
||||
return showtime, nil
|
||||
}
|
||||
|
||||
func UpdateSystemTime(dateTime, timezone string) error {
|
||||
func UpdateSystemTime(dateTime string) error {
|
||||
system := runtime.GOOS
|
||||
if system == "linux" {
|
||||
stdout, err := cmd.Execf(`%s timedatectl set-timezone "%s"`, cmd.SudoHandleCmd(), timezone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("update system time zone failed, stdout: %s, err: %v", stdout, err)
|
||||
}
|
||||
|
||||
stdout2, err := cmd.Execf(`%s timedatectl set-time "%s"`, cmd.SudoHandleCmd(), dateTime)
|
||||
stdout2, err := cmd.Execf(`%s date -s "%s"`, cmd.SudoHandleCmd(), dateTime)
|
||||
if err != nil {
|
||||
return fmt.Errorf("update system time failed,stdout: %s, err: %v", stdout2, err)
|
||||
}
|
||||
@ -75,3 +70,15 @@ func UpdateSystemTime(dateTime, timezone string) error {
|
||||
}
|
||||
return fmt.Errorf("the current system architecture %v does not support synchronization", system)
|
||||
}
|
||||
|
||||
func UpdateSystemTimeZone(timezone string) error {
|
||||
system := runtime.GOOS
|
||||
if system == "linux" {
|
||||
stdout, err := cmd.Execf(`%s timedatectl set-timezone "%s"`, cmd.SudoHandleCmd(), timezone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("update system time zone failed, stdout: %s, err: %v", stdout, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("the current system architecture %v does not support synchronization", system)
|
||||
}
|
||||
|
@ -7878,7 +7878,7 @@ var doc = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.SyncTimeZone"
|
||||
"$ref": "#/definitions/dto.SyncTime"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -7893,11 +7893,10 @@ var doc = `{
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"ntpSite",
|
||||
"timeZone"
|
||||
"ntpSite"
|
||||
],
|
||||
"formatEN": "sync system time [ntpSite]-[timeZone]",
|
||||
"formatZH": "系统时间同步[ntpSite]-[timeZone]",
|
||||
"formatEN": "sync system time [ntpSite]",
|
||||
"formatZH": "系统时间同步[ntpSite]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
@ -12621,14 +12620,11 @@ var doc = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.SyncTimeZone": {
|
||||
"dto.SyncTime": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ntpSite": {
|
||||
"type": "string"
|
||||
},
|
||||
"timeZone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -7864,7 +7864,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.SyncTimeZone"
|
||||
"$ref": "#/definitions/dto.SyncTime"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -7879,11 +7879,10 @@
|
||||
"x-panel-log": {
|
||||
"BeforeFuntions": [],
|
||||
"bodyKeys": [
|
||||
"ntpSite",
|
||||
"timeZone"
|
||||
"ntpSite"
|
||||
],
|
||||
"formatEN": "sync system time [ntpSite]-[timeZone]",
|
||||
"formatZH": "系统时间同步[ntpSite]-[timeZone]",
|
||||
"formatEN": "sync system time [ntpSite]",
|
||||
"formatZH": "系统时间同步[ntpSite]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
@ -12607,14 +12606,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.SyncTimeZone": {
|
||||
"dto.SyncTime": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ntpSite": {
|
||||
"type": "string"
|
||||
},
|
||||
"timeZone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1694,12 +1694,10 @@ definitions:
|
||||
required:
|
||||
- id
|
||||
type: object
|
||||
dto.SyncTimeZone:
|
||||
dto.SyncTime:
|
||||
properties:
|
||||
ntpSite:
|
||||
type: string
|
||||
timeZone:
|
||||
type: string
|
||||
type: object
|
||||
dto.UpdateDescription:
|
||||
properties:
|
||||
@ -8276,7 +8274,7 @@ paths:
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.SyncTimeZone'
|
||||
$ref: '#/definitions/dto.SyncTime'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
@ -8291,9 +8289,8 @@ paths:
|
||||
BeforeFuntions: []
|
||||
bodyKeys:
|
||||
- ntpSite
|
||||
- timeZone
|
||||
formatEN: sync system time [ntpSite]-[timeZone]
|
||||
formatZH: 系统时间同步[ntpSite]-[timeZone]
|
||||
formatEN: sync system time [ntpSite]
|
||||
formatZH: 系统时间同步[ntpSite]
|
||||
paramKeys: []
|
||||
/settings/update:
|
||||
post:
|
||||
|
@ -38,8 +38,8 @@ export const handleExpired = (param: Setting.PasswordUpdate) => {
|
||||
export const loadTimeZone = () => {
|
||||
return http.get<Array<string>>(`/settings/time/option`);
|
||||
};
|
||||
export const syncTime = (timeZone: string, ntpSite: string) => {
|
||||
return http.post<string>(`/settings/time/sync`, { timeZone: timeZone, ntpSite: ntpSite });
|
||||
export const syncTime = (ntpSite: string) => {
|
||||
return http.post<string>(`/settings/time/sync`, { ntpSite: ntpSite });
|
||||
};
|
||||
|
||||
export const cleanMonitors = () => {
|
||||
|
@ -907,11 +907,17 @@ const message = {
|
||||
'If you do not operate the panel for more than {0} seconds, the panel automatically logs out',
|
||||
syncTime: 'Server time',
|
||||
timeZone: 'Time Zone',
|
||||
timeZoneHelper: 'Timezone modification depends on the system timedatectl service.',
|
||||
timeZoneChangeHelper: 'Changing the time zone requires restarting the service. Do you want to continue?',
|
||||
timeZoneHelper:
|
||||
'Timezone modification depends on the system timedatectl service. take effect after restart the 1Panel service.',
|
||||
timeZoneCN: 'Bei Jing',
|
||||
timeZoneAM: 'Los Angeles',
|
||||
timeZoneNY: 'New York',
|
||||
ntpALi: 'Alibaba',
|
||||
ntpGoogle: 'Google',
|
||||
syncSite: 'Ntp Server',
|
||||
syncSiteHelper:
|
||||
'This operation will use {0} as the source for system time synchronization. Do you want to continue?',
|
||||
changePassword: 'Password change',
|
||||
oldPassword: 'Original password',
|
||||
newPassword: 'New password',
|
||||
|
@ -905,12 +905,16 @@ const message = {
|
||||
sessionTimeoutError: '最小超时时间为 300 秒',
|
||||
sessionTimeoutHelper: '如果用户超过 {0} 秒未操作面板,面板将自动退出登录',
|
||||
syncTime: '服务器时间',
|
||||
timeZone: '时区',
|
||||
timeZoneHelper: '时区修改依赖于系统 timedatectl 服务。',
|
||||
timeZone: '系统时区',
|
||||
timeZoneChangeHelper: '系统时区修改需要重启服务,是否继续?',
|
||||
timeZoneHelper: '时区修改依赖于系统 timedatectl 服务,重启 1Panel 服务后生效。',
|
||||
timeZoneCN: '北京',
|
||||
timeZoneAM: '洛杉矶',
|
||||
timeZoneNY: '纽约',
|
||||
syncSite: '同步地址',
|
||||
ntpALi: '阿里',
|
||||
ntpGoogle: '谷歌',
|
||||
syncSite: 'NTP 服务器',
|
||||
syncSiteHelper: '该操作将使用 {0} 作为源进行系统时间同步,是否继续?',
|
||||
changePassword: '密码修改',
|
||||
oldPassword: '原密码',
|
||||
newPassword: '新密码',
|
||||
|
@ -73,6 +73,15 @@
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('setting.timeZone')" prop="timeZone">
|
||||
<el-input disabled v-model.number="form.timeZone">
|
||||
<template #append>
|
||||
<el-button @click="onChangeTimeZone" icon="Setting">
|
||||
{{ $t('commons.button.set') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.syncTime')">
|
||||
<el-input disabled v-model="form.localTime">
|
||||
<template #append>
|
||||
@ -92,6 +101,7 @@
|
||||
<UserName ref="userNameRef" />
|
||||
<PanelName ref="panelNameRef" @search="search()" />
|
||||
<Timeout ref="timeoutRef" @search="search()" />
|
||||
<TimeZone ref="timezoneRef" @search="search()" />
|
||||
<Ntp ref="ntpRef" @search="search()" />
|
||||
</div>
|
||||
</template>
|
||||
@ -108,6 +118,7 @@ import Password from '@/views/setting/panel/password/index.vue';
|
||||
import UserName from '@/views/setting/panel/username/index.vue';
|
||||
import Timeout from '@/views/setting/panel/timeout/index.vue';
|
||||
import PanelName from '@/views/setting/panel/name/index.vue';
|
||||
import TimeZone from '@/views/setting/panel/timezone/index.vue';
|
||||
import Ntp from '@/views/setting/panel/ntp/index.vue';
|
||||
|
||||
const loading = ref(false);
|
||||
@ -137,6 +148,7 @@ const passwordRef = ref();
|
||||
const panelNameRef = ref();
|
||||
const timeoutRef = ref();
|
||||
const ntpRef = ref();
|
||||
const timezoneRef = ref();
|
||||
|
||||
const search = async () => {
|
||||
const res = await getSettingInfo();
|
||||
@ -164,8 +176,11 @@ const onChangeTitle = () => {
|
||||
const onChangeTimeout = () => {
|
||||
timeoutRef.value.acceptParams({ sessionTimeout: form.sessionTimeout });
|
||||
};
|
||||
const onChangeTimeZone = () => {
|
||||
timezoneRef.value.acceptParams({ timeZone: form.timeZone });
|
||||
};
|
||||
const onChangeNtp = () => {
|
||||
ntpRef.value.acceptParams({ localTime: form.localTime, timeZone: form.timeZone, ntpSite: form.ntpSite });
|
||||
ntpRef.value.acceptParams({ localTime: form.localTime, ntpSite: form.ntpSite });
|
||||
};
|
||||
|
||||
const onSave = async (key: string, val: any) => {
|
||||
|
@ -4,56 +4,25 @@
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('setting.syncTime')" :back="handleClose" />
|
||||
</template>
|
||||
<el-alert v-if="canChangeZone()" style="margin-bottom: 20px" :closable="false" type="warning">
|
||||
<template #default>
|
||||
<span>
|
||||
<span>{{ $t('setting.timeZoneHelper') }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('setting.timeZone')" prop="timeZone" :rules="Rules.requiredInput">
|
||||
<el-select filterable :disabled="canChangeZone()" v-model="form.timeZone">
|
||||
<el-option v-for="item in zones" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
<el-button
|
||||
:disabled="canChangeZone()"
|
||||
type="primary"
|
||||
link
|
||||
class="tagClass"
|
||||
@click="form.timeZone = 'Asia/Shanghai'"
|
||||
>
|
||||
{{ $t('setting.timeZoneCN') }}
|
||||
<el-form-item :label="$t('setting.syncSite')" prop="ntpSite" :rules="Rules.requiredInput">
|
||||
<el-input v-model="form.ntpSite" />
|
||||
<el-button type="primary" link class="tagClass" @click="form.ntpSite = 'pool.ntp.org'">
|
||||
{{ $t('website.default') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="canChangeZone()"
|
||||
type="primary"
|
||||
link
|
||||
class="tagClass"
|
||||
@click="form.timeZone = 'America/Los_Angeles'"
|
||||
>
|
||||
{{ $t('setting.timeZoneAM') }}
|
||||
<el-button type="primary" link class="tagClass" @click="form.ntpSite = 'ntp.aliyun.com'">
|
||||
{{ $t('setting.ntpALi') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="canChangeZone()"
|
||||
type="primary"
|
||||
link
|
||||
class="tagClass"
|
||||
@click="form.timeZone = 'America/New_York'"
|
||||
>
|
||||
{{ $t('setting.timeZoneNY') }}
|
||||
<el-button type="primary" link class="tagClass" @click="form.ntpSite = 'time.google.com'">
|
||||
{{ $t('setting.ntpGoogle') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('setting.syncTime')" prop="localTime">
|
||||
<el-input v-model="form.localTime" disabled />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('setting.syncSite')" prop="ntpSite" :rules="Rules.requiredInput">
|
||||
<el-input v-model="form.ntpSite" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@ -72,24 +41,20 @@
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { loadTimeZone, syncTime } from '@/api/modules/setting';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { syncTime } from '@/api/modules/setting';
|
||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
interface DialogProps {
|
||||
timeZone: string;
|
||||
localTime: string;
|
||||
ntpSite: string;
|
||||
}
|
||||
const drawerVisiable = ref();
|
||||
const loading = ref();
|
||||
const zones = ref<Array<string>>([]);
|
||||
const oldTimeZone = ref();
|
||||
|
||||
const form = reactive({
|
||||
timeZone: '',
|
||||
localTime: '',
|
||||
ntpSite: '',
|
||||
});
|
||||
@ -97,38 +62,37 @@ const form = reactive({
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
loadTimeZones();
|
||||
oldTimeZone.value = params.timeZone;
|
||||
form.timeZone = params.timeZone;
|
||||
form.localTime = params.localTime;
|
||||
form.ntpSite = params.ntpSite;
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
|
||||
const canChangeZone = () => {
|
||||
return zones.value.length === 0;
|
||||
};
|
||||
|
||||
const loadTimeZones = async () => {
|
||||
const res = await loadTimeZone();
|
||||
zones.value = res.data;
|
||||
};
|
||||
const onSyncTime = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
await syncTime(form.timeZone, form.ntpSite)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
form.localTime = res.data;
|
||||
emit('search');
|
||||
handleClose();
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('setting.syncSiteHelper', [form.ntpSite]),
|
||||
i18n.global.t('setting.syncSite'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
).then(async () => {
|
||||
loading.value = true;
|
||||
await syncTime(form.ntpSite)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
form.localTime = res.data;
|
||||
emit('search');
|
||||
handleClose();
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
139
frontend/src/views/setting/panel/timezone/index.vue
Normal file
139
frontend/src/views/setting/panel/timezone/index.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('setting.timeZone')" :back="handleClose" />
|
||||
</template>
|
||||
<el-alert v-if="canChangeZone()" style="margin-bottom: 20px" :closable="false" type="warning">
|
||||
<template #default>
|
||||
<span>
|
||||
<span>{{ $t('setting.timeZoneHelper') }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('setting.timeZone')" prop="timeZone" :rules="Rules.requiredInput">
|
||||
<el-select filterable :disabled="canChangeZone()" v-model="form.timeZone">
|
||||
<el-option v-for="item in zones" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
<el-button
|
||||
:disabled="canChangeZone()"
|
||||
type="primary"
|
||||
link
|
||||
class="tagClass"
|
||||
@click="form.timeZone = 'Asia/Shanghai'"
|
||||
>
|
||||
{{ $t('setting.timeZoneCN') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="canChangeZone()"
|
||||
type="primary"
|
||||
link
|
||||
class="tagClass"
|
||||
@click="form.timeZone = 'America/Los_Angeles'"
|
||||
>
|
||||
{{ $t('setting.timeZoneAM') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="canChangeZone()"
|
||||
type="primary"
|
||||
link
|
||||
class="tagClass"
|
||||
@click="form.timeZone = 'America/New_York'"
|
||||
>
|
||||
{{ $t('setting.timeZoneNY') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { loadTimeZone, updateSetting } from '@/api/modules/setting';
|
||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import router from '@/routers';
|
||||
import { GlobalStore } from '@/store';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
interface DialogProps {
|
||||
timeZone: string;
|
||||
}
|
||||
const drawerVisiable = ref();
|
||||
const loading = ref();
|
||||
|
||||
const form = reactive({
|
||||
timeZone: '',
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const zones = ref<Array<string>>([]);
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
loadTimeZones();
|
||||
form.timeZone = params.timeZone;
|
||||
drawerVisiable.value = true;
|
||||
};
|
||||
|
||||
const loadTimeZones = async () => {
|
||||
const res = await loadTimeZone();
|
||||
zones.value = res.data;
|
||||
};
|
||||
|
||||
const canChangeZone = () => {
|
||||
return zones.value.length === 0;
|
||||
};
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
ElMessageBox.confirm(i18n.global.t('setting.timeZoneChangeHelper'), i18n.global.t('setting.timeZone'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
}).then(async () => {
|
||||
await updateSetting({ key: 'TimeZone', value: form.timeZone })
|
||||
.then(async () => {
|
||||
loading.value = false;
|
||||
router.push({ name: 'entrance', params: { code: globalStore.entrance } });
|
||||
globalStore.setLogStatus(false);
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
drawerVisiable.value = false;
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisiable.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.tagClass {
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user