This commit is contained in:
unknown
2026-02-04 20:27:13 +08:00
commit 3b042d1dad
9410 changed files with 1488147 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package ui
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type CityOptionsAction struct {
actionutils.ParentAction
}
func (this *CityOptionsAction) RunPost(params struct{}) {
citiesResp, err := this.RPC().RegionCityRPC().FindAllRegionCities(this.UserContext(), &pb.FindAllRegionCitiesRequest{
IncludeRegionProvince: true,
})
if err != nil {
this.ErrorPage(err)
return
}
var cityMaps = []maps.Map{}
for _, city := range citiesResp.RegionCities {
if city.Codes == nil {
city.Codes = []string{}
}
var fullname = city.Name
if city.RegionProvince != nil && len(city.RegionProvince.Name) > 0 && city.RegionProvince.Name != city.Name {
fullname = city.RegionProvince.Name + " " + fullname
}
cityMaps = append(cityMaps, maps.Map{
"id": city.Id,
"name": city.Name,
"fullname": fullname,
"codes": city.Codes,
})
}
this.Data["cities"] = cityMaps
this.Success()
}

View File

@@ -0,0 +1,154 @@
package ui
import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/default/servers/server/settings/conds/condutils"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/files"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"net/http"
)
type ComponentsAction actions.Action
var componentsData = []byte{}
var componentsDataSum string
func (this *ComponentsAction) RunGet(params struct{}) {
this.AddHeader("Content-Type", "text/javascript; charset=utf-8")
// etag
var requestETag = this.Header("If-None-Match")
if len(requestETag) > 0 && requestETag == "\""+componentsDataSum+"\"" {
this.ResponseWriter.WriteHeader(http.StatusNotModified)
return
}
if !Tea.IsTesting() && len(componentsData) > 0 {
this.AddHeader("Last-Modified", "Fri, 06 Sep 2019 08:29:50 GMT")
_, _ = this.Write(componentsData)
return
}
var buffer = bytes.NewBuffer([]byte{})
var webRoot string
if Tea.IsTesting() {
webRoot = Tea.Root + "/../web/public/js/components/"
} else {
webRoot = Tea.Root + "/web/public/js/components/"
}
f := files.NewFile(webRoot)
f.Range(func(file *files.File) {
if !file.IsFile() {
return
}
if file.Ext() != ".js" {
return
}
data, err := file.ReadAll()
if err != nil {
logs.Error(err)
return
}
buffer.Write(data)
buffer.Write([]byte{'\n', '\n'})
})
// 条件组件
typesJSON, err := json.Marshal(condutils.ReadAllAvailableCondTypes())
if err != nil {
logs.Println("ComponentsAction: " + err.Error())
} else {
buffer.WriteString("window.REQUEST_COND_COMPONENTS = ")
buffer.Write(typesJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
// 条件操作符
requestOperatorsJSON, err := json.Marshal(shared.AllRequestOperators())
if err != nil {
logs.Println("ComponentsAction marshal request operators failed: " + err.Error())
} else {
buffer.WriteString("window.REQUEST_COND_OPERATORS = ")
buffer.Write(requestOperatorsJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
// 请求变量
requestVariablesJSON, err := json.Marshal(shared.DefaultRequestVariables())
if err != nil {
logs.Println("ComponentsAction marshal request variables failed: " + err.Error())
} else {
buffer.WriteString("window.REQUEST_VARIABLES = ")
buffer.Write(requestVariablesJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
// 指标
metricHTTPKeysJSON, err := json.Marshal(serverconfigs.FindAllMetricKeyDefinitions(serverconfigs.MetricItemCategoryHTTP))
if err != nil {
logs.Println("ComponentsAction marshal metric http keys failed: " + err.Error())
} else {
buffer.WriteString("window.METRIC_HTTP_KEYS = ")
buffer.Write(metricHTTPKeysJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
// WAF checkpoints
var wafCheckpointsMaps = []maps.Map{}
for _, checkpoint := range firewallconfigs.AllCheckpoints {
wafCheckpointsMaps = append(wafCheckpointsMaps, maps.Map{
"name": checkpoint.Name,
"prefix": checkpoint.Prefix,
"description": checkpoint.Description,
})
}
wafCheckpointsJSON, err := json.Marshal(wafCheckpointsMaps)
if err != nil {
logs.Println("ComponentsAction marshal waf rule checkpoints failed: " + err.Error())
} else {
buffer.WriteString("window.WAF_RULE_CHECKPOINTS = ")
buffer.Write(wafCheckpointsJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
// WAF操作符
wafOperatorsJSON, err := json.Marshal(firewallconfigs.AllRuleOperators)
if err != nil {
logs.Println("ComponentsAction marshal waf rule operators failed: " + err.Error())
} else {
buffer.WriteString("window.WAF_RULE_OPERATORS = ")
buffer.Write(wafOperatorsJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
// WAF验证码类型
captchaTypesJSON, err := json.Marshal(firewallconfigs.FindAllCaptchaTypes())
if err != nil {
logs.Println("ComponentsAction marshal captcha types failed: " + err.Error())
} else {
buffer.WriteString("window.WAF_CAPTCHA_TYPES = ")
buffer.Write(captchaTypesJSON)
buffer.Write([]byte{';', '\n', '\n'})
}
componentsData = buffer.Bytes()
// ETag
var h = md5.New()
h.Write(buffer.Bytes())
componentsDataSum = fmt.Sprintf("%x", h.Sum(nil))
this.AddHeader("ETag", "\""+componentsDataSum+"\"")
_, _ = this.Write(componentsData)
}

View File

@@ -0,0 +1,3 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package ui

View File

@@ -0,0 +1,49 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package ui
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"strings"
)
type CountryOptionsAction struct {
actionutils.ParentAction
}
func (this *CountryOptionsAction) RunPost(params struct{}) {
countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.UserContext(), &pb.FindAllRegionCountriesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
var countryMaps = []maps.Map{}
for _, country := range countriesResp.RegionCountries {
if lists.ContainsInt64(regionconfigs.FindAllGreaterChinaSubRegionIds(), country.Id) {
continue
}
if country.Codes == nil {
country.Codes = []string{}
}
var letter = ""
if len(country.Pinyin) > 0 && len(country.Pinyin[0]) > 0 {
letter = strings.ToUpper(country.Pinyin[0][:1])
}
countryMaps = append(countryMaps, maps.Map{
"id": country.Id,
"name": country.DisplayName,
"fullname": letter + " " + country.DisplayName,
"codes": country.Codes,
})
}
this.Data["countries"] = countryMaps
this.Success()
}

View File

@@ -0,0 +1,22 @@
package ui
import (
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
)
// 下载指定的文本内容
type DownloadAction struct {
actionutils.ParentAction
}
func (this *DownloadAction) Init() {
this.Nav("", "", "")
}
func (this *DownloadAction) RunGet(params struct {
File string
Text string
}) {
this.AddHeader("Content-Disposition", "attachment; filename=\""+params.File+"\";")
this.WriteString(params.Text)
}

View File

@@ -0,0 +1,70 @@
package ui
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/types"
"mime"
"path/filepath"
)
// ImageAction 公开的图片,不需要检查用户权限
type ImageAction struct {
actionutils.ParentAction
}
func (this *ImageAction) Init() {
this.Nav("", "", "")
}
func (this *ImageAction) RunGet(params struct {
FileId int64
}) {
fileResp, err := this.RPC().FileRPC().FindEnabledFile(this.UserContext(), &pb.FindEnabledFileRequest{FileId: params.FileId})
if err != nil {
this.ErrorPage(err)
return
}
file := fileResp.File
if file == nil {
this.NotFound("file", params.FileId)
return
}
if !file.IsPublic {
this.NotFound("file", params.FileId)
return
}
chunkIdsResp, err := this.RPC().FileChunkRPC().FindAllFileChunkIds(this.UserContext(), &pb.FindAllFileChunkIdsRequest{FileId: file.Id})
if err != nil {
this.ErrorPage(err)
return
}
var mimeType = file.MimeType
if len(mimeType) == 0 {
if len(file.Filename) > 0 {
var ext = filepath.Ext(file.Filename)
mimeType = mime.TypeByExtension(ext)
}
if len(mimeType) == 0 {
mimeType = "image/png"
}
}
this.AddHeader("Last-Modified", "Fri, 06 Sep 2019 08:29:50 GMT")
this.AddHeader("Content-Type", mimeType)
this.AddHeader("Content-Length", types.String(file.Size))
for _, chunkId := range chunkIdsResp.FileChunkIds {
chunkResp, err := this.RPC().FileChunkRPC().DownloadFileChunk(this.UserContext(), &pb.DownloadFileChunkRequest{FileChunkId: chunkId})
if err != nil {
this.ErrorPage(err)
return
}
if chunkResp.FileChunk == nil {
continue
}
_, _ = this.Write(chunkResp.FileChunk.Data)
}
}

View File

@@ -0,0 +1,34 @@
package ui
import (
"compress/gzip"
"github.com/iwind/TeaGo"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/actions"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Prefix("/ui").
// 公共可以访问的链接
Get("/image/:fileId", new(ImageAction)).
// 以下需要登录
Get("/download", new(DownloadAction)).
Post("/providerOptions", new(ProviderOptionsAction)).
Post("/countryOptions", new(CountryOptionsAction)).
Post("/provinceOptions", new(ProvinceOptionsAction)).
Post("/cityOptions", new(CityOptionsAction)).
EndAll()
// 开发环境下总是动态加载,以便于调试
if Tea.IsTesting() {
server.
Helper(&actions.Gzip{Level: gzip.BestCompression}).
Get("/js/components.js", new(ComponentsAction)).
EndAll()
}
})
}

View File

@@ -0,0 +1,36 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package ui
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type ProviderOptionsAction struct {
actionutils.ParentAction
}
func (this *ProviderOptionsAction) RunPost(params struct{}) {
providersResp, err := this.RPC().RegionProviderRPC().FindAllRegionProviders(this.UserContext(), &pb.FindAllRegionProvidersRequest{})
if err != nil {
this.ErrorPage(err)
return
}
var providerMaps = []maps.Map{}
for _, provider := range providersResp.RegionProviders {
if provider.Codes == nil {
provider.Codes = []string{}
}
providerMaps = append(providerMaps, maps.Map{
"id": provider.Id,
"name": provider.Name,
"codes": provider.Codes,
})
}
this.Data["providers"] = providerMaps
this.Success()
}

View File

@@ -0,0 +1,36 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package ui
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
"github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
)
type ProvinceOptionsAction struct {
actionutils.ParentAction
}
func (this *ProvinceOptionsAction) RunPost(params struct{}) {
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.UserContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{RegionCountryId: regionconfigs.RegionChinaId})
if err != nil {
this.ErrorPage(err)
return
}
var provinceMaps = []maps.Map{}
for _, province := range provincesResp.RegionProvinces {
if province.Codes == nil {
province.Codes = []string{}
}
provinceMaps = append(provinceMaps, maps.Map{
"id": province.Id,
"name": province.DisplayName,
"codes": province.Codes,
})
}
this.Data["provinces"] = provinceMaps
this.Success()
}