gojichu
parent
caf831c320
commit
184f05a7f7
@ -0,0 +1,12 @@
|
|||||||
|
.idea
|
||||||
|
.trae
|
||||||
|
.codebuddy
|
||||||
|
*.log
|
||||||
|
*.rar
|
||||||
|
build
|
||||||
|
ziqian
|
||||||
|
upload
|
||||||
|
package
|
||||||
|
build
|
||||||
|
node_modules
|
||||||
|
config.yaml
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
# 子千项目配置文件示例
|
||||||
|
# 复制此文件为 config.yaml 并根据实际环境修改
|
||||||
|
|
||||||
|
# Gin 框架配置
|
||||||
|
gin:
|
||||||
|
# 服务器监听端口
|
||||||
|
port: "8850"
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config 应用配置
|
||||||
|
type Config struct {
|
||||||
|
Gin GinConfig `json:"gin" yaml:"gin"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GinConfig Gin配置
|
||||||
|
type GinConfig struct {
|
||||||
|
Port string `json:"port" yaml:"port"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDefaultConfig 获取默认配置
|
||||||
|
func getDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
Gin: GinConfig{
|
||||||
|
Port: "8850",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadFromFile 从配置文件加载配置
|
||||||
|
func loadFromFile() (*Config, error) {
|
||||||
|
configPaths := []string{
|
||||||
|
"./config.yaml",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, path := range configPaths {
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("read config file error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var config Config
|
||||||
|
if err := yaml.Unmarshal(data, &config); err != nil {
|
||||||
|
return nil, fmt.Errorf("unmarshal config file error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadFromEnv 从环境变量加载配置
|
||||||
|
func loadFromEnv(config *Config) {
|
||||||
|
// 加载 Gin 配置
|
||||||
|
if port := os.Getenv("GIN_PORT"); port != "" {
|
||||||
|
config.Gin.Port = port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfig 获取配置
|
||||||
|
func GetConfig() *Config {
|
||||||
|
// 先加载默认配置
|
||||||
|
config := getDefaultConfig()
|
||||||
|
|
||||||
|
// 再从配置文件加载
|
||||||
|
if fileConfig, err := loadFromFile(); err == nil && fileConfig != nil {
|
||||||
|
// 合并配置文件中的配置
|
||||||
|
if fileConfig.Gin.Port != "" {
|
||||||
|
config.Gin.Port = fileConfig.Gin.Port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最后从环境变量加载
|
||||||
|
loadFromEnv(config)
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
module ziqian
|
||||||
|
|
||||||
|
go 1.24.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gin-gonic/gin v1.11.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||||
|
github.com/bytedance/sonic v1.15.0 // indirect
|
||||||
|
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||||
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
||||||
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
|
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
|
github.com/quic-go/qpack v0.6.0 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||||
|
go.uber.org/mock v0.6.0 // indirect
|
||||||
|
golang.org/x/arch v0.23.0 // indirect
|
||||||
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
|
golang.org/x/net v0.49.0 // indirect
|
||||||
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
|
golang.org/x/text v0.33.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
|
)
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||||
|
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||||
|
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||||
|
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||||
|
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||||
|
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||||
|
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||||
|
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
|
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||||
|
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||||
|
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||||
|
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||||
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||||
|
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||||
|
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||||
|
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||||
|
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||||
|
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||||
|
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||||
|
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||||
|
golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=
|
||||||
|
golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||||
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"ziqian/config"
|
||||||
|
"ziqian/router"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 初始化配置
|
||||||
|
cfg := config.GetConfig()
|
||||||
|
|
||||||
|
// 设置路由
|
||||||
|
r := router.SetupRouter()
|
||||||
|
|
||||||
|
// 启动服务器
|
||||||
|
addr := fmt.Sprintf(":%s", cfg.Gin.Port)
|
||||||
|
fmt.Printf("server is running on %s\n", addr)
|
||||||
|
if err := r.Run(addr); err != nil {
|
||||||
|
fmt.Printf("start server error: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
u "ziqian/utils"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupRouter() *gin.Engine {
|
||||||
|
r := gin.Default()
|
||||||
|
|
||||||
|
r.LoadHTMLFiles("templates/index.html")
|
||||||
|
|
||||||
|
// 只在开发环境中配置静态文件服务
|
||||||
|
if gin.Mode() == gin.DebugMode {
|
||||||
|
// 配置静态文件服务
|
||||||
|
r.Static("/static", "./static")
|
||||||
|
fmt.Println("Development mode: Static file services enabled")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Production mode: Static file services disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加CORS中间件
|
||||||
|
r.Use(func(c *gin.Context) {
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||||
|
|
||||||
|
if c.Request.Method == "OPTIONS" {
|
||||||
|
c.AbortWithStatus(204)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
})
|
||||||
|
|
||||||
|
r.GET("/", func(c *gin.Context) {
|
||||||
|
u.Zi.Html(c, "index.html", gin.H{
|
||||||
|
"Title": "Ziqian API",
|
||||||
|
"Subtitle": "基于 Gin 框架的 API 服务",
|
||||||
|
"CurrentTime": time.Now().Format("2006-01-02 15:04:05"),
|
||||||
|
"Version": "1.0.0",
|
||||||
|
"Year": time.Now().Year(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
apiGroup := r.Group("/api")
|
||||||
|
{
|
||||||
|
apiGroup.Any("/ho", func(c *gin.Context) {
|
||||||
|
u.Zi.Echo(c, gin.H{
|
||||||
|
"status": "ok",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
apiGroup.Any("/map", func(c *gin.Context) {
|
||||||
|
cParam := c.Query("c")
|
||||||
|
typeList := strings.Split(cParam, ",")
|
||||||
|
if cParam == "" {
|
||||||
|
typeList = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
processed := make(map[string]bool)
|
||||||
|
apiRoutes := make(map[string]string)
|
||||||
|
|
||||||
|
protocol := "http"
|
||||||
|
xForwardedProto := c.GetHeader("X-Forwarded-Proto")
|
||||||
|
xScheme := c.GetHeader("X-Scheme")
|
||||||
|
if c.Request.TLS != nil || xForwardedProto == "https" || xScheme == "https" {
|
||||||
|
protocol = "https"
|
||||||
|
}
|
||||||
|
host := c.Request.Host
|
||||||
|
|
||||||
|
for _, route := range r.Routes() {
|
||||||
|
path := route.Path
|
||||||
|
if !strings.HasPrefix(path, "/api/") || path == "/api/map" || processed[path] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
processed[path] = true
|
||||||
|
|
||||||
|
keyName := ""
|
||||||
|
for i, part := range strings.Split(strings.TrimPrefix(path, "/api/"), "/") {
|
||||||
|
if part == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
upperPart := strings.ToUpper(string(part[0])) + part[1:]
|
||||||
|
keyName += func() string {
|
||||||
|
if i > 0 {
|
||||||
|
return "_" + upperPart
|
||||||
|
}
|
||||||
|
return upperPart
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if typeList != nil {
|
||||||
|
typePrefix := strings.ToLower(strings.Split(keyName, "_")[0])
|
||||||
|
matched := false
|
||||||
|
for _, t := range typeList {
|
||||||
|
if strings.ToLower(t) == typePrefix {
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apiRoutes[keyName] = fmt.Sprintf("%s://%s%s", protocol, host, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiRoutes["Map"] = fmt.Sprintf("%s://%s%s", protocol, host, "/api/map")
|
||||||
|
apiRoutes["Ho"] = fmt.Sprintf("%s://%s%s", protocol, host, "/api/ho")
|
||||||
|
|
||||||
|
u.Zi.Echo(c, apiRoutes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
port: 7890
|
||||||
|
socks-port: 7891
|
||||||
|
allow-lan: true
|
||||||
|
mode: Rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: 127.0.0.1:9090
|
||||||
|
proxies:
|
||||||
|
- {name: 美国🇺🇸, server: 142.171.118.127, port: 59701, type: ssr, cipher: dummy, password: ssff6288, protocol: auth_aes128_md5, obfs: plain, protocol-param: "", obfs-param: "", udp: true}
|
||||||
|
proxy-groups:
|
||||||
|
- name: 🚀 节点选择
|
||||||
|
type: select
|
||||||
|
proxies:
|
||||||
|
- 🚀 手动切换
|
||||||
|
- DIRECT
|
||||||
|
- name: 🚀 手动切换
|
||||||
|
type: select
|
||||||
|
proxies:
|
||||||
|
- 美国🇺🇸
|
||||||
|
rules:
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Ziqian - 首页</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #333;
|
||||||
|
color: white;
|
||||||
|
padding: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background-color: white;
|
||||||
|
padding: 40px;
|
||||||
|
margin-top: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.api-list {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
.api-item {
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #e9ecef;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="container">
|
||||||
|
<h1>{{.Title}}</h1>
|
||||||
|
<p>{{.Subtitle}}</p>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
<h2>欢迎使用 Ziqian API</h2>
|
||||||
|
<p>这是一个基于 Gin 框架开发的 API 服务。</p>
|
||||||
|
|
||||||
|
<div class="info">
|
||||||
|
<h3>当前系统信息</h3>
|
||||||
|
<p><strong>服务器时间:</strong>{{.CurrentTime}}</p>
|
||||||
|
<p><strong>项目版本:</strong>{{.Version}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<p>© {{.Year}} Ziqian. All rights reserved.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetClientIP(c *gin.Context) string {
|
||||||
|
realIP := c.GetHeader("X-Forwarded-For")
|
||||||
|
if realIP != "" {
|
||||||
|
ips := strings.Split(realIP, ",")
|
||||||
|
for _, ip := range ips {
|
||||||
|
ip = strings.TrimSpace(ip)
|
||||||
|
if ip != "" && ip != "127.0.0.1" {
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
realIP = c.GetHeader("X-Real-IP")
|
||||||
|
if realIP != "" && realIP != "127.0.0.1" {
|
||||||
|
return realIP
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.ClientIP()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ZiUtil struct{}
|
||||||
|
|
||||||
|
var Zi = &ZiUtil{}
|
||||||
|
|
||||||
|
func (z *ZiUtil) Exit(c *gin.Context, code int, message string, data interface{}) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"code": code,
|
||||||
|
"message": message,
|
||||||
|
"data": data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (z *ZiUtil) Echo(c *gin.Context, data interface{}) {
|
||||||
|
Zi.Exit(c, 200, "ok", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (z *ZiUtil) Error(c *gin.Context, message string, code ...int) {
|
||||||
|
errCode := 100001
|
||||||
|
if len(code) > 0 {
|
||||||
|
errCode = code[0]
|
||||||
|
}
|
||||||
|
Zi.Exit(c, errCode, message, gin.H{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (z *ZiUtil) Debug(c *gin.Context, data interface{}) {
|
||||||
|
Zi.Exit(c, 100000, "debug", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (z *ZiUtil) Html(c *gin.Context, name string, data interface{}) {
|
||||||
|
c.HTML(200, name, data)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue