后端重构

This commit is contained in:
Yvan
2026-01-08 20:16:27 +08:00
parent 9cb6b965e0
commit f5f77b32fe
23 changed files with 1450 additions and 2 deletions
+143
View File
@@ -0,0 +1,143 @@
package utils
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"log"
)
// AddImport 增加 import 方法
func AddImport(astNode ast.Node, imp string) {
impStr := fmt.Sprintf("\"%s\"", imp)
ast.Inspect(astNode, func(node ast.Node) bool {
if genDecl, ok := node.(*ast.GenDecl); ok {
if genDecl.Tok == token.IMPORT {
for i := range genDecl.Specs {
if impNode, ok := genDecl.Specs[i].(*ast.ImportSpec); ok {
if impNode.Path.Value == impStr {
return false
}
}
}
genDecl.Specs = append(genDecl.Specs, &ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: impStr,
},
})
}
}
return true
})
}
// FindFunction 查询特定function方法
func FindFunction(astNode ast.Node, FunctionName string) *ast.FuncDecl {
var funcDeclP *ast.FuncDecl
ast.Inspect(astNode, func(node ast.Node) bool {
if funcDecl, ok := node.(*ast.FuncDecl); ok {
if funcDecl.Name.String() == FunctionName {
funcDeclP = funcDecl
return false
}
}
return true
})
return funcDeclP
}
// FindArray 查询特定数组方法
func FindArray(astNode ast.Node, identName, selectorExprName string) *ast.CompositeLit {
var assignStmt *ast.CompositeLit
ast.Inspect(astNode, func(n ast.Node) bool {
switch node := n.(type) {
case *ast.AssignStmt:
for _, expr := range node.Rhs {
if exprType, ok := expr.(*ast.CompositeLit); ok {
if arrayType, ok := exprType.Type.(*ast.ArrayType); ok {
sel, ok1 := arrayType.Elt.(*ast.SelectorExpr)
x, ok2 := sel.X.(*ast.Ident)
if ok1 && ok2 && x.Name == identName && sel.Sel.Name == selectorExprName {
assignStmt = exprType
return false
}
}
}
}
}
return true
})
return assignStmt
}
// CheckImport 检查是否存在Import
func CheckImport(file *ast.File, importPath string) bool {
for _, imp := range file.Imports {
// Remove quotes around the import path
path := imp.Path.Value[1 : len(imp.Path.Value)-1]
if path == importPath {
return true
}
}
return false
}
// clearPosition 清除AST节点位置信息
func clearPosition(astNode ast.Node) {
ast.Inspect(astNode, func(n ast.Node) bool {
switch node := n.(type) {
case *ast.Ident:
node.NamePos = token.NoPos
case *ast.CallExpr:
node.Lparen = token.NoPos
node.Rparen = token.NoPos
case *ast.BasicLit:
node.ValuePos = token.NoPos
case *ast.SelectorExpr:
node.Sel.NamePos = token.NoPos
case *ast.BinaryExpr:
node.OpPos = token.NoPos
case *ast.UnaryExpr:
node.OpPos = token.NoPos
case *ast.StarExpr:
node.Star = token.NoPos
}
return true
})
}
// CreateStmt 创建语句
func CreateStmt(statement string) *ast.ExprStmt {
expr, err := parser.ParseExpr(statement)
if err != nil {
log.Fatal(err)
}
clearPosition(expr)
return &ast.ExprStmt{X: expr}
}
// IsBlockStmt 判断是否为块语句
func IsBlockStmt(node ast.Node) bool {
_, ok := node.(*ast.BlockStmt)
return ok
}
// VariableExistsInBlock 检查变量是否存在于块中
func VariableExistsInBlock(block *ast.BlockStmt, varName string) bool {
exists := false
ast.Inspect(block, func(n ast.Node) bool {
switch node := n.(type) {
case *ast.AssignStmt:
for _, expr := range node.Lhs {
if ident, ok := expr.(*ast.Ident); ok && ident.Name == varName {
exists = true
return false
}
}
}
return true
})
return exists
}
+105
View File
@@ -0,0 +1,105 @@
package utils
import (
"errors"
"os"
"path/filepath"
"reflect"
"strings"
)
// PathExists 文件目录是否存在
func PathExists(path string) (bool, error) {
fi, err := os.Stat(path)
if err == nil {
if fi.IsDir() {
return true, nil
}
return false, errors.New("存在同名文件")
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// CreateDir 批量创建文件夹
func CreateDir(dirs ...string) error {
for _, v := range dirs {
exist, err := PathExists(v)
if err != nil {
return err
}
if !exist {
if err := os.MkdirAll(v, os.ModePerm); err != nil {
return err
}
}
}
return nil
}
// FileMove 文件移动
// src: 源位置,绝对路径或相对路径
// dst: 目标位置,绝对路径或相对路径,必须为文件夹
func FileMove(src string, dst string) error {
if dst == "" {
return nil
}
var err error
src, err = filepath.Abs(src)
if err != nil {
return err
}
dst, err = filepath.Abs(dst)
if err != nil {
return err
}
dir := filepath.Dir(dst)
if _, err = os.Stat(dir); err != nil {
if err = os.MkdirAll(dir, 0o755); err != nil {
return err
}
}
return os.Rename(src, dst)
}
// DeLFile 删除文件或目录
func DeLFile(filePath string) error {
return os.RemoveAll(filePath)
}
// TrimSpace 去除结构体字符串字段的空格
// target: 目标结构体,传入必须是指针类型
func TrimSpace(target interface{}) {
t := reflect.TypeOf(target)
if t.Kind() != reflect.Ptr {
return
}
t = t.Elem()
v := reflect.ValueOf(target).Elem()
for i := 0; i < t.NumField(); i++ {
if v.Field(i).Kind() == reflect.String {
v.Field(i).SetString(strings.TrimSpace(v.Field(i).String()))
}
}
}
// FileExist 判断文件是否存在
func FileExist(path string) bool {
fi, err := os.Lstat(path)
if err == nil {
return !fi.IsDir()
}
return !os.IsNotExist(err)
}
// DirExist 判断目录是否存在
func DirExist(path string) bool {
fi, err := os.Stat(path)
if err == nil {
return fi.IsDir()
}
return false
}
+48
View File
@@ -0,0 +1,48 @@
package utils
import (
"encoding/json"
"strings"
)
// GetJSONKeys 获取JSON对象的所有键(保持顺序)
func GetJSONKeys(jsonStr string) (keys []string, err error) {
dec := json.NewDecoder(strings.NewReader(jsonStr))
t, err := dec.Token()
if err != nil {
return nil, err
}
// 确保数据是一个对象
if t != json.Delim('{') {
return nil, err
}
for dec.More() {
t, err = dec.Token()
if err != nil {
return nil, err
}
keys = append(keys, t.(string))
// 解析值
var value interface{}
err = dec.Decode(&value)
if err != nil {
return nil, err
}
}
return keys, nil
}
// ToJSON 将对象转换为JSON字符串
func ToJSON(v interface{}) string {
b, err := json.Marshal(v)
if err != nil {
return ""
}
return string(b)
}
// FromJSON 将JSON字符串解析为对象
func FromJSON(jsonStr string, v interface{}) error {
return json.Unmarshal([]byte(jsonStr), v)
}
+78
View File
@@ -0,0 +1,78 @@
package utils
// 预定义验证规则
var (
IdVerify = Rules{"ID": []string{NotEmpty()}}
ApiVerify = Rules{"Path": {NotEmpty()}, "Description": {NotEmpty()}, "ApiGroup": {NotEmpty()}, "Method": {NotEmpty()}}
MenuVerify = Rules{"Path": {NotEmpty()}, "Name": {NotEmpty()}, "Component": {NotEmpty()}, "Sort": {Ge("0")}}
MenuMetaVerify = Rules{"Title": {NotEmpty()}}
LoginVerify = Rules{"Username": {NotEmpty()}, "Password": {NotEmpty()}}
RegisterVerify = Rules{"Username": {NotEmpty()}, "NickName": {NotEmpty()}, "Password": {NotEmpty()}, "AuthorityId": {NotEmpty()}}
PageInfoVerify = Rules{"Page": {NotEmpty()}, "PageSize": {NotEmpty()}}
CustomerVerify = Rules{"CustomerName": {NotEmpty()}, "CustomerPhoneData": {NotEmpty()}}
AutoCodeVerify = Rules{"Abbreviation": {NotEmpty()}, "StructName": {NotEmpty()}, "PackageName": {NotEmpty()}}
AutoPackageVerify = Rules{"PackageName": {NotEmpty()}}
AuthorityVerify = Rules{"AuthorityId": {NotEmpty()}, "AuthorityName": {NotEmpty()}}
AuthorityIdVerify = Rules{"AuthorityId": {NotEmpty()}}
OldAuthorityVerify = Rules{"OldAuthorityId": {NotEmpty()}}
ChangePasswordVerify = Rules{"Password": {NotEmpty()}, "NewPassword": {NotEmpty()}}
SetUserAuthorityVerify = Rules{"AuthorityId": {NotEmpty()}}
)
// Rules 验证规则类型
type Rules map[string][]string
// NotEmpty 非空验证
func NotEmpty() string {
return "notEmpty"
}
// Ge 大于等于验证
func Ge(value string) string {
return "ge=" + value
}
// Le 小于等于验证
func Le(value string) string {
return "le=" + value
}
// Gt 大于验证
func Gt(value string) string {
return "gt=" + value
}
// Lt 小于验证
func Lt(value string) string {
return "lt=" + value
}
// Eq 等于验证
func Eq(value string) string {
return "eq=" + value
}
// Ne 不等于验证
func Ne(value string) string {
return "ne=" + value
}
// Len 长度验证
func Len(value string) string {
return "len=" + value
}
// MinLen 最小长度验证
func MinLen(value string) string {
return "minLen=" + value
}
// MaxLen 最大长度验证
func MaxLen(value string) string {
return "maxLen=" + value
}
// Regexp 正则验证
func Regexp(value string) string {
return "regexp=" + value
}