merge: 合并OMC分支
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
sysMenuService "nms_cxy/features/sys_menu/service"
|
||||
sysRoleService "nms_cxy/features/sys_role/service"
|
||||
"nms_cxy/lib/core/cache"
|
||||
"nms_cxy/lib/core/vo"
|
||||
"nms_cxy/lib/dborm"
|
||||
srcConfig "nms_cxy/src/framework/config"
|
||||
)
|
||||
|
||||
// 登录缓存用户信息
|
||||
func CacheLoginUser(user *dborm.User) {
|
||||
// 过期时间
|
||||
expiresStr, err := dborm.XormGetConfigValue("Security", "sessionExpires")
|
||||
if err != nil {
|
||||
expiresStr = "18000"
|
||||
}
|
||||
expiresValue, _ := strconv.Atoi(expiresStr)
|
||||
expireTime := time.Duration(expiresValue) * time.Second
|
||||
|
||||
nowTime := time.Now().UnixMilli()
|
||||
|
||||
// 登录用户
|
||||
loginUser := vo.LoginUser{
|
||||
UserID: fmt.Sprint(user.Id),
|
||||
UserName: user.Name,
|
||||
ExpireTime: nowTime + expireTime.Milliseconds(),
|
||||
LoginTime: nowTime,
|
||||
User: *user,
|
||||
}
|
||||
|
||||
// 是否管理员
|
||||
if srcConfig.IsAdmin(loginUser.UserID) {
|
||||
loginUser.Permissions = []string{"*:*:*"}
|
||||
} else {
|
||||
// 获取权限标识
|
||||
loginUser.Permissions = sysMenuService.NewRepoSysMenu.SelectMenuPermsByUserId(loginUser.UserID)
|
||||
// 获取角色信息
|
||||
loginUser.User.Roles = sysRoleService.NewRepoSysRole.SelectRoleListByUserId(loginUser.UserID)
|
||||
}
|
||||
|
||||
// 缓存时间
|
||||
cache.SetLocalTTL(user.AccountId, loginUser, time.Duration(expireTime))
|
||||
}
|
||||
|
||||
// 清除缓存用户信息
|
||||
func ClearLoginUser(accountId string) {
|
||||
cache.DeleteLocalTTL(accountId)
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package cachekey
|
||||
|
||||
// 缓存的key常量
|
||||
|
||||
// 登录用户
|
||||
const LOGIN_TOKEN_KEY = "login_tokens:"
|
||||
|
||||
// 验证码
|
||||
const CAPTCHA_CODE_KEY = "captcha_codes:"
|
||||
|
||||
// 参数管理
|
||||
const SYS_CONFIG_KEY = "sys_config:"
|
||||
|
||||
// 字典管理
|
||||
const SYS_DICT_KEY = "sys_dict:"
|
||||
|
||||
// 防重提交
|
||||
const REPEAT_SUBMIT_KEY = "repeat_submit:"
|
||||
|
||||
// 限流
|
||||
const RATE_LIMIT_KEY = "rate_limit:"
|
||||
|
||||
// 登录账户密码错误次数
|
||||
const PWD_ERR_CNT_KEY = "pwd_err_cnt:"
|
||||
@@ -10,16 +10,16 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"nms_cxy/lib/core/vo"
|
||||
commonConstants "nms_cxy/src/framework/constants/common"
|
||||
tokenConst "nms_cxy/src/framework/constants/token"
|
||||
"nms_cxy/src/framework/constants/token"
|
||||
tokenUtils "nms_cxy/src/framework/utils/token"
|
||||
"nms_cxy/src/framework/vo"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// Param 地址栏参数{id}
|
||||
func Param(r *http.Request, key string) string {
|
||||
// GetParam 地址栏参数{id}
|
||||
func GetParam(r *http.Request, key string) string {
|
||||
vars := mux.Vars(r)
|
||||
v, ok := vars[key]
|
||||
if ok {
|
||||
@@ -48,7 +48,7 @@ func QueryMap(r *http.Request) map[string]any {
|
||||
return queryParams
|
||||
}
|
||||
|
||||
// ShouldBindQuery 查询参数读取json请求结构团体
|
||||
// ShouldBindQuery 查询参数读取json请求结构团体 &xxx
|
||||
func ShouldBindQuery(r *http.Request, args any) error {
|
||||
queryParams := QueryMap(r)
|
||||
body, err := json.Marshal(queryParams)
|
||||
@@ -58,7 +58,7 @@ func ShouldBindQuery(r *http.Request, args any) error {
|
||||
return json.Unmarshal(body, args)
|
||||
}
|
||||
|
||||
// 读取json请求结构团体
|
||||
// ShouldBindJSON 读取json请求结构团体 &xxx
|
||||
func ShouldBindJSON(r *http.Request, args any) error {
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) // 设置较大的长度,例如 1<<20 (1MB)
|
||||
if err != nil {
|
||||
@@ -123,12 +123,26 @@ func SaveUploadedFile(r *http.Request, dst string) error {
|
||||
|
||||
// Authorization 解析请求头
|
||||
func Authorization(r *http.Request) string {
|
||||
authHeader := r.Header.Get(tokenConst.HEADER_KEY)
|
||||
// Query请求查询
|
||||
if authQuery := r.URL.Query().Get(token.ACCESS_TOKEN); authQuery != "" {
|
||||
return authQuery
|
||||
}
|
||||
// Header请求头
|
||||
if authHeader := r.Header.Get(token.ACCESS_TOKEN); authHeader != "" {
|
||||
return authHeader
|
||||
}
|
||||
|
||||
// Query请求查询
|
||||
if authQuery := r.URL.Query().Get(token.RESPONSE_FIELD); authQuery != "" {
|
||||
return authQuery
|
||||
}
|
||||
// Header请求头
|
||||
authHeader := r.Header.Get(token.HEADER_KEY)
|
||||
if authHeader == "" {
|
||||
return ""
|
||||
}
|
||||
// 拆分 Authorization 请求头,提取 JWT 令牌部分
|
||||
arr := strings.Split(authHeader, tokenConst.HEADER_PREFIX)
|
||||
arr := strings.Split(authHeader, token.HEADER_PREFIX)
|
||||
if len(arr) == 2 && arr[1] == "" {
|
||||
return ""
|
||||
}
|
||||
@@ -165,12 +179,24 @@ type ContextKey string
|
||||
|
||||
// LoginUser 登录用户信息需要Authorize中间件
|
||||
func LoginUser(r *http.Request) (vo.LoginUser, error) {
|
||||
// 上下文
|
||||
v := r.Context().Value(ContextKey(commonConstants.CTX_LOGIN_USER))
|
||||
if v != nil {
|
||||
return v.(vo.LoginUser), nil
|
||||
// 获取请求头标识信息
|
||||
tokenStr := Authorization(r)
|
||||
if tokenStr == "" {
|
||||
return vo.LoginUser{}, fmt.Errorf("not token info")
|
||||
}
|
||||
return vo.LoginUser{}, fmt.Errorf("No user information")
|
||||
// 验证令牌
|
||||
claims, err := tokenUtils.Verify(tokenStr)
|
||||
if err != nil {
|
||||
return vo.LoginUser{}, fmt.Errorf("token verify fail")
|
||||
}
|
||||
|
||||
// 获取缓存的用户信息
|
||||
loginUser := tokenUtils.LoginUser(claims)
|
||||
if loginUser.UserID == "" {
|
||||
return vo.LoginUser{}, fmt.Errorf("not user info")
|
||||
}
|
||||
|
||||
return loginUser, nil
|
||||
}
|
||||
|
||||
// LoginUserToUserID 登录用户信息-用户ID
|
||||
@@ -188,5 +214,5 @@ func LoginUserToUserName(r *http.Request) string {
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return loginUser.UserName
|
||||
return loginUser.User.UserName
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package datasource
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"regexp"
|
||||
|
||||
"nms_cxy/lib/dborm"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// 获取默认数据源
|
||||
func DefaultDB() *xorm.Engine {
|
||||
return dborm.DbClient.XEngine
|
||||
}
|
||||
|
||||
// RawDB 原生查询语句
|
||||
func RawDB(source string, sql string, parameters []any) ([]map[string]any, error) {
|
||||
// 数据源
|
||||
db := DefaultDB()
|
||||
|
||||
// 使用正则表达式替换连续的空白字符为单个空格
|
||||
fmtSql := regexp.MustCompile(`\s+`).ReplaceAllString(sql, " ")
|
||||
|
||||
// log.Infof("sql=> %v", fmtSql)
|
||||
// log.Infof("parameters=> %v", parameters)
|
||||
|
||||
// 查询结果
|
||||
var rows []map[string]any
|
||||
err := db.SQL(fmtSql, parameters...).Find(&rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// ExecDB 原生执行语句
|
||||
func ExecDB(source string, sql string, parameters []any) (sql.Result, error) {
|
||||
// 数据源
|
||||
db := DefaultDB()
|
||||
|
||||
// 使用正则表达式替换连续的空白字符为单个空格
|
||||
fmtSql := regexp.MustCompile(`\s+`).ReplaceAllString(sql, " ")
|
||||
// 执行结果
|
||||
res, err := db.Exec(append([]any{fmtSql}, parameters...)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package datasource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PageNumSize 分页页码记录数
|
||||
func PageNumSize(pageNum, pageSize any) (int, int) {
|
||||
// 记录起始索引
|
||||
pageNumStr := fmt.Sprintf("%v", pageNum)
|
||||
num := 1
|
||||
if v, err := strconv.Atoi(pageNumStr); err == nil && v > 0 {
|
||||
num = v
|
||||
}
|
||||
|
||||
// 显示记录数
|
||||
pageSizeStr := fmt.Sprintf("%v", pageSize)
|
||||
size := 10
|
||||
if v, err := strconv.Atoi(pageSizeStr); err == nil && v > 0 {
|
||||
size = v
|
||||
}
|
||||
return num - 1, size
|
||||
}
|
||||
|
||||
// SetFieldValue 判断结构体内是否存在指定字段并设置值
|
||||
func SetFieldValue(obj any, fieldName string, value any) {
|
||||
// 获取结构体的反射值
|
||||
userValue := reflect.ValueOf(obj)
|
||||
|
||||
// 获取字段的反射值
|
||||
fieldValue := userValue.Elem().FieldByName(fieldName)
|
||||
|
||||
// 检查字段是否存在
|
||||
if fieldValue.IsValid() && fieldValue.CanSet() {
|
||||
// 获取字段的类型
|
||||
fieldType := fieldValue.Type()
|
||||
|
||||
// 转换传入的值类型为字段类型
|
||||
switch fieldType.Kind() {
|
||||
case reflect.String:
|
||||
if value == nil {
|
||||
fieldValue.SetString("")
|
||||
} else {
|
||||
fieldValue.SetString(fmt.Sprintf("%v", value))
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
intValue, err := strconv.ParseInt(fmt.Sprintf("%v", value), 10, 64)
|
||||
if err != nil {
|
||||
intValue = 0
|
||||
}
|
||||
fieldValue.SetInt(intValue)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
uintValue, err := strconv.ParseUint(fmt.Sprintf("%v", value), 10, 64)
|
||||
if err != nil {
|
||||
uintValue = 0
|
||||
}
|
||||
fieldValue.SetUint(uintValue)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
floatValue, err := strconv.ParseFloat(fmt.Sprintf("%v", value), 64)
|
||||
if err != nil {
|
||||
floatValue = 0
|
||||
}
|
||||
fieldValue.SetFloat(floatValue)
|
||||
default:
|
||||
// 设置字段的值
|
||||
fieldValue.Set(reflect.ValueOf(value).Convert(fieldValue.Type()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertIdsSlice 将 []string 转换为 []any
|
||||
func ConvertIdsSlice(ids []string) []any {
|
||||
// 将 []string 转换为 []any
|
||||
arr := make([]any, len(ids))
|
||||
for i, v := range ids {
|
||||
arr[i] = v
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// 查询-参数值的占位符
|
||||
func KeyPlaceholderByQuery(sum int) string {
|
||||
placeholders := make([]string, sum)
|
||||
for i := 0; i < sum; i++ {
|
||||
placeholders[i] = "?"
|
||||
}
|
||||
return strings.Join(placeholders, ",")
|
||||
}
|
||||
|
||||
// 插入-参数映射键值占位符 keys, placeholder, values
|
||||
func KeyPlaceholderValueByInsert(params map[string]any) ([]string, string, []any) {
|
||||
// 参数映射的键
|
||||
keys := make([]string, len(params))
|
||||
// 参数映射的值
|
||||
values := make([]any, len(params))
|
||||
sum := 0
|
||||
for k, v := range params {
|
||||
keys[sum] = k
|
||||
values[sum] = v
|
||||
sum++
|
||||
}
|
||||
// 参数值的占位符
|
||||
placeholders := make([]string, sum)
|
||||
for i := 0; i < sum; i++ {
|
||||
placeholders[i] = "?"
|
||||
}
|
||||
return keys, strings.Join(placeholders, ","), values
|
||||
}
|
||||
|
||||
// 更新-参数映射键值占位符 keys, values
|
||||
func KeyValueByUpdate(params map[string]any) ([]string, []any) {
|
||||
// 参数映射的键
|
||||
keys := make([]string, len(params))
|
||||
// 参数映射的值
|
||||
values := make([]any, len(params))
|
||||
sum := 0
|
||||
for k, v := range params {
|
||||
keys[sum] = k + "=?"
|
||||
values[sum] = v
|
||||
sum++
|
||||
}
|
||||
return keys, values
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package mmlclient
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"nms_cxy/lib/core/conf"
|
||||
)
|
||||
|
||||
// 定义MMLClient结构体
|
||||
type MMLClient struct {
|
||||
awaitTime time.Duration // 等待时间
|
||||
conn net.Conn
|
||||
reader *bufio.Reader
|
||||
size int // 包含字符
|
||||
}
|
||||
|
||||
// 封装NewMMLClient函数,用于创建MMLClient实例
|
||||
// 网元UDM的IP地址 "198.51.100.1"
|
||||
func NewMMLClient(ip string) (*MMLClient, error) {
|
||||
// 创建TCP连接
|
||||
portMML := conf.Get("mml.port").(int)
|
||||
hostMML := fmt.Sprintf("%s:%d", ip, portMML)
|
||||
conn, err := net.Dial("tcp", hostMML)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 进行登录
|
||||
usernameMML := conf.Get("mml.user").(string)
|
||||
passwordMML := conf.Get("mml.password").(string)
|
||||
fmt.Fprintln(conn, usernameMML)
|
||||
fmt.Fprintln(conn, passwordMML)
|
||||
|
||||
// 发送后等待
|
||||
awaitTime := time.Duration(300) * time.Millisecond
|
||||
time.Sleep(awaitTime)
|
||||
|
||||
// 读取内容
|
||||
buf := make([]byte, 1024*1024*1)
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建MMLClient实例
|
||||
client := &MMLClient{
|
||||
conn: conn,
|
||||
reader: bufio.NewReader(conn),
|
||||
awaitTime: awaitTime,
|
||||
size: n,
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// 封装Send函数,用于向TCP连接发送数据
|
||||
func (c *MMLClient) Send(msg string) error {
|
||||
_, err := fmt.Fprintln(c.conn, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(c.awaitTime)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 封装Receive函数,用于从TCP连接中接收数据
|
||||
func (c *MMLClient) Receive() (string, error) {
|
||||
buf := make([]byte, 1024*1024*1)
|
||||
n, err := c.reader.Read(buf)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return "", fmt.Errorf("server closed the connection")
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
c.size += n
|
||||
return string(buf[0:n]), nil
|
||||
}
|
||||
|
||||
// 封装Close函数,用于关闭TCP连接
|
||||
func (c *MMLClient) Close() error {
|
||||
return c.conn.Close()
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package mmlclient
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 发送MML原始消息
|
||||
// ip 网元IP地址
|
||||
// msg 指令
|
||||
func MMLSendMsg(ip, msg string) (string, error) {
|
||||
// 创建MMLClient实例
|
||||
client, err := NewMMLClient(ip)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create MMLClient instance: %v", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// 发送数据
|
||||
err = client.Send(msg)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("sending data failed: %v", err)
|
||||
}
|
||||
|
||||
// 接收数据
|
||||
data, err := client.Receive()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to receive data: %v", err)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
// ip 网元IP地址
|
||||
// msg 指令
|
||||
func MMLSendMsgToString(ip, msg string) (string, error) {
|
||||
// 发送获取数据
|
||||
str, err := MMLSendMsg(ip, msg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
str = strings.ToLower(str)
|
||||
|
||||
// 截断
|
||||
index := strings.Index(str, "\n")
|
||||
if index != -1 {
|
||||
str = str[:index]
|
||||
}
|
||||
|
||||
// 命令成功
|
||||
if strings.Contains(str, "ok") || strings.Contains(str, "success") {
|
||||
return str, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf(str)
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
// ip 网元IP地址
|
||||
// msg 指令
|
||||
func MMLSendMsgToMap(ip, msg string) (map[string]string, error) {
|
||||
// 发送获取数据
|
||||
str, err := MMLSendMsg(ip, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 无数据
|
||||
if strings.HasPrefix(str, "No Auth Data") {
|
||||
return nil, fmt.Errorf("no auth data")
|
||||
}
|
||||
|
||||
// 初始化一个map用于存储拆分后的键值对
|
||||
m := make(map[string]string)
|
||||
|
||||
var items []string
|
||||
if strings.Contains(str, "\r\n") {
|
||||
// 按照分隔符"\r\n"进行拆分
|
||||
items = strings.Split(str, "\r\n")
|
||||
} else if strings.Contains(str, "\n") {
|
||||
// 按照分隔符"\n"进行拆分
|
||||
items = strings.Split(str, "\n")
|
||||
}
|
||||
|
||||
// 遍历拆分后的结果
|
||||
for _, item := range items {
|
||||
var pair []string
|
||||
|
||||
if strings.Contains(item, "=") {
|
||||
// 按照分隔符"="进行拆分键值对
|
||||
pair = strings.SplitN(item, "=", 2)
|
||||
} else if strings.Contains(item, ":") {
|
||||
// 按照分隔符":"进行拆分键值对
|
||||
pair = strings.SplitN(item, ":", 2)
|
||||
}
|
||||
|
||||
if len(pair) == 2 {
|
||||
// 将键值对存入map中
|
||||
m[pair[0]] = pair[1]
|
||||
}
|
||||
}
|
||||
return m, err
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package date
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"nms_cxy/lib/log"
|
||||
)
|
||||
|
||||
const (
|
||||
// 年 列如:2022
|
||||
YYYY = "2006"
|
||||
// 年-月 列如:2022-12
|
||||
YYYY_MM = "2006-01"
|
||||
// 年-月-日 列如:2022-12-30
|
||||
YYYY_MM_DD = "2006-01-02"
|
||||
// 年月日时分秒 列如:20221230010159
|
||||
YYYYMMDDHHMMSS = "20060102150405"
|
||||
// 年-月-日 时:分:秒 列如:2022-12-30 01:01:59
|
||||
YYYY_MM_DD_HH_MM_SS = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
// 格式时间字符串
|
||||
//
|
||||
// dateStr 时间字符串
|
||||
//
|
||||
// formatStr 时间格式 默认YYYY-MM-DD HH:mm:ss
|
||||
func ParseStrToDate(dateStr, formatStr string) time.Time {
|
||||
t, err := time.Parse(formatStr, dateStr)
|
||||
if err != nil {
|
||||
log.Infof("utils ParseStrToDate err %v", err)
|
||||
return time.Time{}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// 格式时间
|
||||
//
|
||||
// date 可转的Date对象
|
||||
//
|
||||
// formatStr 时间格式 默认YYYY-MM-DD HH:mm:ss
|
||||
func ParseDateToStr(date any, formatStr string) string {
|
||||
t, ok := date.(time.Time)
|
||||
if !ok {
|
||||
switch v := date.(type) {
|
||||
case int64:
|
||||
if v == 0 {
|
||||
return ""
|
||||
}
|
||||
t = time.UnixMilli(v)
|
||||
case string:
|
||||
parsedTime, err := time.Parse(formatStr, v)
|
||||
if err != nil {
|
||||
fmt.Printf("utils ParseDateToStr err %v \n", err)
|
||||
return ""
|
||||
}
|
||||
t = parsedTime
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return t.Format(formatStr)
|
||||
}
|
||||
|
||||
// 格式时间成日期路径
|
||||
//
|
||||
// 年/月 列如:2022/12
|
||||
func ParseDatePath(date time.Time) string {
|
||||
return date.Format("2006/01")
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
package parse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
// Number 解析数值型
|
||||
func Number(str any) int64 {
|
||||
switch str := str.(type) {
|
||||
case string:
|
||||
if str == "" {
|
||||
return 0
|
||||
}
|
||||
num, err := strconv.ParseInt(str, 10, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return num
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
return reflect.ValueOf(str).Int()
|
||||
case float32, float64:
|
||||
return int64(reflect.ValueOf(str).Float())
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// Boolean 解析布尔型
|
||||
func Boolean(str any) bool {
|
||||
switch str := str.(type) {
|
||||
case string:
|
||||
if str == "" || str == "false" || str == "0" {
|
||||
return false
|
||||
}
|
||||
// 尝试将字符串解析为数字
|
||||
if num, err := strconv.ParseFloat(str, 64); err == nil {
|
||||
return num != 0
|
||||
}
|
||||
return true
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
num := reflect.ValueOf(str).Int()
|
||||
return num != 0
|
||||
case float32, float64:
|
||||
num := reflect.ValueOf(str).Float()
|
||||
return num != 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// FirstUpper 首字母转大写
|
||||
//
|
||||
// 字符串 abc_123!@# 结果 Abc_123
|
||||
func FirstUpper(str string) string {
|
||||
if len(str) == 0 {
|
||||
return str
|
||||
}
|
||||
reg := regexp.MustCompile(`[^_\w]+`)
|
||||
str = reg.ReplaceAllString(str, "")
|
||||
return strings.ToUpper(str[:1]) + str[1:]
|
||||
}
|
||||
|
||||
// Bit 比特位为单位
|
||||
func Bit(bit float64) string {
|
||||
var GB, MB, KB string
|
||||
|
||||
if bit > float64(1<<30) {
|
||||
GB = fmt.Sprintf("%0.2f", bit/(1<<30))
|
||||
}
|
||||
|
||||
if bit > float64(1<<20) && bit < (1<<30) {
|
||||
MB = fmt.Sprintf("%.2f", bit/(1<<20))
|
||||
}
|
||||
|
||||
if bit > float64(1<<10) && bit < (1<<20) {
|
||||
KB = fmt.Sprintf("%.2f", bit/(1<<10))
|
||||
}
|
||||
|
||||
if GB != "" {
|
||||
return GB + "GB"
|
||||
} else if MB != "" {
|
||||
return MB + "MB"
|
||||
} else if KB != "" {
|
||||
return KB + "KB"
|
||||
} else {
|
||||
return fmt.Sprintf("%vB", bit)
|
||||
}
|
||||
}
|
||||
|
||||
// CronExpression 解析 Cron 表达式,返回下一次执行的时间戳(毫秒)
|
||||
//
|
||||
// 【*/5 * * * * ?】 6个参数
|
||||
func CronExpression(expression string) int64 {
|
||||
specParser := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
|
||||
schedule, err := specParser.Parse(expression)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return 0
|
||||
}
|
||||
return schedule.Next(time.Now()).UnixMilli()
|
||||
}
|
||||
|
||||
// SafeContent 内容值进行安全掩码
|
||||
func SafeContent(value string) string {
|
||||
if len(value) < 3 {
|
||||
return strings.Repeat("*", len(value))
|
||||
} else if len(value) < 6 {
|
||||
return string(value[0]) + strings.Repeat("*", len(value)-1)
|
||||
} else if len(value) < 10 {
|
||||
return string(value[0]) + strings.Repeat("*", len(value)-2) + string(value[len(value)-1])
|
||||
} else if len(value) < 15 {
|
||||
return value[:2] + strings.Repeat("*", len(value)-4) + value[len(value)-2:]
|
||||
} else {
|
||||
return value[:3] + strings.Repeat("*", len(value)-6) + value[len(value)-3:]
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveDuplicates 数组内字符串去重
|
||||
func RemoveDuplicates(ids []string) []string {
|
||||
uniqueIDs := make(map[string]bool)
|
||||
uniqueIDSlice := make([]string, 0)
|
||||
|
||||
for _, id := range ids {
|
||||
_, ok := uniqueIDs[id]
|
||||
if !ok && id != "" {
|
||||
uniqueIDs[id] = true
|
||||
uniqueIDSlice = append(uniqueIDSlice, id)
|
||||
}
|
||||
}
|
||||
|
||||
return uniqueIDSlice
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package regular
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Replace 正则替换
|
||||
func Replace(originStr, pattern, repStr string) string {
|
||||
regex := regexp.MustCompile(pattern)
|
||||
return regex.ReplaceAllString(originStr, repStr)
|
||||
}
|
||||
|
||||
// 判断是否为有效用户名格式
|
||||
//
|
||||
// 用户名不能以数字开头,可包含大写小写字母,数字,且不少于5位
|
||||
func ValidUsername(username string) bool {
|
||||
if username == "" {
|
||||
return false
|
||||
}
|
||||
pattern := `^[a-zA-Z][a-z0-9A-Z]{5,}`
|
||||
match, err := regexp.MatchString(pattern, username)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
||||
// 判断是否为有效手机号格式,1开头的11位手机号
|
||||
func ValidMobile(mobile string) bool {
|
||||
if mobile == "" {
|
||||
return false
|
||||
}
|
||||
pattern := `^1[3|4|5|6|7|8|9][0-9]\d{8}$`
|
||||
match, err := regexp.MatchString(pattern, mobile)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
||||
// 判断是否为http(s)://开头
|
||||
//
|
||||
// link 网络链接
|
||||
func ValidHttp(link string) bool {
|
||||
if link == "" {
|
||||
return false
|
||||
}
|
||||
pattern := `^http(s)?:\/\/+`
|
||||
match, err := regexp.MatchString(pattern, link)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return match
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package scan
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ScanPort(port int) bool {
|
||||
ln, err := net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
defer ln.Close()
|
||||
return false
|
||||
}
|
||||
|
||||
func ScanUDPPort(port int) bool {
|
||||
ln, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: port})
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
defer ln.Close()
|
||||
return false
|
||||
}
|
||||
|
||||
func ScanPortWithProto(port int, proto string) bool {
|
||||
if proto == "udp" {
|
||||
return ScanUDPPort(port)
|
||||
}
|
||||
return ScanPort(port)
|
||||
}
|
||||
@@ -23,6 +23,4 @@ type LoginUser struct {
|
||||
|
||||
// User 用户信息
|
||||
User dborm.User `json:"user"`
|
||||
|
||||
Session dborm.Session `json:"-"`
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package vo
|
||||
|
||||
// Router 路由信息对象
|
||||
type Router struct {
|
||||
// 路由名字 英文首字母大写
|
||||
Name string `json:"name"`
|
||||
// 路由地址
|
||||
Path string `json:"path"`
|
||||
// 其他元素
|
||||
Meta RouterMeta `json:"meta"`
|
||||
// 组件地址
|
||||
Component string `json:"component"`
|
||||
// 重定向地址
|
||||
Redirect string `json:"redirect"`
|
||||
// 子路由
|
||||
Children []Router `json:"children,omitempty"`
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package vo
|
||||
|
||||
// RouterMeta 路由元信息对象
|
||||
type RouterMeta struct {
|
||||
// 设置该菜单在侧边栏和面包屑中展示的名字
|
||||
Title string `json:"title"`
|
||||
// 设置该菜单的图标
|
||||
Icon string `json:"icon"`
|
||||
// 设置为true,则不会被 <keep-alive>缓存
|
||||
Cache bool `json:"cache"`
|
||||
// 内链地址(http(s)://开头), 打开目标位置 '_blank' | '_self' | ''
|
||||
Target string `json:"target"`
|
||||
// 在菜单中隐藏子节点
|
||||
HideChildInMenu bool `json:"hideChildInMenu"`
|
||||
// 在菜单中隐藏自己和子节点
|
||||
HideInMenu bool `json:"hideInMenu"`
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package vo
|
||||
|
||||
// import sysmenu "nms_cxy/features/sys_menu"
|
||||
|
||||
// TreeSelect 树结构实体类
|
||||
type TreeSelect struct {
|
||||
// ID 节点ID
|
||||
ID string `json:"id"`
|
||||
|
||||
// Label 节点名称
|
||||
Label string `json:"label"`
|
||||
|
||||
// Title 节点名称旧版本layui
|
||||
Title string `json:"title"`
|
||||
|
||||
// Children 子节点
|
||||
Children []TreeSelect `json:"children"`
|
||||
}
|
||||
|
||||
// // SysMenuTreeSelect 使用给定的 SysMenu 对象解析为 TreeSelect 对象
|
||||
// func SysMenuTreeSelect(sysMenu sysmenu.SysMenu) TreeSelect {
|
||||
// t := TreeSelect{}
|
||||
// t.ID = sysMenu.MenuID
|
||||
// t.Label = sysMenu.MenuName
|
||||
|
||||
// if len(sysMenu.Children) > 0 {
|
||||
// for _, menu := range sysMenu.Children {
|
||||
// child := SysMenuTreeSelect(menu)
|
||||
// t.Children = append(t.Children, child)
|
||||
// }
|
||||
// } else {
|
||||
// t.Children = []TreeSelect{}
|
||||
// }
|
||||
|
||||
// return t
|
||||
// }
|
||||
Reference in New Issue
Block a user