feat: 合并Gin_Vue

This commit is contained in:
TsMask
2023-10-16 17:10:38 +08:00
parent 5289818fd4
commit 40a32cb67f
203 changed files with 19719 additions and 178 deletions

View File

@@ -8,9 +8,9 @@ import (
sysMenuService "ems.agt/features/sys_menu/service"
sysRoleService "ems.agt/features/sys_role/service"
"ems.agt/lib/core/cache"
"ems.agt/lib/core/conf"
"ems.agt/lib/core/vo"
"ems.agt/lib/dborm"
srcConfig "ems.agt/src/framework/config"
)
// 登录缓存用户信息
@@ -35,7 +35,7 @@ func CacheLoginUser(user *dborm.User) {
}
// 是否管理员
if conf.IsAdmin(loginUser.UserID) {
if srcConfig.IsAdmin(loginUser.UserID) {
loginUser.Permissions = []string{"*:*:*"}
} else {
// 获取权限标识

View File

@@ -2,51 +2,35 @@ package conf
import (
"fmt"
"time"
"github.com/spf13/viper"
)
var v *viper.Viper
// 配置文件读取
func InitConfig(configFile string) {
v = viper.New()
// 设置配置文件路径
viper.SetConfigFile(configFile)
v.SetConfigFile(configFile)
// 读取配置文件
err := viper.ReadInConfig()
err := v.ReadInConfig()
if err != nil {
fmt.Printf("读取配置文件失败: %v \n", err)
return
}
// 记录程序开始运行的时间点
viper.Set("runTime", time.Now())
}
// RunTime 程序开始运行的时间
func RunTime() time.Time {
return viper.GetTime("runTime")
}
// Get 获取配置信息
//
// Get("framework.name")
func Get(key string) any {
return viper.Get(key)
return v.Get(key)
}
// IsAdmin 用户是否为管理员
func IsAdmin(userID string) bool {
if userID == "" {
return false
}
// 从本地配置获取user信息
// admins := Get("user.adminList").([]any)
admins := []string{"1", "2", "3"}
for _, s := range admins {
if s == userID {
return true
}
}
return false
// AllSettings 全部配置信息
func AllSettings() map[string]interface{} {
return v.AllSettings()
}

View File

@@ -1,358 +0,0 @@
package redis
import (
"context"
"fmt"
"strings"
"time"
"ems.agt/lib/core/conf"
"ems.agt/lib/log"
"github.com/redis/go-redis/v9"
)
// Redis连接实例
var rdbMap = make(map[string]*redis.Client)
// 声明定义限流脚本命令
var rateLimitCommand = redis.NewScript(`
local key = KEYS[1]
local time = tonumber(ARGV[1])
local count = tonumber(ARGV[2])
local current = redis.call('get', key);
if current and tonumber(current) >= count then
return tonumber(current);
end
current = redis.call('incr', key)
if tonumber(current) == 1 then
redis.call('expire', key, time)
end
return tonumber(current);`)
// 连接Redis实例
func Connect() {
ctx := context.Background()
// 读取数据源配置
datasource := conf.Get("redis.dataSource").(map[string]any)
for k, v := range datasource {
client := v.(map[string]any)
// 创建连接
address := fmt.Sprintf("%s:%d", client["host"], client["port"])
rdb := redis.NewClient(&redis.Options{
Addr: address,
Password: client["password"].(string),
DB: client["db"].(int),
})
// 测试数据库连接
pong, err := rdb.Ping(ctx).Result()
if err != nil {
log.Fatalf("failed error ping redis %s %d is %v", client["host"], client["db"], err)
continue
}
log.Infof("redis %s %d %s connection is successful.", client["host"], client["db"], pong)
rdbMap[k] = rdb
}
}
// 关闭Redis实例
func Close() {
for _, rdb := range rdbMap {
if err := rdb.Close(); err != nil {
log.Errorf("fatal error db close: %s", err)
}
}
}
// 获取默认实例
func DefaultRDB() *redis.Client {
source := conf.Get("redis.defaultDataSourceName").(string)
return rdbMap[source]
}
// 获取实例
func RDB(source string) *redis.Client {
return rdbMap[source]
}
// Info 获取redis服务信息
func Info(source string) map[string]map[string]string {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
info, err := rdb.Info(ctx).Result()
if err != nil {
return map[string]map[string]string{}
}
infoObj := make(map[string]map[string]string)
lines := strings.Split(info, "\r\n")
label := ""
for _, line := range lines {
if strings.Contains(line, "#") {
label = strings.Fields(line)[len(strings.Fields(line))-1]
label = strings.ToLower(label)
infoObj[label] = make(map[string]string)
continue
}
kvArr := strings.Split(line, ":")
if len(kvArr) >= 2 {
key := strings.TrimSpace(kvArr[0])
value := strings.TrimSpace(kvArr[len(kvArr)-1])
infoObj[label][key] = value
}
}
return infoObj
}
// KeySize 获取redis当前连接可用键Key总数信息
func KeySize(source string) int64 {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
size, err := rdb.DBSize(ctx).Result()
if err != nil {
return 0
}
return size
}
// CommandStats 获取redis命令状态信息
func CommandStats(source string) []map[string]string {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
commandstats, err := rdb.Info(ctx, "commandstats").Result()
if err != nil {
return []map[string]string{}
}
statsObjArr := make([]map[string]string, 0)
lines := strings.Split(commandstats, "\r\n")
for _, line := range lines {
if !strings.HasPrefix(line, "cmdstat_") {
continue
}
kvArr := strings.Split(line, ":")
key := kvArr[0]
valueStr := kvArr[len(kvArr)-1]
statsObj := make(map[string]string)
statsObj["name"] = key[8:]
statsObj["value"] = valueStr[6:strings.Index(valueStr, ",usec=")]
statsObjArr = append(statsObjArr, statsObj)
}
return statsObjArr
}
// 获取键的剩余有效时间(秒)
func GetExpire(source string, key string) (float64, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
ttl, err := rdb.TTL(ctx, key).Result()
if err != nil {
return 0, err
}
return ttl.Seconds(), nil
}
// 获得缓存数据的key列表
func GetKeys(source string, pattern string) ([]string, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
// 初始化变量
var keys []string
var cursor uint64 = 0
ctx := context.Background()
// 循环遍历获取匹配的键
for {
// 使用 SCAN 命令获取匹配的键
batchKeys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, 100).Result()
if err != nil {
log.Errorf("Failed to scan keys: %v", err)
return keys, err
}
cursor = nextCursor
keys = append(keys, batchKeys...)
// 当 cursor 为 0表示遍历完成
if cursor == 0 {
break
}
}
return keys, nil
}
// 批量获得缓存数据
func GetBatch(source string, keys []string) ([]any, error) {
if len(keys) == 0 {
return []any{}, fmt.Errorf("not keys")
}
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
// 获取缓存数据
result, err := rdb.MGet(context.Background(), keys...).Result()
if err != nil {
log.Errorf("Failed to get batch data: %v", err)
return []any{}, err
}
return result, nil
}
// 获得缓存数据
func Get(source, key string) (string, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
value, err := rdb.Get(ctx, key).Result()
if err == redis.Nil || err != nil {
return "", err
}
return value, nil
}
// 获得缓存数据Hash
func GetHash(source, key string) (map[string]string, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
value, err := rdb.HGetAll(ctx, key).Result()
if err == redis.Nil || err != nil {
return map[string]string{}, err
}
return value, nil
}
// 判断是否存在
func Has(source string, keys ...string) (bool, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
exists, err := rdb.Exists(ctx, keys...).Result()
if err != nil {
return false, err
}
return exists >= 1, nil
}
// 设置缓存数据
func Set(source, key string, value any) (bool, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
err := rdb.Set(ctx, key, value, 0).Err()
if err != nil {
log.Errorf("redis lua script err %v", err)
return false, err
}
return true, nil
}
// 设置缓存数据与过期时间
func SetByExpire(source, key string, value any, expiration time.Duration) (bool, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
err := rdb.Set(ctx, key, value, expiration).Err()
if err != nil {
log.Errorf("redis lua script err %v", err)
return false, err
}
return true, nil
}
// 删除单个
func Del(source string, key string) (bool, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
err := rdb.Del(ctx, key).Err()
if err != nil {
log.Errorf("redis lua script err %v", err)
return false, err
}
return true, nil
}
// 删除多个
func DelKeys(source string, keys []string) (bool, error) {
if len(keys) == 0 {
return false, fmt.Errorf("no keys")
}
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
err := rdb.Del(ctx, keys...).Err()
if err != nil {
log.Errorf("redis lua script err %v", err)
return false, err
}
return true, nil
}
// 限流查询并记录
func RateLimit(source, limitKey string, time, count int64) (int64, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
ctx := context.Background()
result, err := rateLimitCommand.Run(ctx, rdb, []string{limitKey}, time, count).Result()
if err != nil {
log.Errorf("redis lua script err %v", err)
return 0, err
}
return result.(int64), err
}

View File

@@ -1,20 +0,0 @@
package crypto
import (
"golang.org/x/crypto/bcrypt"
)
// BcryptHash Bcrypt密码加密
func BcryptHash(originStr string) string {
hash, err := bcrypt.GenerateFromPassword([]byte(originStr), bcrypt.DefaultCost)
if err != nil {
return ""
}
return string(hash)
}
// BcryptCompare Bcrypt密码匹配检查
func BcryptCompare(originStr, hashStr string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashStr), []byte(originStr))
return err == nil
}

