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