diff --git a/internal/utils/time.go b/internal/utils/time.go
new file mode 100644
index 00000000..eda01764
--- /dev/null
+++ b/internal/utils/time.go
@@ -0,0 +1,55 @@
+// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
+
+package utils
+
+import (
+ "errors"
+ "fmt"
+ "github.com/iwind/TeaGo/types"
+ "regexp"
+)
+
+// RangeTimes 计算时间点
+func RangeTimes(timeFrom string, timeTo string, everyMinutes int32) (result []string, err error) {
+ if everyMinutes <= 0 {
+ return nil, errors.New("invalid 'everyMinutes'")
+ }
+
+ var reg = regexp.MustCompile(`^\d{4}$`)
+ if !reg.MatchString(timeFrom) {
+ return nil, errors.New("invalid timeFrom '" + timeFrom + "'")
+ }
+ if !reg.MatchString(timeTo) {
+ return nil, errors.New("invalid timeTo '" + timeTo + "'")
+ }
+
+ if timeFrom > timeTo {
+ // swap
+ timeFrom, timeTo = timeTo, timeFrom
+ }
+
+ var everyMinutesInt = int(everyMinutes)
+
+ var fromHour = types.Int(timeFrom[:2])
+ var fromMinute = types.Int(timeFrom[2:])
+ var toHour = types.Int(timeTo[:2])
+ var toMinute = types.Int(timeTo[2:])
+
+ if fromMinute%everyMinutesInt == 0 {
+ result = append(result, timeFrom)
+ }
+
+ for {
+ fromMinute += everyMinutesInt
+ if fromMinute > 59 {
+ fromHour += fromMinute / 60
+ fromMinute = fromMinute % 60
+ }
+ if fromHour > toHour || (fromHour == toHour && fromMinute > toMinute) {
+ break
+ }
+ result = append(result, fmt.Sprintf("%02d%02d", fromHour, fromMinute))
+ }
+
+ return
+}
diff --git a/web/public/js/components.js b/web/public/js/components.js
index b0dd2c3c..6cc0b52a 100644
--- a/web/public/js/components.js
+++ b/web/public/js/components.js
@@ -1590,6 +1590,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
域名跳转
{{redirect.domainAfterScheme}}
+ 忽略端口
@@ -5180,7 +5181,7 @@ example2.com
-
`}),Vue.component("datepicker",{props:["value","v-name","name","v-value","v-bottom-left","placeholder"],mounted:function(){let t=this;teaweb.datepicker(this.$refs.dayInput,function(e){t.day=e,t.change()},!!this.vBottomLeft)},data:function(){let e=this.vName,t=(null==(e=null==e?this.name:e)&&(e="day"),this.vValue),i=(null==t&&null==(t=this.value)&&(t=""),"YYYY-MM-DD");return null!=this.placeholder&&(i=this.placeholder),{realName:e,realPlaceholder:i,day:t}},watch:{value:function(e){this.day=e}},methods:{change:function(){this.$emit("input",this.day),this.$emit("change",this.day)}},template:`
+
`}),Vue.component("datepicker",{props:["value","v-name","name","v-value","v-bottom-left","placeholder"],mounted:function(){let t=this;teaweb.datepicker(this.$refs.dayInput,function(e){t.day=e,t.change()},!!this.vBottomLeft)},data:function(){let e=this.vName,t=(null==(e=null==e?this.name:e)&&(e="day"),this.vValue),i=(null==t&&null==(t=this.value)&&(t=""),"YYYY-MM-DD");return null!=this.placeholder&&(i=this.placeholder),{realName:e,realPlaceholder:i,day:t}},watch:{value:function(e){this.day=e;let t=this.$refs.dayInput.picker;null!=t&&null!=e&&/^\d+-\d+-\d+$/.test(e)&&t.setDate(e)}},methods:{change:function(){this.$emit("input",this.day),this.$emit("change",this.day)}},template:`
`}),Vue.component("sort-arrow",{props:["name"],data:function(){let e=window.location.toString(),n="",t="",o=[];if(null!=window.location.search&&0 `}),Vue.component("user-link",{props:["v-user","v-keyword"],data:function(){let e=this.vUser;return{user:e=null==e?{id:0,username:"",fullname:""}:e}},template:`
{{user.fullname}}({{user.username}})
diff --git a/web/public/js/components.src.js b/web/public/js/components.src.js
index 422e9e33..34e37412 100755
--- a/web/public/js/components.src.js
+++ b/web/public/js/components.src.js
@@ -4511,6 +4511,7 @@ Vue.component("http-host-redirect-box", {
域名跳转
{{redirect.domainAfterScheme}}
+ 忽略端口
@@ -16333,6 +16334,13 @@ Vue.component("datepicker", {
watch: {
value: function (v) {
this.day = v
+
+ let picker = this.$refs.dayInput.picker
+ if (picker != null) {
+ if (v != null && /^\d+-\d+-\d+$/.test(v)) {
+ picker.setDate(v)
+ }
+ }
}
},
methods: {