View File

@@ -8,8 +8,11 @@ import (
"net/url"
"os"
"path/filepath"
"strings"
"ems.agt/lib/core/vo"
commonConstants "ems.agt/src/framework/constants/common"
tokenConst "ems.agt/src/framework/constants/token"
"github.com/gorilla/mux"
)
@@ -101,13 +104,27 @@ func SaveUploadedFile(r *http.Request, dst string) error {
/// ==== 登录用户信息, 通过中间件后预置入
// Authorization 解析请求头
func Authorization(r *http.Request) string {
authHeader := r.Header.Get(tokenConst.HEADER_KEY)
if authHeader == "" {
return ""
}
// 拆分 Authorization 请求头,提取 JWT 令牌部分
arr := strings.Split(authHeader, tokenConst.HEADER_PREFIX)
if len(arr) == 2 && arr[1] == "" {
return ""
}
return arr[1]
}
// 定义自定义类型作为键
type ContextKey string
// LoginUser 登录用户信息需要Authorize中间件
func LoginUser(r *http.Request) (vo.LoginUser, error) {
// 上下文
v := r.Context().Value(ContextKey("LoginUser"))
v := r.Context().Value(ContextKey(commonConstants.CTX_LOGIN_USER))
if v != nil {
return v.(vo.LoginUser), nil
}