Browse Source

feat: core 增加 xpack 节点管理

pull/5993/head
ssongliu 4 months ago
parent
commit
fafa042ee9
  1. 4
      .gitignore
  2. 2
      agent/init/router/router.go
  3. 16
      agent/server/server.go
  4. 2
      cmd/server/conf/app.yaml
  5. 0
      cmd/server/qqwry/qqwey.go
  6. 0
      cmd/server/qqwry/qqwry.dat
  7. 24
      core/app/api/v1/auth.go
  8. 10
      core/app/dto/common.go
  9. 11
      core/app/dto/common_req.go
  10. 9
      core/app/repo/common.go
  11. 2
      core/app/service/entry.go
  12. 8
      core/constant/errs.go
  13. 1
      core/i18n/lang/en.yaml
  14. 1
      core/i18n/lang/zh-Hant.yaml
  15. 1
      core/i18n/lang/zh.yaml
  16. 2
      core/init/migration/migrations/init.go
  17. 39
      core/init/router/router.go
  18. 40
      core/middleware/proxy.go
  19. 2
      core/router/entry.go
  20. 1
      core/server/server.go
  21. 165
      core/utils/qqwry/qqwry.go
  22. 142
      core/utils/ssh/ssh.go
  23. 2
      frontend/.env.development
  24. 2
      frontend/.env.production
  25. 14
      frontend/src/api/modules/auth.ts
  26. 2
      frontend/src/api/modules/setting.ts
  27. 4
      frontend/src/components/group/index.vue
  28. 3
      frontend/src/lang/modules/en.ts
  29. 3
      frontend/src/lang/modules/tw.ts
  30. 3
      frontend/src/lang/modules/zh.ts
  31. 2
      frontend/src/views/host/terminal/host/index.vue
  32. 2
      frontend/src/views/host/terminal/terminal/index.vue
  33. 2
      frontend/src/views/toolbox/device/ntp/index.vue
  34. 2
      frontend/src/views/website/runtime/node/operate/index.vue
  35. 2
      frontend/src/views/website/runtime/php/create/index.vue
  36. 2
      frontend/vite.config.ts

4
.gitignore vendored

