This commit is contained in:
wintsa 2024-04-11 14:24:55 +08:00
parent 51ac40758e
commit 36ed79167f
22 changed files with 210 additions and 305 deletions

View File

@ -38,6 +38,7 @@ RUN go env -w GO111MODULE=on \
&& export PATH=$PATH:/go/bin \ && export PATH=$PATH:/go/bin \
&& go install -a -v github.com/go-bindata/go-bindata/...@latest \ && go install -a -v github.com/go-bindata/go-bindata/...@latest \
&& go install -a -v github.com/elazarl/go-bindata-assetfs/...@latest \ && go install -a -v github.com/elazarl/go-bindata-assetfs/...@latest \
&& go install -a -v github.com/gin-contrib/cors/...@latest \
&& go-bindata-assetfs -o=assets/bindata.go -pkg=assets assets/... \ && go-bindata-assetfs -o=assets/bindata.go -pkg=assets assets/... \
&& go build -o sun-panel --ldflags="-X sun-panel/global.RUNCODE=release -X sun-panel/global.ISDOCKER=docker" main.go && go build -o sun-panel --ldflags="-X sun-panel/global.RUNCODE=release -X sun-panel/global.ISDOCKER=docker" main.go
@ -61,4 +62,4 @@ RUN apk add --no-cache bash ca-certificates su-exec tzdata \
&& chmod +x ./sun-panel \ && chmod +x ./sun-panel \
&& ./sun-panel -config && ./sun-panel -config
CMD ./sun-panel CMD ./sun-panel

12
compose-dev.yaml Normal file
View File

@ -0,0 +1,12 @@
services:
app:
entrypoint:
- sleep
- infinity
image: docker/dev-environments-default:stable-1
init: true
volumes:
- type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock

0
conf/conf.example.ini Normal file
View File

0
conf/conf.ini Normal file
View File

View File

