diff --git a/backend/app/dto/request/website.go b/backend/app/dto/request/website.go index fff1310f3..ecb38844e 100644 --- a/backend/app/dto/request/website.go +++ b/backend/app/dto/request/website.go @@ -1,6 +1,8 @@ package request -import "github.com/1Panel-dev/1Panel/backend/app/dto" +import ( + "github.com/1Panel-dev/1Panel/backend/app/dto" +) type WebsiteSearch struct { dto.PageInfo @@ -36,6 +38,7 @@ type WebsiteUpdate struct { PrimaryDomain string `json:"primaryDomain" validate:"required"` Remark string `json:"remark"` WebsiteGroupID uint `json:"webSiteGroupID" validate:"required"` + ExpireDate string `json:"expireDate"` } type WebsiteDelete struct { diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 76e67554f..a318157f1 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -254,6 +254,13 @@ func (w WebsiteService) UpdateWebsite(req request.WebsiteUpdate) error { website.PrimaryDomain = req.PrimaryDomain website.WebsiteGroupID = req.WebsiteGroupID website.Remark = req.Remark + if req.ExpireDate != "" { + expireDate, err := time.Parse(constant.DateLayout, req.ExpireDate) + if err != nil { + return err + } + website.ExpireDate = expireDate + } return websiteRepo.Save(context.TODO(), &website) } diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 8d641f252..d20e952fa 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -67,6 +67,7 @@ export namespace Website { primaryDomain: string; remark: string; webSiteGroupId: number; + expireDate?: string; } export interface WebSiteOp { diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 427ff5ac8..e2a9f8aed 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -947,6 +947,8 @@ export default { ext: '文件扩展名', wafInputHelper: '按行输入数据,一行一个', data: '数据', + ever: '永久', + nextYear: '一年后', }, nginx: { serverNamesHashBucketSizeHelper: '服务器名字的hash表大小', diff --git a/frontend/src/utils/util.ts b/frontend/src/utils/util.ts index f510ed500..1f5cc6115 100644 --- a/frontend/src/utils/util.ts +++ b/frontend/src/utils/util.ts @@ -49,6 +49,17 @@ export function dateFromat(row: number, col: number, dataStr: any) { return `${String(y)}-${String(m)}-${String(d)} ${String(h)}:${String(minute)}:${String(second)}`; } +//2016-01-12 +export function dateFromatSimple(dataStr: any) { + const date = new Date(dataStr); + const y = date.getFullYear(); + let m: string | number = date.getMonth() + 1; + m = m < 10 ? `0${String(m)}` : m; + let d: string | number = date.getDate(); + d = d < 10 ? `0${String(d)}` : d; + return `${String(y)}-${String(m)}-${String(d)}`; +} + // 20221013151302 export function dateFromatForName(dataStr: any) { const date = new Date(dataStr); diff --git a/frontend/src/views/website/website/index.vue b/frontend/src/views/website/website/index.vue index 8588de59e..2331e8134 100644 --- a/frontend/src/views/website/website/index.vue +++ b/frontend/src/views/website/website/index.vue @@ -48,9 +48,29 @@ - - {{ $t('website.neverExpire') }} - {{ dateFromat(1, 1, row.webSiteSSL.expireDate) }} + + + pickerVisibility(visibility, row)" + size="small" + > + + + + {{ $t('website.neverExpire') }} + + + {{ dateFromatSimple(row.expireDate) }} + + { + return new Date('1970-01-01'); + }, + }, + { + text: i18n.global.t('website.nextYear'), + value: () => { + const now = new Date(); + now.setFullYear(now.getFullYear() + 1); + return now; + }, + }, +]; +const loading = ref(false); const createRef = ref(); const deleteRef = ref(); const groupRef = ref(); @@ -114,6 +149,10 @@ let nginxIsExist = ref(false); let containerName = ref(''); let nginxStatus = ref(''); let installPath = ref(''); +const uploadRef = ref(); +const dialogBackupRef = ref(); +const data = ref(); +let dateRefs: Map = new Map(); const paginationConfig = reactive({ currentPage: 1, @@ -121,14 +160,12 @@ const paginationConfig = reactive({ total: 0, }); -const data = ref(); const search = async () => { const req = { name: '', page: paginationConfig.currentPage, pageSize: paginationConfig.pageSize, }; - SearchWebsites(req).then((res) => { data.value = res.data.items; paginationConfig.total = res.data.total; @@ -142,8 +179,67 @@ const openConfig = (id: number) => { router.push({ name: 'WebsiteConfig', params: { id: id, tab: 'basic' } }); }; -const uploadRef = ref(); -const dialogBackupRef = ref(); +const isEver = (time: string) => { + const expireDate = new Date(time); + return expireDate < new Date('1970-01-02'); +}; + +const isBeforeNow = (time: string) => { + return new Date() > new Date(time); +}; + +const setDate = (time: string) => { + if (isEver(time)) { + return new Date().toLocaleDateString(); + } else { + return new Date(time); + } +}; + +const openDatePicker = (row: any, index: number) => { + row.showdate = true; + const ref = dateRefs.get(index); + if (ref != undefined) { + if (isBeforeNow(row.expireDate)) { + row.oldExpireDate = row.expireDate; + const date = new Date().toLocaleDateString(); + row.expireDate = date; + } + ref.handleOpen(); + } +}; + +const setdateRefs = (ref: any, index: number) => { + dateRefs.set(index, ref); +}; + +const pickerVisibility = (visibility: boolean, row: any) => { + if (!visibility) { + row.showdate = false; + if (!row.change) { + if (row.oldExpireDate) { + row.expireDate = row.oldExpireDate; + } + row.change = false; + } + } +}; + +const submitDate = (row: any) => { + const reqDate = dateFromatSimple(row.expireDate); + const req = { + id: row.id, + primaryDomain: row.primaryDomain, + remark: row.remark, + webSiteGroupId: row.webSiteGroupId, + expireDate: reqDate, + }; + + UpdateWebsite(req).then(() => { + row.change = true; + ElMessage.success(i18n.global.t('commons.msg.updateSuccess')); + }); +}; const buttons = [ { @@ -200,6 +296,11 @@ const checkExist = (data: App.CheckInstalled) => { installPath.value = data.installPath; }; +const checkDate = (date: Date) => { + const now = new Date(); + return date < now; +}; + const opWebsite = (op: string, id: number) => { ElMessageBox.confirm(i18n.global.t('website.' + op + 'Helper'), i18n.global.t('cronjob.changeStatus'), { confirmButtonText: i18n.global.t('commons.button.confirm'),