Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MELF晓宇
gin-start
提交
4faa7d45
G
gin-start
项目概览
MELF晓宇
/
gin-start
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gin-start
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
4faa7d45
编写于
4月 17, 2022
作者:
MELF晓宇
🤤
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
- 修改casbin执行者为异步
- 修复雪花id使用过程中重复问题 - 封装tmpl返回结果 - 添加aes相关实现
上级
6aaf0583
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
268 addition
and
33 deletion
+268
-33
config/conf.go
config/conf.go
+13
-2
global/conn.go
global/conn.go
+8
-6
global/constants.go
global/constants.go
+3
-5
global/model.go
global/model.go
+1
-20
menu/model/menu.go
menu/model/menu.go
+24
-0
utils/crypto/aes.go
utils/crypto/aes.go
+160
-0
utils/result/result.go
utils/result/result.go
+59
-0
未找到文件。
config/conf.go
浏览文件 @
4faa7d45
...
...
@@ -15,6 +15,8 @@ package conf
import
(
"context"
"database/sql"
"fmt"
"github.com/bwmarrin/snowflake"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
gormadapter
"github.com/casbin/gorm-adapter/v3"
...
...
@@ -147,7 +149,7 @@ func (i Init) Redis() *redis.Client {
* @Description: 初始化Casbin
* @receiver i
*/
func
(
i
Init
)
Casbin
()
(
Enforcer
*
casbin
.
Enforcer
)
{
func
(
i
Init
)
Casbin
()
(
Enforcer
*
casbin
.
Synced
Enforcer
)
{
// Gorm适配器
adapter
,
err
:=
gormadapter
.
NewAdapterByDB
(
global
.
DB
)
if
err
!=
nil
{
...
...
@@ -173,7 +175,7 @@ func (i Init) Casbin() (Enforcer *casbin.Enforcer) {
`
)
// 通过ORM新建一个执行者
Enforcer
,
err
=
casbin
.
NewEnforcer
(
m
,
adapter
)
Enforcer
,
err
=
casbin
.
New
Synced
Enforcer
(
m
,
adapter
)
if
err
!=
nil
{
panic
(
"新建Casbin执行者异常:"
+
err
.
Error
())
}
...
...
@@ -225,3 +227,12 @@ func (i Init) Validate() *validator.Validate {
v
:=
validator
.
New
()
return
v
}
func
(
i
Init
)
Node
()
*
snowflake
.
Node
{
nodeNum
:=
global
.
V
.
GetInt64
(
"Distributed.Node"
)
node
,
err
:=
snowflake
.
NewNode
(
nodeNum
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
return
node
}
global/conn.go
浏览文件 @
4faa7d45
...
...
@@ -13,6 +13,7 @@
package
global
import
(
"github.com/bwmarrin/snowflake"
"github.com/casbin/casbin/v2"
"github.com/go-playground/validator/v10"
"github.com/go-redis/redis/v8"
...
...
@@ -21,10 +22,11 @@ import (
)
var
(
E
*
Env
// 环境类型实例
V
*
viper
.
Viper
// Viper实例
Enforcer
*
casbin
.
Enforcer
// Casbin执行者
DB
*
gorm
.
DB
// 数据库连接池
RDB
*
redis
.
Client
// Redis连接池
Validate
*
validator
.
Validate
// Validate参数校验器
E
*
Env
// 环境类型实例
V
*
viper
.
Viper
// Viper实例
Enforcer
*
casbin
.
SyncedEnforcer
// Casbin执行者
DB
*
gorm
.
DB
// 数据库连接池
RDB
*
redis
.
Client
// Redis连接池
Validate
*
validator
.
Validate
// Validate参数校验器
Node
*
snowflake
.
Node
// 雪花ID节点
)
global/constants.go
浏览文件 @
4faa7d45
...
...
@@ -16,9 +16,7 @@ package global
type
Env
=
string
const
(
ENV_DEV
Env
=
"dev"
// 开发环境
ENV_PRO
Env
=
"pro"
// 生产环境
ENV_TEST
Env
=
"test"
// 测试环境
ENV_RET
Env
=
"ren"
// 回归环境
ENV_FAT
Env
=
"fat"
// 预发布环境
ENV_DEV
Env
=
"dev"
// 开发环境
ENV_PRO
Env
=
"pro"
// 生产环境
ENV_FAT
Env
=
"fat"
// 测试环境
)
global/model.go
浏览文件 @
4faa7d45
...
...
@@ -13,19 +13,11 @@
package
global
import
(
"fmt"
"github.com/bwmarrin/snowflake"
"sync"
"time"
"github.com/melf-xyzh/gin-start/utils/dtype"
)
var
(
// 定义一个锁
idLock
sync
.
Mutex
)
type
Model
struct
{
ID
dtype
.
DistributedId
`json:"id,omitempty" gorm:"column:id;primary_key;"`
CreateTime
dtype
.
Time
`json:"createTime,omitempty" gorm:"column:create_time;comment:创建时间;"`
...
...
@@ -38,18 +30,7 @@ type Model struct {
* @return DistributedId
*/
func
CreateId
()
dtype
.
DistributedId
{
idLock
.
Lock
()
defer
idLock
.
Unlock
()
// Create a new Node with a Node number of 1
// node, err := snowflake.NewNode(nodeNum)
// 为编号为nodeNum的节点生成一个节点
nodeNum
:=
V
.
GetInt64
(
"Distributed.Node"
)
node
,
err
:=
snowflake
.
NewNode
(
nodeNum
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
id
:=
node
.
Generate
()
id
:=
Node
.
Generate
()
return
dtype
.
DistributedId
(
id
.
Int64
())
}
...
...
menu/model/menu.go
0 → 100644
浏览文件 @
4faa7d45
/**
* @Time :2022/3/6 18:24
* @Author :MELF晓宇
* @Email :xyzh.melf@petalmail.com
* @FileName:menu.go
* @Project :gin-start
* @Blog :https://blog.csdn.net/qq_29537269
* @Guide :https://guide.melf.space
* @Information:
*
*/
package
model
import
"github.com/melf-xyzh/gin-start/global"
type
Menu
struct
{
global
.
Model
MenuName
string
Sort
uint
Url
string
RouterName
string
IsShow
int
}
utils/crypto/aes.go
0 → 100644
浏览文件 @
4faa7d45
/**
* @Time :2022/4/17 16:17
* @Author :MELF晓宇
* @Email :xyzh.melf@petalmail.com
* @FileName:aes.go
* @Project :gin-start
* @Blog :https://blog.csdn.net/qq_29537269
* @Guide :https://guide.melf.space
* @Information:
*
*/
package
crypto
import
(
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
"github.com/melf-xyzh/gin-start/global"
)
// 高级加密标准(Advanced Encryption Standard,AES)
type
AesCrypto
struct
{}
var
AES
=
new
(
AesCrypto
)
// EnPwdCode
/**
* @Description: 加密base64
* @param pwd
* @return string
* @return error
*/
func
(
aesCrypto
*
AesCrypto
)
EnPwdCode
(
pwd
[]
byte
)
(
string
,
error
)
{
aesPwd
:=
global
.
V
.
GetString
(
"AES.Password"
)
if
aesPwd
==
""
{
panic
(
"AES.Password未初始化"
)
}
// pwdKey 加密钥匙,16,24,32位字符串的话,分别对应AES-128,AES-192,AES-256 加密方法
pwdKey
:=
[]
byte
(
aesPwd
)
result
,
err
:=
aesEncrypt
(
pwd
,
pwdKey
)
if
err
!=
nil
{
return
""
,
err
}
return
base64
.
StdEncoding
.
EncodeToString
(
result
),
err
}
// DePwdCode
/**
* @Description: 解密
* @param pwd
* @return []byte
* @return error
*/
func
(
aesCrypto
*
AesCrypto
)
DePwdCode
(
pwd
string
)
([]
byte
,
error
)
{
aesPwd
:=
global
.
V
.
GetString
(
"AES.Password"
)
if
aesPwd
==
""
{
panic
(
"AES.Password未初始化"
)
}
// pwdKey 加密钥匙,16,24,32位字符串的话,分别对应AES-128,AES-192,AES-256 加密方法
pwdKey
:=
[]
byte
(
aesPwd
)
//解密base64字符串
pwdByte
,
err
:=
base64
.
StdEncoding
.
DecodeString
(
pwd
)
if
err
!=
nil
{
return
nil
,
err
}
//执行AES解密
return
aesDecrypt
(
pwdByte
,
pwdKey
)
}
// pkcs7Padding
/**
* @Description: PKCS7 填充模式
* @param ciphertext
* @param blockSize
* @return []byte
*/
func
pkcs7Padding
(
ciphertext
[]
byte
,
blockSize
int
)
[]
byte
{
padding
:=
blockSize
-
len
(
ciphertext
)
%
blockSize
// Repeat()函数的功能是把切片[]byte{byte(padding)}复制padding个,然后合并成新的字节切片返回
paddingText
:=
bytes
.
Repeat
([]
byte
{
byte
(
padding
)},
padding
)
return
append
(
ciphertext
,
paddingText
...
)
}
// PKCS7UnPadding
/**
* @Description:填充的反向操作,删除填充字符串
* @param origData
* @return []byte
* @return error
*/
func
pkcs7UnPadding
(
origData
[]
byte
)
([]
byte
,
error
)
{
//获取数据长度
length
:=
len
(
origData
)
if
length
==
0
{
return
nil
,
errors
.
New
(
"加密字符串错误!"
)
}
//获取填充字符串长度
unPadding
:=
int
(
origData
[
length
-
1
])
//截取切片,删除填充字节,并且返回明文
return
origData
[
:
(
length
-
unPadding
)],
nil
}
// aesEncrypt
/**
* @Description: 实现加密
* @param origData
* @param key
* @return []byte
* @return error
*/
func
aesEncrypt
(
origData
[]
byte
,
key
[]
byte
)
([]
byte
,
error
)
{
//创建加密算法实例
block
,
err
:=
aes
.
NewCipher
(
key
)
if
err
!=
nil
{
return
nil
,
err
}
//获取块的大小
blockSize
:=
block
.
BlockSize
()
//对数据进行填充,让数据长度满足需求
origData
=
pkcs7Padding
(
origData
,
blockSize
)
//采用AES加密方法中CBC加密模式
blocMode
:=
cipher
.
NewCBCEncrypter
(
block
,
key
[
:
blockSize
])
crypted
:=
make
([]
byte
,
len
(
origData
))
//执行加密
blocMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
// aesDecrypt
/**
* @Description: 实现解密
* @param cypted
* @param key
* @return []byte
* @return error
*/
func
aesDecrypt
(
cypted
[]
byte
,
key
[]
byte
)
([]
byte
,
error
)
{
//创建加密算法实例
block
,
err
:=
aes
.
NewCipher
(
key
)
if
err
!=
nil
{
return
nil
,
err
}
//获取块大小
blockSize
:=
block
.
BlockSize
()
//创建加密客户端实例
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
key
[
:
blockSize
])
origData
:=
make
([]
byte
,
len
(
cypted
))
//这个函数也可以用来解密
blockMode
.
CryptBlocks
(
origData
,
cypted
)
//去除填充字符串
origData
,
err
=
pkcs7UnPadding
(
origData
)
if
err
!=
nil
{
return
nil
,
err
}
return
origData
,
err
}
utils/result/result.go
浏览文件 @
4faa7d45
...
...
@@ -102,3 +102,62 @@ func File(c *gin.Context, fileName, filePath string) {
c
.
Header
(
"Content-Type"
,
"application/octet-stream"
)
c
.
File
(
filePath
)
}
// OkView
/**
* @Description: 返回成功界面
* @param c
* @param tmplPath tmpl文件路径
* @param title 网页标题
* @param msg
*/
func
OkView
(
c
*
gin
.
Context
,
tmplPath
,
title
,
msg
string
)
{
c
.
HTML
(
http
.
StatusOK
,
tmplPath
,
gin
.
H
{
"code"
:
CODE_SUCCESS
,
"title"
:
title
,
"msg"
:
msg
,
})
}
// FailView
/**
* @Description: 返回失败界面
* @param c
* @param tmplPath tmpl文件路径
* @param title 网页标题
* @param msg
*/
func
FailView
(
c
*
gin
.
Context
,
tmplPath
,
title
,
msg
string
)
{
c
.
HTML
(
http
.
StatusOK
,
tmplPath
,
gin
.
H
{
"code"
:
CODE_FAIL
,
"title"
:
title
,
"msg"
:
msg
,
})
}
// View
/**
* @Description: 返回界面
* @param c
* @param tmplPath
* @param title
*/
func
View
(
c
*
gin
.
Context
,
tmplPath
,
title
string
)
{
c
.
HTML
(
http
.
StatusOK
,
tmplPath
,
gin
.
H
{
"code"
:
CODE_FAIL
,
"title"
:
title
,
})
}
// DataView
/**
* @Description: 返回数据界面
* @param c
* @param tmplPath
* @param title
* @param data
*/
func
DataView
(
c
*
gin
.
Context
,
tmplPath
,
title
string
,
data
map
[
string
]
interface
{})
{
data
[
"title"
]
=
title
c
.
HTML
(
http
.
StatusOK
,
tmplPath
,
data
)
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录