@ -19,7 +19,8 @@
"bootstrap": "pnpm install && pnpm run common:prepare", "bootstrap": "pnpm install && pnpm run common:prepare",
"common:cleanup": "rimraf node_modules && rimraf pnpm-lock.yaml", "common:cleanup": "rimraf node_modules && rimraf pnpm-lock.yaml",
"common:prepare": "husky install", "common:prepare": "husky install",
"devBuild": " yarn run build && node copy-static-files.js && cd service && go run main.go" "devBuild": " yarn run build && node copy-static-files.js && cd service && go run main.go",
"gobindaata":"go-bindata -o assets/assets.go -pkg assets assets/"
}, },
"dependencies": { "dependencies": {
"@traptitech/markdown-it-katex": "^3.6.0", "@traptitech/markdown-it-katex": "^3.6.0",

View File

@ -80,7 +80,11 @@ func validateTransInit(validate *validator.Validate) ut.Translator {
} }
func GetCurrentUserInfo(c *gin.Context) (userInfo models.User, exist bool) { func GetCurrentUserInfo(c *gin.Context) (userInfo models.User, exist bool) {
if value, exist := c.Get("userInfo"); exist { value, exist := c.Get("userInfo")
fmt.Println("exist", exist)
fmt.Println("value", value)
if exist {
if v, ok := value.(models.User); ok { if v, ok := value.(models.User); ok {
return v, exist return v, exist
} }

View File

@ -43,7 +43,6 @@ func (a *ItemIconGroup) Edit(c *gin.Context) {
apiReturn.SuccessData(c, req) apiReturn.SuccessData(c, req)
} }
func (a *ItemIconGroup) GetList(c *gin.Context) { func (a *ItemIconGroup) GetList(c *gin.Context) {
userInfo, _ := base.GetCurrentUserInfo(c) userInfo, _ := base.GetCurrentUserInfo(c)

View File

@ -48,6 +48,11 @@ func (a *ItemIcon) Edit(c *gin.Context) {
} }
if req.ID != 0 { if req.ID != 0 {
if userInfo.Role != 1 {
apiReturn.ErrorNoAccess(c)
c.Abort()
return
}
// 修改 // 修改
updateField := []string{"IconJson", "Icon", "Title", "Url", "LanUrl", "Description", "OpenMethod", "GroupId", "UserId", "ItemIconGroupId"} updateField := []string{"IconJson", "Icon", "Title", "Url", "LanUrl", "Description", "OpenMethod", "GroupId", "UserId", "ItemIconGroupId"}
if req.Sort != 0 { if req.Sort != 0 {

View File

@ -1,6 +1,10 @@
package system package system
import ( import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv" "strconv"
"strings" "strings"
"sun-panel/api/api_v1/common/apiReturn" "sun-panel/api/api_v1/common/apiReturn"
@ -25,6 +29,9 @@ type LoginLoginVerify struct {
VCode string `json:"vcode" validate:"max=6"` VCode string `json:"vcode" validate:"max=6"`
Email string `json:"email"` Email string `json:"email"`
} }
type getTokenVerify struct {
Username string `json:"username" validate:"required"`
}
// @Summary 登录账号 // @Summary 登录账号
// @Accept application/json // @Accept application/json
@ -121,7 +128,8 @@ func (l *LoginApi) Logout(c *gin.Context) {
* @return {*} * @return {*}
*/ */
func (l LoginApi) GetToken(c *gin.Context) { func (l LoginApi) GetToken(c *gin.Context) {
param := LoginLoginVerify{} param := getTokenVerify{}
if err := c.ShouldBindJSON(&param); err != nil { if err := c.ShouldBindJSON(&param); err != nil {
apiReturn.ErrorParamFomat(c, err.Error()) apiReturn.ErrorParamFomat(c, err.Error())
return return
@ -131,9 +139,11 @@ func (l LoginApi) GetToken(c *gin.Context) {
apiReturn.ErrorParamFomat(c, errMsg) apiReturn.ErrorParamFomat(c, errMsg)
return return
} }
fmt.Print("-----------2")
settings := systemSetting.ApplicationSetting{} settings := systemSetting.ApplicationSetting{}
global.SystemSetting.GetValueByInterface("system_application", &settings) global.SystemSetting.GetValueByInterface("system_application", &settings)
fmt.Print("-----------2")
mUser := models.User{} mUser := models.User{}
var ( var (
@ -141,30 +151,64 @@ func (l LoginApi) GetToken(c *gin.Context) {
info models.User info models.User
) )
bToken := "" bToken := ""
param.Username = strings.TrimSpace(param.Username) param.Username = strings.TrimSpace(param.Username)
info, err1 := mUser.GetUserInfoByUsername(param.Username) info, err = mUser.GetUserInfoByUsername(param.Username)
if err1 != nil { if err != nil {
// 未找到记录 账号 // 未找到记录 账号
if err == gorm.ErrRecordNotFound { if err == gorm.ErrRecordNotFound {
return fmt.Print("-----------2")
client := &http.Client{}
// mUser := models.User{ data := url.Values{}
// Username: strings.TrimSpace(param.Username), data.Set("appid", "a2a6cab8-42e2-46d0-b0d2-4013e6708103")
// Password: cmn.PasswordEncryption("zw.123456"), data.Set("loginid", param.Username)
// Name: param.Username,
// HeadImage: "", // 创建 HTTP 请求
// Status: 1, req, err := http.NewRequest("POST", "https://oa.zwgczx.com/ssologin/getToken", strings.NewReader(data.Encode()))
// Role: 2, if err != nil {
// // Mail: param.Username, 不再保存邮箱账号字段 panic(err)
// } }
// userInfo, err := mUser.CreateOne()
// if err != nil { // 设置请求头
// apiReturn.ErrorDatabase(c, err.Error()) req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// return
// } // 发送POST请求
// info = userInfo res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
if strings.Contains(string(body), "Token获取失败") {
fmt.Println("请求失败: Token获取失败")
apiReturn.ErrorNoAccess(c)
panic("请求失败: Token获取失败")
return
}
mUser := models.User{
Username: strings.TrimSpace(param.Username),
Password: cmn.PasswordEncryption("zw.123456"),
Name: param.Username,
HeadImage: "",
Status: 1,
Role: 2,
// Mail: param.Username, 不再保存邮箱账号字段
}
userInfo, err := mUser.CreateOne()
if err != nil {
apiReturn.ErrorDatabase(c, err.Error())
return
}
info = userInfo
} else { } else {
// 未知错误 // 未知错误
apiReturn.Error(c, err.Error()) apiReturn.Error(c, err.Error())
@ -203,11 +247,10 @@ func (l LoginApi) GetToken(c *gin.Context) {
global.CUserToken.SetDefault(cToken, bToken) global.CUserToken.SetDefault(cToken, bToken)
global.Logger.Debug("token:", cToken, "|", bToken) global.Logger.Debug("token:", cToken, "|", bToken)
global.Logger.Debug(global.CUserToken.Get(cToken)) global.Logger.Debug(global.CUserToken.Get(cToken))
fmt.Println("info", info)
// 设置当前用户信息 // 设置当前用户信息
c.Set("userInfo", info) c.Set("userInfo", info)
info.Token = cToken // 重要 采用cToken,隐藏真实token apiReturn.SuccessData(c, cToken)
apiReturn.SuccessData(c, info)
} }
/** /**
@ -217,6 +260,25 @@ func (l LoginApi) GetToken(c *gin.Context) {
* @Description: token验证 * @Description: token验证
* @return {*} * @return {*}
*/ */
// func (l LoginApi) tokenValidate(c *gin.Context) { func (l LoginApi) VerifyToken(c *gin.Context) {
// 从请求参数中获取 token
token := c.Query("token")
fmt.Println("---------------------------", token)
// 检查 token 的有效性(这里仅做示例,实际需要根据业务逻辑来验证)
if bToken, err := global.CUserToken.Get(token); err != false {
// Token 有效,返回验证成功的响应
mUser := models.User{}
userInfo, err := mUser.GetUserInfoByToken(bToken)
if err != nil {
apiReturn.ErrorNoAccess(c)
// } return
}
apiReturn.SuccessData(c, userInfo)
} else {
// Token 无效,返回验证失败的响应
apiReturn.ErrorNoAccess(c)
}
}

View File

@ -1,258 +0,0 @@
// Code generated by go-bindata. DO NOT EDIT.
// sources:
// assets/readme.md
// assets/version
package assets
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
)
func bindataRead(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
clErr := gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
if clErr != nil {
return nil, err
}
return buf.Bytes(), nil
}
type asset struct {
bytes []byte
info os.FileInfo
}
type bindataFileInfo struct {
name string
size int64
mode os.FileMode
modTime time.Time
}
func (fi bindataFileInfo) Name() string {
return fi.name
}
func (fi bindataFileInfo) Size() int64 {
return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
return false
}
func (fi bindataFileInfo) Sys() interface{} {
return nil
}
var _assetsReadmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x54\x4d\x6f\xe3\x54\x14\xdd\xbf\x5f\xf1\xa4\xec\x2a\xc5\x56\x3a\x2a\x19\x46\x9a\x0a\x56\x61\x07\x0b\x24\x16\x08\xc9\x4e\xe2\x3a\x06\xd7\x8e\xc6\x4e\x23\x21\x16\x9e\xc9\xf7\x47\xe3\x04\xd2\x40\x43\x3a\xe9\x30\x93\x12\x3a\x34\x89\xa8\x5a\xdc\xc4\x51\xff\x8c\xef\x7b\xf6\xaa\x7f\x01\xd9\x6e\x86\x14\xaa\x0a\x34\xbb\xa7\xf7\xee\xbb\xe7\xdc\x73\xcf\xbd\x91\x08\x86\x59\xd9\x3b\x3a\x24\xc6\x73\xf7\xa2\x48\xe6\x6d\x6a\xf7\xdc\x69\x87\x54\xdb\xa2\x4a\x7a\x15\x67\x71\x49\x6a\x3f\x40\xb3\x04\xd5\x19\x98\x53\x52\xfb\xd5\x7d\xd5\x0c\xef\xa1\x5c\x42\x08\x5a\x43\x5a\xab\x92\x83\x43\x3a\x6e\x90\xa3\x11\x99\xb7\x9f\x64\x74\x3d\xab\x3d\x61\xd9\xa4\xac\x8a\x8c\xa0\x48\xbc\xa2\x0b\xfc\x2e\x93\x52\x77\xd9\x1c\xab\xe5\x14\x36\xa5\x2a\xba\xa0\xe8\xec\x66\x2c\x86\xd0\x36\x76\xac\xb9\x33\x2f\xd3\x89\x01\xcd\x9e\x57\x18\xd3\xe5\x1f\xf0\x7d\x13\x2a\x26\xcc\x3a\x50\x99\x7b\xdd\x43\xda\x2f\x42\xe5\x98\xb6\x2a\x37\x76\x13\x66\x65\xa8\xed\xd3\xb7\xd3\x87\xb9\x39\xd6\xd9\x8d\xdd\x24\x03\x83\x2e\xaa\x74\xdc\x80\xb9\x09\x66\x07\xac\x82\x73\xd5\x80\x76\x0b\xcc\x53\x32\xa8\x39\x96\xe1\x58\xa7\xff\xf8\x88\x50\x24\x12\xc1\x31\x06\xc3\xa4\xe6\xbe\x2e\xa1\x8d\x0d\x4c\xce\xc7\xa4\x68\xde\xd8\x7d\x8e\x61\x18\x0e\xae\x4b\xde\xab\x05\x58\x27\x8e\x55\xc7\x1b\x1b\x88\xe3\x38\x4d\xcb\x20\x51\xc5\xa2\xa0\x63\x51\xd2\x33\xb9\x64\x50\xab\xa8\x46\x93\x92\x92\xe6\x75\x7e\xfd\xc8\x30\xcc\x3d\xb1\x82\xcc\x7f\xcb\x3f\x93\xd7\x02\xa3\xbc\xa6\x09\xfa\x8e\x16\x7c\x40\x11\x2c\xaa\xbe\xcc\x83\xdf\xb7\x9f\xc6\x98\x58\x1c\x3b\xcb\x6b\xda\x1d\x4b\x8a\xae\xf1\xb2\x4c\x7a\x57\x60\x9b\x7e\x5a\x49\xd1\x74\x5e\x96\x71\x94\xc7\xd1\xbd\xff\x44\xe6\x23\x99\xd7\x05\x4d\x7f\xf0\xf3\xc3\xec\x56\x19\x38\x8e\x0b\xb4\xdb\x5c\x69\x47\xaa\x6d\xa8\x0f\x7d\xb9\x67\x65\xcc\x25\x3e\xfd\xec\xe3\xcf\x3f\x61\x93\x92\xc2\x61\xa8\x1f\x43\x69\x44\x5b\x53\xf8\xa5\x00\xe6\x4f\x5e\xc5\x44\x08\xcc\x17\xae\x51\x80\x76\xd1\xad\x9c\xd2\xf3\x05\x5d\x0c\xd7\xdf\xbd\xd2\x3e\x5d\x4e\x60\xff\x1c\xcc\x29\x0a\x7b\xf4\x88\xc1\xd0\x6a\x50\xfb\xb7\xd0\xbc\x61\xfb\x30\x54\x67\x38\x20\x47\x7f\x9e\xc0\xf2\x00\x39\x8b\x91\x63\x35\xa0\xb3\x74\x16\x6f\x60\x30\xfe\x42\x52\xd2\x6a\x5e\xa3\xfd\x22\x97\x55\xf3\xc2\x33\x2d\x23\xc8\x32\x07\xe6\xd4\x2d\x2c\x1d\xbb\x4f\xea\x23\xaf\x7b\xe8\xdb\xcc\x9c\x86\x12\x73\xa9\xdd\x34\x17\x1a\x64\xd5\xea\x08\x06\xdb\x00\xb3\x13\xf2\xf3\x83\xaf\x2e\xbd\xa3\x97\x74\x30\x84\xc9\x4b\x98\x95\x49\xcd\x20\x83\x5a\xc8\x27\x1c\xa6\x1b\xbb\xe9\x5c\x4f\x48\xf7\x6a\x9d\xaa\x0f\xb1\x18\x81\x59\x27\x3f\x5e\xd2\xee\x90\x1c\x54\xd1\xbf\x05\xc6\xd1\xb4\x90\xcc\x89\x38\xaa\x3e\x0d\x6e\x34\xf6\x36\x80\x11\x55\x1c\xcd\x7e\x23\xde\x5e\x63\x4d\xe7\x75\x29\xe5\xf7\x03\xef\x49\x42\x3e\x38\x44\x30\xbc\xe9\x3b\xd6\xe9\xfb\xe4\xbd\x7d\xf5\xd3\xf9\x36\x24\x67\xaf\xc1\x36\xdf\x55\x7e\x4f\x55\xed\x96\x37\x30\xdc\x93\xe7\x5e\x65\x9f\xf4\x66\x61\xfd\xf7\x12\xf8\x3f\xc8\xbe\xb7\xb6\xef\x80\x87\x20\x18\x5a\x0b\xd2\xaa\x71\xab\x72\xb8\xc0\x1a\x11\x1c\x9a\x89\xf4\x2a\xf4\xed\x31\x4a\xa8\xf8\x3b\x9c\x50\xb1\x3b\x3d\x73\xc7\x46\xb8\x31\xd6\x29\x87\x5d\x80\x93\x17\xce\xf2\xc0\xb1\x5a\x09\x49\x71\x2c\xc3\xbd\xf8\x33\x34\x40\xe2\x1d\x75\xb4\x5a\x6c\xf9\x7c\x9e\xf9\x5a\xe2\x15\x2d\x93\x0b\xe6\x23\xcb\xf2\xf1\x9d\xad\xc7\x8f\xb7\x3e\x88\x7f\x28\xec\x20\xf4\xa5\xa8\xca\xbc\x22\x7e\x95\x50\xa1\x5c\x82\x8b\xe6\xfa\x76\xfd\x5b\x09\x7f\xab\x05\x73\x02\x66\x3d\x84\xba\x03\x90\x52\xfc\xfd\xa9\x05\x00\x32\xaf\xa4\xf7\xd8\x2c\x1b\x8b\x6d\xc5\xe3\x9b\xb1\x47\x4c\x46\xdf\x95\xff\x0a\x00\x00\xff\xff\xf7\xb4\x46\x06\xba\x05\x00\x00")
func assetsReadmeMdBytes() ([]byte, error) {
return bindataRead(
_assetsReadmeMd,
"assets/readme.md",
)
}
func assetsReadmeMd() (*asset, error) {
bytes, err := assetsReadmeMdBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "assets/readme.md", size: 1466, mode: os.FileMode(438), modTime: time.Unix(1712453357, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _assetsVersion = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x32\x34\xa8\x31\xd4\x33\xd6\x33\x00\x04\x00\x00\xff\xff\x10\xcf\x99\x2f\x08\x00\x00\x00")
func assetsVersionBytes() ([]byte, error) {
return bindataRead(
_assetsVersion,
"assets/version",
)
}
func assetsVersion() (*asset, error) {
bytes, err := assetsVersionBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "assets/version", size: 8, mode: os.FileMode(438), modTime: time.Unix(1712453357, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
}
return a.bytes, nil
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
a, err := Asset(name)
if err != nil {
panic("asset: Asset(" + name + "): " + err.Error())
}
return a
}
// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
}
return a.info, nil
}
return nil, fmt.Errorf("AssetInfo %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"assets/readme.md": assetsReadmeMd,
"assets/version": assetsVersion,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for childName := range node.Children {
rv = append(rv, childName)
}
return rv, nil
}
type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
"assets": &bintree{nil, map[string]*bintree{
"readme.md": &bintree{assetsReadmeMd, map[string]*bintree{}},
"version": &bintree{assetsVersion, map[string]*bintree{}},
}},
}}
// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
data, err := Asset(name)
if err != nil {
return err
}
info, err := AssetInfo(name)
if err != nil {
return err
}
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
if err != nil {
return err
}
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
if err != nil {
return err
}
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
if err != nil {
return err
}
return nil
}
// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
children, err := AssetDir(name)
// File
if err != nil {
return RestoreAsset(dir, name)
}
// Dir
for _, child := range children {
err = RestoreAssets(dir, filepath.Join(name, child))
if err != nil {
return err
}
}
return nil
}
func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

View File

@ -0,0 +1,43 @@
# ======================
# Basic configuration
# ======================
[base]
# Web run port. Default:3002
http_port=3002
# Database driver [mysql/sqlite(Default)]
database_drive=mysql
# Cache driver [redis/memory(Default)]
cache_drive=redis
# Queue driver [redis/memory(Default)]
queue_drive=redis
# File cache path (Please start with the current path './')
# Warning: The files that have been uploaded after the modification cannot be accessed
source_path=./uploads
# File cache path.
source_temp_path=./runtime/temp
# ======================
# Mysql database driver
# ======================
[mysql]
host=192.168.2.222
port=3306
username=root
password=12300114
db_name=navpanel
wait_timeout=100
# ======================
# sqlite database driver
# ======================
[sqlite]
file_path=./database/database.db
# ======================
# redis database driver
# ======================
[redis]
address=127.0.0.1:6379
password=
prefix=sun_panel:
db=0

View File

@ -32,6 +32,7 @@ require (
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect

View File

@ -24,6 +24,8 @@ 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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=

View File

@ -14,17 +14,11 @@ import (
// 初始化总路由 // 初始化总路由
func InitRouters(addr string) error { func InitRouters(addr string) error {
router := gin.Default() router := gin.Default()
router.Use(cors.Default())
rootRouter := router.Group("/") rootRouter := router.Group("/")
routerGroup := rootRouter.Group("api") routerGroup := rootRouter.Group("api")
router.Use(cors.New(cors.Config{
// 允许所有源
AllowOrigins: []string{"*"},
// 允许所有方法
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
// 允许所有标头
AllowHeaders: []string{"*"},
}))
// 接口
system.Init(routerGroup) system.Init(routerGroup)
panel.Init(routerGroup) panel.Init(routerGroup)
openness.Init(routerGroup) openness.Init(routerGroup)

View File

@ -11,10 +11,11 @@ func InitItemIcon(router *gin.RouterGroup) {
itemIcon := api_v1.ApiGroupApp.ApiPanel.ItemIcon itemIcon := api_v1.ApiGroupApp.ApiPanel.ItemIcon
r := router.Group("", middleware.LoginInterceptor) r := router.Group("", middleware.LoginInterceptor)
{ {
r.POST("/panel/itemIcon/edit", middleware.AdminInterceptor, itemIcon.Edit)
r.POST("/panel/itemIcon/edit", itemIcon.Edit)
r.POST("/panel/itemIcon/deletes", middleware.AdminInterceptor, itemIcon.Deletes) r.POST("/panel/itemIcon/deletes", middleware.AdminInterceptor, itemIcon.Deletes)
r.POST("/panel/itemIcon/saveSort", middleware.AdminInterceptor, itemIcon.SaveSort) r.POST("/panel/itemIcon/saveSort", middleware.AdminInterceptor, itemIcon.SaveSort)
r.POST("/panel/itemIcon/addMultiple", itemIcon.AddMultiple) r.POST("/panel/itemIcon/addMultiple", middleware.AdminInterceptor, itemIcon.AddMultiple)
r.POST("/panel/itemIcon/getSiteFavicon", itemIcon.GetSiteFavicon) r.POST("/panel/itemIcon/getSiteFavicon", itemIcon.GetSiteFavicon)
} }

View File

@ -11,9 +11,9 @@ func InitItemIconGroup(router *gin.RouterGroup) {
itemIconGroup := api_v1.ApiGroupApp.ApiPanel.ItemIconGroup itemIconGroup := api_v1.ApiGroupApp.ApiPanel.ItemIconGroup
r := router.Group("", middleware.LoginInterceptor) r := router.Group("", middleware.LoginInterceptor)
{ {
r.POST("/panel/itemIconGroup/edit", itemIconGroup.Edit) r.POST("/panel/itemIconGroup/edit", middleware.AdminInterceptor, itemIconGroup.Edit)
r.POST("/panel/itemIconGroup/deletes", itemIconGroup.Deletes) r.POST("/panel/itemIconGroup/deletes", middleware.AdminInterceptor, itemIconGroup.Deletes)
r.POST("/panel/itemIconGroup/saveSort", itemIconGroup.SaveSort) r.POST("/panel/itemIconGroup/saveSort", middleware.AdminInterceptor, itemIconGroup.SaveSort)
} }
// 公开模式 // 公开模式

View File

@ -13,5 +13,6 @@ func InitLogin(router *gin.RouterGroup) {
router.POST("/login", loginApi.Login) router.POST("/login", loginApi.Login)
router.POST("/logout", middleware.LoginInterceptor, loginApi.Logout) router.POST("/logout", middleware.LoginInterceptor, loginApi.Logout)
router.POST("/getToken", loginApi.GetToken) router.POST("/getToken", loginApi.GetToken)
router.GET("/verifyToken", loginApi.VerifyToken)
} }

View File

@ -1,4 +1,4 @@
import { post } from '@/utils/request' import { post,get } from '@/utils/request'
// 登录相关 // 登录相关
@ -8,7 +8,12 @@ export function login<T>(data: Login.LoginReqest) {
data, data,
}) })
} }
//验证
export function verifyToken<T>(token: string) {
return get({
url: `/verifyToken?token=${token}`,
})
}
export function logout<T>() { export function logout<T>() {
return post<T>({ return post<T>({
url: '/logout', url: '/logout',

View File

@ -14,6 +14,7 @@ export function edit<T>(req: Panel.ItemInfo) {
}) })
} }
// export function getInfo<T>(id: number) { // export function getInfo<T>(id: number) {
// return post<T>({ // return post<T>({
// url: '/aiApplet/getInfo', // url: '/aiApplet/getInfo',

31
src/router/authToken.ts Normal file
View File

@ -0,0 +1,31 @@
import { verifyToken } from '@/api';
import { useAuthStore } from '@/store/modules/auth';
import type { Router } from 'vue-router'
export function tokenAuth(router: Router) {
router.beforeEach(async (to, from, next) => {
// 检查路由的查询参数中是否包含 token
const token = to.query.token as string | undefined;
if (token &&token.length>0) {
// 如果包含 token则发送请求验证 token
const isValidToken = await verifyToken(token);
if (isValidToken.code==0) {
// 如果 token 验证成功,则继续路由
const authStore = useAuthStore()
await authStore.setToken(token)
await authStore.setUserInfo(isValidToken.data)
next();
} else {
// 如果 token 验证失败,则重定向到其他页面(比如登录页面)
next({ name: 'login' });
}
} else {
// 如果没有 token则继续路由
next();
}
});
}

View File

@ -2,6 +2,7 @@ import type { App } from 'vue'
import type { RouteRecordRaw } from 'vue-router' import type { RouteRecordRaw } from 'vue-router'
import { createRouter, createWebHashHistory } from 'vue-router' import { createRouter, createWebHashHistory } from 'vue-router'
import { setupPageGuard } from './permission' import { setupPageGuard } from './permission'
import { tokenAuth } from './authToken'
const routes: RouteRecordRaw[] = [ const routes: RouteRecordRaw[] = [
{ {
@ -50,7 +51,7 @@ export const router = createRouter({
}) })
setupPageGuard(router) setupPageGuard(router)
tokenAuth(router)
export async function setupRouter(app: App) { export async function setupRouter(app: App) {
app.use(router) app.use(router)
await router.isReady() await router.isReady()

View File

@ -39,7 +39,6 @@ function http<T = any>(
if (loginMessageShow === false) { if (loginMessageShow === false) {
loginMessageShow = true loginMessageShow = true
message.warning(t('api.loginExpires'), { message.warning(t('api.loginExpires'), {
// message.warning('登录过期', {
onLeave() { onLeave() {
loginMessageShow = false loginMessageShow = false
}, },