@ -14,6 +14,7 @@ build/1panel
.vscode
*.project
*.factorypath
__debug*
# IntelliJ IDEA
.idea/*
@ -43,6 +44,9 @@ agent/xpack
agent/router/entry_xpack.go
agent/server/init_xpack.go
agent/utils/xpack/xpack_xpack.go
core/xpack
core/router/entry_xpack.go
core/server/init_xpack.go
.history/
dist/

2
agent/init/router/router.go

@ -31,7 +31,7 @@ func Routers() *gin.Engine {
PublicGroup.Use(gzip.Gzip(gzip.DefaultCompression))
setWebStatic(PublicGroup)
}
PrivateGroup := Router.Group("/api/v1")
PrivateGroup := Router.Group("/api/v2")
PrivateGroup.Use(middleware.GlobalLoading())
for _, router := range rou.RouterGroupApp {
router.InitRouter(PrivateGroup)

16
agent/server/server.go

@ -3,6 +3,7 @@ package server
import (
"net"
"net/http"
"os"
"github.com/1Panel-dev/1Panel/agent/cron"
"github.com/1Panel-dev/1Panel/agent/i18n"
@ -38,22 +39,11 @@ func Start() {
server := &http.Server{
Handler: rootRouter,
}
//ln, err := net.Listen("tcp4", "0.0.0.0:9998")
//if err != nil {
// panic(err)
//}
//type tcpKeepAliveListener struct {
// *net.TCPListener
//}
//
//global.LOG.Info("listen at http://0.0.0.0:9998")
//if err := server.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}); err != nil {
// panic(err)
//}
_ = os.Remove("/tmp/agent.sock")
listener, err := net.Listen("unix", "/tmp/agent.sock")
if err != nil {
panic(err)
}
server.Serve(listener)
_ = server.Serve(listener)
}

2
cmd/server/conf/app.yaml

@ -1,6 +1,6 @@
system:
db_core_file: 1Panel_Core.db
db_file: 1Panel_Core.db
db_file: 1Panel.db
base_dir: /opt
mode: dev
repo_url: https://resource.fit2cloud.com/1panel/package

0
cmd/server/conf/qqwry/qqwey.go → cmd/server/qqwry/qqwey.go

0
cmd/server/conf/qqwry/qqwry.dat → cmd/server/qqwry/qqwry.dat

24
core/app/api/v1/auth.go

@ -8,9 +8,9 @@ import (
"github.com/1Panel-dev/1Panel/core/app/model"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
// "github.com/1Panel-dev/1Panel/core/middleware"
"github.com/1Panel-dev/1Panel/core/middleware"
"github.com/1Panel-dev/1Panel/core/utils/captcha"
"github.com/1Panel-dev/1Panel/core/utils/qqwry"
"github.com/gin-gonic/gin"
)
@ -124,10 +124,10 @@ func (b *BaseApi) CheckIsSafety(c *gin.Context) {
return
}
if status == "unpass" {
// if middleware.Get.LoadErrCode("err-entrance") != 200 {
// helper.ErrResponse(c, middleware.LoadErrCode("err-entrance"))
// return
// }
if middleware.LoadErrCode("err-entrance") != 200 {
helper.ErrResponse(c, middleware.LoadErrCode("err-entrance"))
return
}
helper.ErrorWithDetail(c, constant.CodeErrEntrance, constant.ErrTypeInternalServer, nil)
return
}
@ -175,12 +175,12 @@ func saveLoginLogs(c *gin.Context, err error) {
logs.Status = constant.StatusSuccess
}
logs.IP = c.ClientIP()
// qqWry, err := qqwry.NewQQwry()
// if err != nil {
// global.LOG.Errorf("load qqwry datas failed: %s", err)
// }
// res := qqWry.Find(logs.IP)
qqWry, err := qqwry.NewQQwry()
if err != nil {
global.LOG.Errorf("load qqwry datas failed: %s", err)
}
res := qqWry.Find(logs.IP)
logs.Agent = c.GetHeader("User-Agent")
// logs.Address = res.Area
logs.Address = res.Area
_ = logService.CreateLoginLog(logs)
}

10
core/app/dto/common_res.go → core/app/dto/common.go

@ -1,5 +1,15 @@
package dto
type SearchWithPage struct {
PageInfo
Info string `json:"info"`
}
type PageInfo struct {
Page int `json:"page" validate:"required,number"`
PageSize int `json:"pageSize" validate:"required,number"`
}
type PageResult struct {
Total int64 `json:"total"`
Items interface{} `json:"items"`

11
core/app/dto/common_req.go

@ -1,11 +0,0 @@
package dto
type SearchWithPage struct {
PageInfo
Info string `json:"info"`
}
type PageInfo struct {
Page int `json:"page" validate:"required,number"`
PageSize int `json:"pageSize" validate:"required,number"`
}

9
core/app/repo/common.go

@ -7,14 +7,21 @@ import (
type DBOption func(*gorm.DB) *gorm.DB
type ICommonRepo interface {
WithByID(id uint) DBOption
WithOrderBy(orderStr string) DBOption
}
type CommonRepo struct{}
func NewCommonRepo() ICommonRepo {
func NewICommonRepo() ICommonRepo {
return &CommonRepo{}
}
func (c *CommonRepo) WithByID(id uint) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id = ?", id)
}
}
func (c *CommonRepo) WithOrderBy(orderStr string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Order(orderStr)

2
core/app/service/entry.go

@ -3,7 +3,7 @@ package service
import "github.com/1Panel-dev/1Panel/core/app/repo"
var (
commonRepo = repo.NewCommonRepo()
commonRepo = repo.NewICommonRepo()
settingRepo = repo.NewISettingRepo()
logRepo = repo.NewILogRepo()
)

8
core/constant/errs.go

@ -31,9 +31,11 @@ var (
ErrInitialPassword = errors.New("ErrInitialPassword")
ErrInvalidParams = errors.New("ErrInvalidParams")
ErrTokenParse = errors.New("ErrTokenParse")
ErrPortInUsed = "ErrPortInUsed"
ErrCmdTimeout = "ErrCmdTimeout"
ErrTokenParse = errors.New("ErrTokenParse")
ErrStructTransform = errors.New("ErrStructTransform")
ErrPortInUsed = "ErrPortInUsed"
ErrCmdTimeout = "ErrCmdTimeout"
ErrGroupIsUsed = "ErrGroupIsUsed"
)
// api

1
core/i18n/lang/en.yaml

@ -13,6 +13,7 @@ ErrNotSupportType: "The system does not support the current type: {{ .detail }}"
ErrNameIsExist: "Name is already exist"
ErrDemoEnvironment: "Demo server, prohibit this operation!"
ErrEntrance: "Security entrance information error. Please check and try again!"
ErrGroupIsUsed: "The group is in use and cannot be deleted"
#app
ErrPortInUsed: "{{ .detail }} port already in use"

1
core/i18n/lang/zh-Hant.yaml

@ -13,6 +13,7 @@ ErrNotSupportType: "系統暫不支持當前類型: {{ .detail }}"
ErrNameIsExist: "名稱已存在"
ErrDemoEnvironment: "演示伺服器,禁止此操作!"
ErrEntrance: "安全入口信息錯誤,請檢查後重試!"
ErrGroupIsUsed: "分組正在使用中,無法刪除"
#app
ErrPortInUsed: "{{ .detail }} 端口已被佔用!"

1
core/i18n/lang/zh.yaml

@ -13,6 +13,7 @@ ErrNotSupportType: "系统暂不支持当前类型: {{ .detail }}"
ErrDemoEnvironment: "演示服务器,禁止此操作!"
ErrCmdTimeout: "命令执行超时!"
ErrEntrance: "安全入口信息错误,请检查后重试!"
ErrGroupIsUsed: "分组正在使用中,无法删除"
#app
ErrPortInUsed: "{{ .detail }} 端口已被占用!"

2
core/init/migration/migrations/init.go

@ -82,7 +82,7 @@ var InitSetting = &gormigrate.Migration{
if err := tx.Create(&model.Setting{Key: "PrsoxyPasswdKeep", Value: ""}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "XpackHideMenu", Value: "{\"id\":\"1\",\"label\":\"/xpack\",\"isCheck\":true,\"title\":\"xpack.menu\",\"children\":[{\"id\":\"2\",\"title\":\"xpack.waf.name\",\"path\":\"/xpack/waf/dashboard\",\"label\":\"Dashboard\",\"isCheck\":true},{\"id\":\"3\",\"title\":\"xpack.tamper.tamper\",\"path\":\"/xpack/tamper\",\"label\":\"Tamper\",\"isCheck\":true},{\"id\":\"4\",\"title\":\"xpack.gpu.gpu\",\"path\":\"/xpack/gpu\",\"label\":\"GPU\",\"isCheck\":true},{\"id\":\"5\",\"title\":\"xpack.setting.setting\",\"path\":\"/xpack/setting\",\"label\":\"XSetting\",\"isCheck\":true},{\"id\":\"6\",\"title\":\"xpack.monitor.name\",\"path\":\"/xpack/monitor/dashboard\",\"label\":\"MonitorDashboard\",\"isCheck\":true},{\"id\":\"7\",\"title\":\"xpack.multihost.agentManagement\",\"path\":\"/xpack/multihost/manage\",\"label\":\"Multihost\",\"isCheck\":true}]}"}).Error; err != nil {
if err := tx.Create(&model.Setting{Key: "XpackHideMenu", Value: "{\"id\":\"1\",\"label\":\"/xpack\",\"isCheck\":true,\"title\":\"xpack.menu\",\"children\":[{\"id\":\"2\",\"title\":\"xpack.waf.name\",\"path\":\"/xpack/waf/dashboard\",\"label\":\"Dashboard\",\"isCheck\":true},{\"id\":\"3\",\"title\":\"xpack.tamper.tamper\",\"path\":\"/xpack/tamper\",\"label\":\"Tamper\",\"isCheck\":true},{\"id\":\"4\",\"title\":\"xpack.gpu.gpu\",\"path\":\"/xpack/gpu\",\"label\":\"GPU\",\"isCheck\":true},{\"id\":\"5\",\"title\":\"xpack.setting.setting\",\"path\":\"/xpack/setting\",\"label\":\"XSetting\",\"isCheck\":true},{\"id\":\"6\",\"title\":\"xpack.monitor.name\",\"path\":\"/xpack/monitor/dashboard\",\"label\":\"MonitorDashboard\",\"isCheck\":true},{\"id\":\"7\",\"title\":\"xpack.node.nodeManagement\",\"path\":\"/xpack/node\",\"label\":\"Node\",\"isCheck\":true}]}"}).Error; err != nil {
return err
}

39
core/init/router/router.go

@ -1,8 +1,9 @@
package router
import (
"context"
"fmt"
"net/http"
"github.com/1Panel-dev/1Panel/cmd/server/docs"
"github.com/1Panel-dev/1Panel/cmd/server/web"
"github.com/1Panel-dev/1Panel/core/global"
@ -13,11 +14,6 @@ import (
"github.com/gin-gonic/gin"
swaggerfiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"net"
"net/http"
"net/http/httputil"
"os"
"strings"
)
var (
@ -62,7 +58,7 @@ func Routers() *gin.Engine {
PublicGroup.Use(gzip.Gzip(gzip.DefaultCompression))
setWebStatic(PublicGroup)
}
PrivateGroup := Router.Group("/api/v1")
PrivateGroup := Router.Group("/api/v2/core")
PrivateGroup.Use(middleware.WhiteAllow())
PrivateGroup.Use(middleware.BindDomain())
PrivateGroup.Use(middleware.GlobalLoading())
@ -70,35 +66,6 @@ func Routers() *gin.Engine {
router.InitRouter(PrivateGroup)
}
// 使用 unix 代理
sockPath := "/tmp/agent.sock"
if _, err := os.Stat(sockPath); err != nil {
panic(err)
}
dialUnix := func(proto, addr string) (conn net.Conn, err error) {
return net.Dial("unix", sockPath)
}
transport := &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialUnix(network, addr)
},
}
proxy := &httputil.ReverseProxy{
Director: func(req *http.Request) {
req.URL.Scheme = "http"
req.URL.Host = "unix"
},
Transport: transport,
}
Router.Use(func(c *gin.Context) {
if strings.HasPrefix(c.Request.URL.Path, "/api") {
proxy.ServeHTTP(c.Writer, c.Request)
c.Abort()
return
}
c.Next()
})
Router.NoRoute(func(c *gin.Context) {
c.Writer.WriteHeader(http.StatusOK)
_, _ = c.Writer.Write(web.IndexByte)

40
core/middleware/proxy.go

@ -1,6 +1,11 @@
package middleware
import (
"context"
"net"
"net/http"
"net/http/httputil"
"os"
"strings"
"github.com/gin-gonic/gin"
@ -8,20 +13,31 @@ import (
func Proxy() gin.HandlerFunc {
return func(c *gin.Context) {
if strings.HasPrefix(c.Request.URL.Path, "/api/v1/auth") ||
strings.HasPrefix(c.Request.URL.Path, "/api/v1/setting") ||
strings.HasPrefix(c.Request.URL.Path, "/api/v1/log") {
if strings.HasPrefix(c.Request.URL.Path, "/api/v2/core") {
c.Next()
return
} else {
sockPath := "/tmp/agent.sock"
if _, err := os.Stat(sockPath); err != nil {
panic(err)
}
dialUnix := func() (conn net.Conn, err error) {
return net.Dial("unix", sockPath)
}
transport := &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialUnix()
},
}
proxy := &httputil.ReverseProxy{
Director: func(req *http.Request) {
req.URL.Scheme = "http"
req.URL.Host = "unix"
},
Transport: transport,
}
proxy.ServeHTTP(c.Writer, c.Request)
c.Abort()
}
//target, err := url.Parse("http://127.0.0.1:9998")
//if err != nil {
// fmt.Printf("Failed to parse target URL: %v", err)
//}
//proxy := httputil.NewSingleHostReverseProxy(target)
//c.Request.Host = target.Host
//c.Request.URL.Scheme = target.Scheme
//c.Request.URL.Host = target.Host
//proxy.ServeHTTP(c.Writer, c.Request)
}
}

2
core/router/entry.go

@ -1,3 +1,5 @@
//go:build !xpack
package router
func RouterGroups() []CommonRouter {

1
core/server/server.go

@ -36,6 +36,7 @@ func Start() {
cache.Init()
session.Init()
gin.SetMode("debug")
InitOthers()
hook.Init()
rootRouter := router.Routers()

165
core/utils/qqwry/qqwry.go

@ -0,0 +1,165 @@
package qqwry
import (
"encoding/binary"
"net"
"strings"
"github.com/1Panel-dev/1Panel/cmd/server/qqwry"
"golang.org/x/text/encoding/simplifiedchinese"
)
const (
indexLen = 7
redirectMode1 = 0x01
redirectMode2 = 0x02
)
var IpCommonDictionary []byte
type QQwry struct {
Data []byte
Offset int64
}
func NewQQwry() (*QQwry, error) {
IpCommonDictionary := qqwry.QQwryByte
return &QQwry{Data: IpCommonDictionary}, nil
}
// readData 从文件中读取数据
func (q *QQwry) readData(num int, offset ...int64) (rs []byte) {
if len(offset) > 0 {
q.setOffset(offset[0])
}
nums := int64(num)
end := q.Offset + nums
dataNum := int64(len(q.Data))
if q.Offset > dataNum {
return nil
}
if end > dataNum {
end = dataNum
}
rs = q.Data[q.Offset:end]
q.Offset = end
return
}
// setOffset 设置偏移量
func (q *QQwry) setOffset(offset int64) {
q.Offset = offset
}
// Find ip地址查询对应归属地信息
func (q *QQwry) Find(ip string) (res ResultQQwry) {
res = ResultQQwry{}
res.IP = ip
if strings.Count(ip, ".") != 3 {
return res
}
offset := q.searchIndex(binary.BigEndian.Uint32(net.ParseIP(ip).To4()))
if offset <= 0 {
return
}
var area []byte
mode := q.readMode(offset + 4)
if mode == redirectMode1 {
countryOffset := q.readUInt24()
mode = q.readMode(countryOffset)
if mode == redirectMode2 {
c := q.readUInt24()
area = q.readString(c)
} else {
area = q.readString(countryOffset)
}
} else if mode == redirectMode2 {
countryOffset := q.readUInt24()
area = q.readString(countryOffset)
} else {
area = q.readString(offset + 4)
}
enc := simplifiedchinese.GBK.NewDecoder()
res.Area, _ = enc.String(string(area))
return
}
type ResultQQwry struct {
IP string `json:"ip"`
Area string `json:"area"`
}
// readMode 获取偏移值类型
func (q *QQwry) readMode(offset uint32) byte {
mode := q.readData(1, int64(offset))
return mode[0]
}
// readString 获取字符串
func (q *QQwry) readString(offset uint32) []byte {
q.setOffset(int64(offset))
data := make([]byte, 0, 30)
for {
buf := q.readData(1)
if buf[0] == 0 {
break
}
data = append(data, buf[0])
}
return data
}
// searchIndex 查找索引位置
func (q *QQwry) searchIndex(ip uint32) uint32 {
header := q.readData(8, 0)
start := binary.LittleEndian.Uint32(header[:4])
end := binary.LittleEndian.Uint32(header[4:])
for {
mid := q.getMiddleOffset(start, end)
buf := q.readData(indexLen, int64(mid))
_ip := binary.LittleEndian.Uint32(buf[:4])
if end-start == indexLen {
offset := byteToUInt32(buf[4:])
buf = q.readData(indexLen)
if ip < binary.LittleEndian.Uint32(buf[:4]) {
return offset
}
return 0
}
if _ip > ip {
end = mid
} else if _ip < ip {
start = mid
} else if _ip == ip {
return byteToUInt32(buf[4:])
}
}
}
// readUInt24
func (q *QQwry) readUInt24() uint32 {
buf := q.readData(3)
return byteToUInt32(buf)
}
// getMiddleOffset
func (q *QQwry) getMiddleOffset(start uint32, end uint32) uint32 {
records := ((end - start) / indexLen) >> 1
return start + records*indexLen
}
// byteToUInt32 将 byte 转换为uint32
func byteToUInt32(data []byte) uint32 {
i := uint32(data[0]) & 0xff
i |= (uint32(data[1]) << 8) & 0xff00
i |= (uint32(data[2]) << 16) & 0xff0000
return i
}

142
core/utils/ssh/ssh.go

@ -0,0 +1,142 @@
package ssh
import (
"bytes"
"fmt"
"io"
"strings"
"sync"
"time"
gossh "golang.org/x/crypto/ssh"
)
type ConnInfo struct {
User string `json:"user"`
Addr string `json:"addr"`
Port int `json:"port"`
AuthMode string `json:"authMode"`
Password string `json:"password"`
PrivateKey []byte `json:"privateKey"`
PassPhrase []byte `json:"passPhrase"`
DialTimeOut time.Duration `json:"dialTimeOut"`
Client *gossh.Client `json:"client"`
Session *gossh.Session `json:"session"`
LastResult string `json:"lastResult"`
}
func (c *ConnInfo) NewClient() (*ConnInfo, error) {
if strings.Contains(c.Addr, ":") {
c.Addr = fmt.Sprintf("[%s]", c.Addr)
}
config := &gossh.ClientConfig{}
config.SetDefaults()
addr := fmt.Sprintf("%s:%d", c.Addr, c.Port)
config.User = c.User
if c.AuthMode == "password" {
config.Auth = []gossh.AuthMethod{gossh.Password(c.Password)}
} else {
signer, err := makePrivateKeySigner(c.PrivateKey, c.PassPhrase)
if err != nil {
return nil, err
}
config.Auth = []gossh.AuthMethod{gossh.PublicKeys(signer)}
}
if c.DialTimeOut == 0 {
c.DialTimeOut = 5 * time.Second
}
config.Timeout = c.DialTimeOut
config.HostKeyCallback = gossh.InsecureIgnoreHostKey()
proto := "tcp"
if strings.Contains(c.Addr, ":") {
proto = "tcp6"
}
client, err := gossh.Dial(proto, addr, config)
if nil != err {
return c, err
}
c.Client = client
return c, nil
}
func (c *ConnInfo) Run(shell string) (string, error) {
if c.Client == nil {
if _, err := c.NewClient(); err != nil {
return "", err
}
}
session, err := c.Client.NewSession()
if err != nil {
return "", err
}
defer session.Close()
buf, err := session.CombinedOutput(shell)
c.LastResult = string(buf)
return c.LastResult, err
}
func (c *ConnInfo) Close() {
_ = c.Client.Close()
}
type SshConn struct {
StdinPipe io.WriteCloser
ComboOutput *wsBufferWriter
Session *gossh.Session
}
func (c *ConnInfo) NewSshConn(cols, rows int) (*SshConn, error) {
sshSession, err := c.Client.NewSession()
if err != nil {
return nil, err
}
stdinP, err := sshSession.StdinPipe()
if err != nil {
return nil, err
}
comboWriter := new(wsBufferWriter)
sshSession.Stdout = comboWriter
sshSession.Stderr = comboWriter
modes := gossh.TerminalModes{
gossh.ECHO: 1,
gossh.TTY_OP_ISPEED: 14400,
gossh.TTY_OP_OSPEED: 14400,
}
if err := sshSession.RequestPty("xterm", rows, cols, modes); err != nil {
return nil, err
}
if err := sshSession.Shell(); err != nil {
return nil, err
}
return &SshConn{StdinPipe: stdinP, ComboOutput: comboWriter, Session: sshSession}, nil
}
func (s *SshConn) Close() {
if s.Session != nil {
s.Session.Close()
}
}
type wsBufferWriter struct {
buffer bytes.Buffer
mu sync.Mutex
}
func (w *wsBufferWriter) Write(p []byte) (int, error) {
w.mu.Lock()
defer w.mu.Unlock()
return w.buffer.Write(p)
}
func makePrivateKeySigner(privateKey []byte, passPhrase []byte) (gossh.Signer, error) {
if len(passPhrase) != 0 {
return gossh.ParsePrivateKeyWithPassphrase(privateKey, passPhrase)
}
return gossh.ParsePrivateKey(privateKey)
}

2
frontend/.env.development

@ -2,7 +2,7 @@
NODE_ENV = 'development'
# 本地环境接口地址
VITE_API_URL = '/api/v1'
VITE_API_URL = '/api/v2'
# 是否生成包预览文件
VITE_REPORT = false

2
frontend/.env.production

@ -2,7 +2,7 @@
NODE_ENV = "production"
# 线上环境接口地址
VITE_API_URL = '/api/v1'
VITE_API_URL = '/api/v2
# 是否生成包预览文件
VITE_REPORT = true

14
frontend/src/api/modules/auth.ts

@ -2,29 +2,29 @@ import { Login } from '@/api/interface/auth';
import http from '@/api';
export const loginApi = (params: Login.ReqLoginForm) => {
return http.post<Login.ResLogin>(`/auth/login`, params);
return http.post<Login.ResLogin>(`/core/auth/login`, params);
};
export const mfaLoginApi = (params: Login.MFALoginForm) => {
return http.post<Login.ResLogin>(`/auth/mfalogin`, params);
return http.post<Login.ResLogin>(`/core/auth/mfalogin`, params);
};
export const getCaptcha = () => {
return http.get<Login.ResCaptcha>(`/auth/captcha`);
return http.get<Login.ResCaptcha>(`/core/auth/captcha`);
};
export const logOutApi = () => {
return http.post<any>(`/auth/logout`);
return http.post<any>(`/core/auth/logout`);
};
export const checkIsSafety = (code: string) => {
return http.get<string>(`/auth/issafety?code=${code}`);
return http.get<string>(`/core/auth/issafety?code=${code}`);
};
export const checkIsDemo = () => {
return http.get<boolean>('/auth/demo');
return http.get<boolean>('/core/auth/demo');
};
export const getLanguage = () => {
return http.get<string>(`/auth/language`);
return http.get<string>(`/core/auth/language`);
};

2
frontend/src/api/modules/setting.ts

@ -26,7 +26,7 @@ export const unbindLicense = () => {
};
export const getSettingInfo = () => {
return http.post<Setting.SettingInfo>(`/settings/search`);
return http.post<Setting.SettingInfo>(`/core/settings/search`);
};
export const getSystemAvailable = () => {
return http.get(`/settings/search/available`);

4
frontend/src/components/group/index.vue

@ -18,10 +18,10 @@
<template #default="{ row }">
<div v-if="!row.edit">
<span v-if="row.name === 'default'">
{{ $t('website.default') }}
{{ $t('commons.table.default') }}
</span>
<span v-if="row.name !== 'default'">{{ row.name }}</span>
<span v-if="row.isDefault">({{ $t('website.default') }})</span>
<span v-if="row.isDefault">({{ $t('commons.table.default') }})</span>
</div>
<el-form @submit.prevent ref="groupForm" v-if="row.edit" :model="row">

3
frontend/src/lang/modules/en.ts

@ -88,6 +88,7 @@ const message = {
statusWaiting: 'Waiting...',
records: 'Records',
group: 'Group',
default: 'Default',
createdAt: 'Creation Time',
publishedAt: 'Publish Time',
date: 'Date',
@ -1928,7 +1929,6 @@ const message = {
nginxPer: 'Performance Tuning',
neverExpire: 'Never Expire',
setDefault: 'Set as default',
default: 'Default',
deleteHelper: 'Related application status is abnormal, please check',
toApp: 'Go to the installed list',
cycle: 'Cycle',
@ -2334,7 +2334,6 @@ const message = {
ustc: 'University of Science and Technology of China',
netease: 'Netease',
aliyun: 'Alibaba Cloud',
default: 'default',
tsinghua: 'Tsinghua University',
xtomhk: 'XTOM Mirror Station (Hong Kong)',
xtom: 'XTOM Mirror Station (Global)',

3
frontend/src/lang/modules/tw.ts

@ -87,6 +87,7 @@ const message = {
statusWaiting: '進行中...',
records: '任務輸出',
group: '分組',
default: '默認',
createdAt: '創建時間',
publishedAt: '發布時間',
date: '時間',
@ -1794,7 +1795,6 @@ const message = {
nginxPer: '性能調整',
neverExpire: '永不過期',
setDefault: '設為默認',
default: '默認',
deleteHelper: '相關應用狀態不正常請檢查',
toApp: '去已安裝列表',
cycle: '周期',
@ -2167,7 +2167,6 @@ const message = {
ustc: '中國科學技術大學',
netease: '網易',
aliyun: '阿里雲',
default: '默認',
tsinghua: '清華大學',
xtomhk: 'XTOM 鏡像站香港',
xtom: 'XTOM 鏡像站全球',

3
frontend/src/lang/modules/zh.ts

@ -87,6 +87,7 @@ const message = {
statusWaiting: '进行中...',
records: '任务输出',
group: '分组',
default: '默认',
createdAt: '创建时间',
publishedAt: '发布时间',
date: '时间',
@ -1796,7 +1797,6 @@ const message = {
nginxPer: '性能调整',
neverExpire: '永不过期',
setDefault: '设为默认',
default: '默认',
deleteHelper: '相关应用状态不正常请检查',
toApp: '去已安装列表',
cycle: '周期',
@ -2170,7 +2170,6 @@ const message = {
ustc: '中国科学技术大学',
netease: '网易',
aliyun: '阿里云',
default: '默认',
tsinghua: '清华大学',
xtomhk: 'XTOM 镜像站香港',
xtom: 'XTOM 镜像站全球',

2
frontend/src/views/host/terminal/host/index.vue

@ -35,7 +35,7 @@
<el-table-column :label="$t('commons.table.port')" prop="port" />
<el-table-column :label="$t('commons.table.group')" show-overflow-tooltip prop="groupBelong">
<template #default="{ row }">
<span v-if="row.groupBelong === 'default'">{{ $t('website.default') }}</span>
<span v-if="row.groupBelong === 'default'">{{ $t('commons.table.default') }}</span>
<span v-else>{{ row.groupBelong }}</span>
</template>
</el-table-column>

2
frontend/src/views/host/terminal/terminal/index.vue

@ -100,7 +100,7 @@
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<span v-if="node.label === 'default'">{{ $t('website.default') }}</span>
<span v-if="node.label === 'default'">{{ $t('commons.table.default') }}</span>
<div v-else>
<span v-if="node.label.length <= 25">
<a @click="onClickConn(node, data)">{{ node.label }}</a>

2
frontend/src/views/toolbox/device/ntp/index.vue

@ -4,7 +4,7 @@
<el-form-item :label="$t('toolbox.device.syncSite')" prop="ntpSite" :rules="Rules.domain">
<el-input v-model="form.ntpSite" />
<el-button type="primary" link class="tagClass" @click="form.ntpSite = 'pool.ntp.org'">
{{ $t('website.default') }}
{{ $t('commons.table.default') }}
</el-button>
<el-button type="primary" link class="tagClass" @click="form.ntpSite = 'ntp.aliyun.com'">
{{ $t('toolbox.device.ntpALi') }}

2
frontend/src/views/website/runtime/node/operate/index.vue

@ -265,7 +265,7 @@ const hasPnpm = computed(() => {
const imageSources = [
{
label: i18n.global.t('runtime.default'),
label: i18n.global.t('commons.table.default'),
value: 'https://registry.npmjs.org/',
},
{

2
frontend/src/views/website/runtime/php/create/index.vue

@ -243,7 +243,7 @@ const phpSources = [
value: 'mirrors.xtom.com',
},
{
label: i18n.global.t('runtime.default'),
label: i18n.global.t('commons.table.default'),
value: 'dl-cdn.alpinelinux.org',
},
];

2
frontend/vite.config.ts

@ -51,7 +51,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
open: viteEnv.VITE_OPEN,
host: '0.0.0.0',
proxy: {
'/api/v1': {
'/api/v2': {
target: 'http://localhost:9999/',
changeOrigin: true,
ws: true,

Loading…
Cancel
Save