@@ -0,0 +1,46 @@ | |||
# Binaries for programs and plugins | |||
*.exe | |||
*.exe~ | |||
*.dll | |||
*.so | |||
*.dylib | |||
# Test binary, built with `go test -c` | |||
*.test | |||
# Output of the go coverage tool, specifically when used with LiteIDE | |||
*.out | |||
.idea | |||
.vscode | |||
*.log | |||
.DS_Store | |||
Thumbs.db | |||
*.swp | |||
*.swn | |||
*.swo | |||
*.swm | |||
*.7z | |||
*.zip | |||
*.rar | |||
*.tar | |||
*.tar.gz | |||
go.sum | |||
/etc/cfg.yaml | |||
images | |||
test/test.json | |||
etc/cfg.yml | |||
t.json | |||
t1.json | |||
t2.json | |||
t3.json | |||
t.go | |||
wait-for-it.sh | |||
test.go | |||
xorm | |||
test.csv | |||
nginx.conf | |||
.devcontainer | |||
.devcontainer/Dockerfile | |||
.devcontainer/sources.list | |||
/t1.go | |||
/tmp/* | |||
.idea/* | |||
/.idea/modules.xml |
@@ -0,0 +1,45 @@ | |||
# 蛋蛋星球 mysql 模型库 | |||
## 项目概述 | |||
集成蛋蛋星球项目所用到的所有数据库、表,并提供类ORM操作类。 | |||
------------- | |||
## 项目结构 | |||
如下: | |||
1. **文档** | |||
- `README.md` - 项目的入口点和概述。 | |||
- `LICENSE` - 项目的许可证。 | |||
2. **源代码** | |||
- `src` - 主代码目录。 | |||
- `dao` - dao包(接口类)。 | |||
- `models` - mysql表模型。 | |||
- `implement` - 实现包(实现所有接口)。 | |||
3. **测试用例** | |||
- `****_test.go` - 测试对应orm类功能。 | |||
- `md` - 测试用例所需结构体 | |||
- `tmp` - 运行临时日志 | |||
4. **工具类** | |||
- `logx` - 日志输出用到。 | |||
- `*****.go` - 其他常用工具函数。 | |||
5. **配置文件** | |||
- `etc` | |||
- `db_tpl` - 数据库模板文件 | |||
- `cfg.yml` - 配置文件。 | |||
6. **脚手架脚本** | |||
- `cmd_db.bat` - 作用于 windows 系统自动生成models目录下的模型 | |||
- `cmd_db.sh` - 作用于 linux 系统自动生成models目录下的模型 | |||
## 安装和运行 | |||
确保安装了所需的依赖,然后运行以下命令: | |||
```bash | |||
.\cmd_db.bat hello_world ---> 自动生成模型类 | |||
.\cmd_dao.bat hello_world ---> 自动生成接口类 | |||
.\cmd_implement.bat hello_world ---> 自动生成实现类 |
@@ -0,0 +1,23 @@ | |||
@echo off | |||
setlocal | |||
set "BasePath=./" | |||
REM 假设已经提供了文件名作为参数 | |||
set "FileName=%~1" | |||
REM 将参数设置最终文件名 | |||
set "FinalFile=%BasePath%src\dao\%FileName%_dao.go" | |||
REM 将文件名转换成大驼峰格式并设置成最终接口名 | |||
for /f "delims=" %%i in ('powershell -File "%BasePath%etc\ps\ConvertToUpperCase.ps1" -inputString "%FileName%"') do set "InterfaceName=%%i" | |||
REM 使用 PowerShell 替换接口名称,并指定 UTF-8 编码 | |||
powershell -Command "(Get-Content '%BasePath%etc\template\template_interface.tpl') -replace 'DemoInterface', '%InterfaceName%' | Out-File -FilePath '%BasePath%temp_interface.go' -Encoding UTF8" | |||
REM 如果需要,将临时文件重命名为最终文件(取决于move Y?N) | |||
move /Y "%BasePath%temp_interface.go" "%FinalFile%" | |||
echo Interface file %FileName%_dao.go generated successfully. | |||
endlocal |
@@ -0,0 +1,25 @@ | |||
@echo off | |||
set Table=* | |||
set TName="" | |||
set one=%1 | |||
if "%one%" NEQ "" ( | |||
set Table=%one% | |||
set TName="^%one%$" | |||
) | |||
set BasePath="./" | |||
set DBUSER="root" | |||
set DBPSW="Fnuo123com@" | |||
set DBNAME="egg" | |||
set DBHOST="119.23.182.117" | |||
set DBPORT="3306" | |||
del "src\model\%Table%.go" | |||
echo start reverse table %Table% | |||
xorm reverse mysql "%DBUSER%:%DBPSW%@tcp(%DBHOST%:%DBPORT%)/%DBNAME%?charset=utf8" %BasePath%/etc/db_tpl %BasePath%/src/model/ %TName% | |||
echo end |
@@ -0,0 +1,21 @@ | |||
#!/bin/bash | |||
# 使用方法, 直接执行该脚本更新所有表, cmd_db.sh 表名, 如 ./cmd_db.sh tableName | |||
Table=* | |||
TName="" | |||
if [ "$1" ] ;then | |||
Table=$1 | |||
TName="^$1$" | |||
fi | |||
BasePath="./" | |||
DBUSER="root" | |||
DBPSW="Fnuo123com@" | |||
DBNAME="egg" | |||
DBHOST="119.23.182.117" | |||
DBPORT="3306" | |||
rm -rf $BasePath/app/db/model/$Table.go && \ | |||
xorm reverse mysql "$DBUSER:$DBPSW@tcp($DBHOST:$DBPORT)/$DBNAME?charset=utf8" $BasePath/etc/db_tpl $BasePath/src/models/ $TName |
@@ -0,0 +1,23 @@ | |||
@echo off | |||
setlocal | |||
set "BasePath=./" | |||
REM 假设已经提供了文件名作为参数 | |||
set "FileName=%~1" | |||
REM 将参数设置最终文件名 | |||
set "FinalFile=%BasePath%src\implement\%FileName%_implement.go" | |||
REM 将文件名转换成大驼峰格式并设置成最终实现类名 | |||
for /f "delims=" %%i in ('powershell -File "%BasePath%etc\ps\ConvertToUpperCase.ps1" -inputString "%FileName%"') do set "ImplementName=%%i" | |||
REM 使用 PowerShell 替换接口名称,并指定 UTF-8 编码 | |||
powershell -Command "(Get-Content '%BasePath%etc\template\template_implement.tpl') -replace 'DemoImplement', '%ImplementName%' | Out-File -FilePath '%BasePath%temp_implement.go' -Encoding UTF8" | |||
REM 如果需要,将临时文件重命名为最终文件(取决于move Y?N) | |||
move /Y "%BasePath%temp_implement.go" "%FinalFile%" | |||
echo Implement file %FileName%_dao.go generated successfully. | |||
endlocal |
@@ -0,0 +1,19 @@ | |||
package enum | |||
type PermissionGroupState int32 | |||
const ( | |||
PermissionGroupStateForNormal = 1 | |||
PermissionGroupStateForDiscard = 2 | |||
) | |||
func (gt PermissionGroupState) String() string { | |||
switch gt { | |||
case PermissionGroupStateForNormal: | |||
return "正常" | |||
case PermissionGroupStateForDiscard: | |||
return "废弃" | |||
default: | |||
return "未知" | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
lang=go | |||
genJson=1 | |||
prefix=cos_ | |||
ignoreColumnsJSON= | |||
created= | |||
updated= | |||
deleted= |
@@ -0,0 +1,17 @@ | |||
package {{.Models}} | |||
{{$ilen := len .Imports}} | |||
{{if gt $ilen 0}} | |||
import ( | |||
{{range .Imports}}"{{.}}"{{end}} | |||
) | |||
{{end}} | |||
{{range .Tables}} | |||
type {{Mapper .Name}} struct { | |||
{{$table := .}} | |||
{{range .ColumnsSeq}}{{$col := $table.GetColumn .}} {{Mapper $col.Name}} {{Type $col}} {{Tag $table $col}} | |||
{{end}} | |||
} | |||
{{end}} | |||
@@ -0,0 +1,9 @@ | |||
param($inputString) | |||
$words = $inputString.Split('_') | |||
$outputString = "" | |||
foreach ($word in $words) { | |||
$outputString += $word.Substring(0,1).ToUpper() + $word.Substring(1).ToLower() + "" | |||
} | |||
$outputString = $outputString.TrimEnd() | |||
$outputString -replace ' ', '' # 如果想要没有空格的字符串,取消注释这行代码 | |||
$outputString |
@@ -0,0 +1,14 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"xorm.io/xorm" | |||
) | |||
func NewDemoImplementDb(engine *xorm.Engine) dao.DemoImplementDao { | |||
return &DemoImplementDb{Db: engine} | |||
} | |||
type DemoImplementDb struct { | |||
Db *xorm.Engine | |||
} |
@@ -0,0 +1,5 @@ | |||
package dao | |||
type DemoInterfaceDao interface { | |||
//TODO:: You can add specific method definitions here | |||
} |
@@ -0,0 +1,14 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/super/dao" | |||
"xorm.io/xorm" | |||
) | |||
func NewDemoImplementDb(engine *xorm.Engine) dao.DemoImplementDao { | |||
return &DemoImplementDb{Db: engine} | |||
} | |||
type DemoImplementDb struct { | |||
Db *xorm.Engine | |||
} |
@@ -0,0 +1,32 @@ | |||
module code.fnuoos.com/zhimeng/model.git | |||
go 1.19 | |||
require ( | |||
github.com/go-sql-driver/mysql v1.8.1 | |||
github.com/syyongx/php2go v0.9.8 | |||
go.uber.org/zap v1.13.0 | |||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 | |||
gopkg.in/yaml.v3 v3.0.1 | |||
xorm.io/xorm v1.3.1 | |||
) | |||
require ( | |||
filippo.io/edwards25519 v1.1.0 // indirect | |||
github.com/goccy/go-json v0.10.2 // indirect | |||
github.com/golang/snappy v0.0.4 // indirect | |||
github.com/jinzhu/copier v0.4.0 // indirect | |||
github.com/json-iterator/go v1.1.12 // indirect | |||
github.com/mattn/go-isatty v0.0.19 // indirect | |||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | |||
github.com/modern-go/reflect2 v1.0.2 // indirect | |||
github.com/stretchr/testify v1.8.3 // indirect | |||
github.com/syndtr/goleveldb v1.0.0 // indirect | |||
go.uber.org/atomic v1.6.0 // indirect | |||
go.uber.org/multierr v1.5.0 // indirect | |||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect | |||
golang.org/x/net v0.10.0 // indirect | |||
golang.org/x/sys v0.8.0 // indirect | |||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 // indirect | |||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect | |||
) |
@@ -0,0 +1,9 @@ | |||
package dao | |||
import "code.fnuoos.com/zhimeng/model.git/src/model" | |||
type AdminBindMediumDao interface { | |||
FindAll(adminId int) (list []model.AdminBindMedium) | |||
FindMediumList(mediumId string, adminId, page, limit int) (list []model.AdminBindMedium, total int64, err error) | |||
GetAdminByMediumId(adminId, mediumId int) (list *model.AdminBindMedium) | |||
} |
@@ -0,0 +1,45 @@ | |||
package dao | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
"xorm.io/xorm" | |||
) | |||
type AdminDao interface { | |||
CreateAdminId() (admId int, err error) | |||
AdminDeleteBySession(session *xorm.Session, admId interface{}) (int64, error) | |||
GetAdmin(id int) (m *model.Admin, err error) | |||
GetSuperAdmin() (m *model.Admin, err error) | |||
GetAdminByUserName(userName string) (m *model.Admin, err error) | |||
GetAdminRolePermission(admId int) (list []*AdminRolePermission, total int64, err error) | |||
FindAdmin(username string, state, page, limit int) (list []model.Admin, total int64, err error) | |||
UpdateAdmin(m *model.Admin, columns ...string) (int64, error) | |||
AdminInsert(m *model.Admin) (int64, error) | |||
FindAdminRolePermissionGroup(admId int) (list []*AdminRolePermissionGroup, total int64, err error) | |||
} | |||
type AdminRolePermissionGroup struct { | |||
model.Admin `xorm:"extends"` | |||
model.AdminRole `xorm:"extends"` | |||
model.Role `xorm:"extends"` | |||
model.RolePermissionGroup `xorm:"extends"` | |||
model.PermissionGroup `xorm:"extends"` | |||
} | |||
func (AdminRolePermissionGroup) TableName() string { | |||
return "admin" | |||
} | |||
type AdminRolePermission struct { | |||
model.Admin `xorm:"extends"` | |||
model.AdminRole `xorm:"extends"` | |||
model.Role `xorm:"extends"` | |||
model.RolePermissionGroup `xorm:"extends"` | |||
model.PermissionGroup `xorm:"extends"` | |||
model.PermissionGroupPermission `xorm:"extends"` | |||
model.Permission `xorm:"extends"` | |||
} | |||
func (AdminRolePermission) TableName() string { | |||
return "admin" | |||
} |
@@ -0,0 +1,26 @@ | |||
package dao | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
"xorm.io/xorm" | |||
) | |||
type AdminRoleDao interface { | |||
FindAdminRole(id int) (*[]model.AdminRole, error) | |||
FindAdminRoleByRoleId(id int) (*[]model.AdminRole, error) | |||
AdminDeleteBySessionForAdmId(session *xorm.Session, admId interface{}) (int64, error) | |||
GetAdminRoleByRole(id int) (m *model.AdminRole, err error) | |||
GetAdminRoleByAdminId(id int) (m *model.AdminRole, err error) | |||
AdminRoleDeleteForRoleBySession(session *xorm.Session, roleId interface{}) (int64, error) | |||
AdminRoleDeleteBySession(session *xorm.Session, id interface{}) (int64, error) | |||
BatchAddAdminRoleBySession(session *xorm.Session, mm []*model.AdminRole) (int64, error) | |||
} | |||
type AdminRole struct { | |||
model.Admin `xorm:"extends"` | |||
model.AdminRole `xorm:"extends"` | |||
} | |||
func (AdminRole) TableName() string { | |||
return "admin_role" | |||
} |
@@ -0,0 +1,5 @@ | |||
package dao | |||
type PermissionDao interface { | |||
//TODO:: You can add specific method definitions here | |||
} |
@@ -0,0 +1,8 @@ | |||
package dao | |||
import "code.fnuoos.com/zhimeng/model.git/src/model" | |||
type PermissionGroupDao interface { | |||
FindPermissionGroup() (*[]model.PermissionGroup, error) | |||
FindPermissionGroupV2() (*[]model.PermissionGroup, error) | |||
} |
@@ -0,0 +1,5 @@ | |||
package dao | |||
type PermissionGroupPermissionDao interface { | |||
//TODO:: You can add specific method definitions here | |||
} |
@@ -0,0 +1,25 @@ | |||
package dao | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
"xorm.io/xorm" | |||
) | |||
type RoleDao interface { | |||
FindRole() (*[]model.Role, error) | |||
GetRole() (m *model.Role, err error) | |||
UpdateRole(m *model.Role, columns ...string) (int64, error) | |||
RoleDeleteBySession(session *xorm.Session, id interface{}) (int64, error) | |||
RoleInsert(m *model.Role) (int, error) | |||
FindPermissionGroupByRole(roleId int) (list []*RolePermissionGroup, total int64, err error) | |||
} | |||
type RolePermissionGroup struct { | |||
model.Role `xorm:"extends"` | |||
model.RolePermissionGroup `xorm:"extends"` | |||
model.PermissionGroup `xorm:"extends"` | |||
} | |||
func (RolePermissionGroup) TableName() string { | |||
return "role" | |||
} |
@@ -0,0 +1,11 @@ | |||
package dao | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
"xorm.io/xorm" | |||
) | |||
type RolePermissionGroupDao interface { | |||
RolePermissionGroupDeleteForRoleBySession(session *xorm.Session, roleId interface{}) (int64, error) | |||
BatchAddRolePermissionGroupBySession(session *xorm.Session, mm []*model.RolePermissionGroup) (int64, error) | |||
} |
@@ -0,0 +1,113 @@ | |||
package db | |||
import ( | |||
"database/sql" | |||
"fmt" | |||
"os" | |||
"time" | |||
_ "github.com/go-sql-driver/mysql" //必须导入mysql驱动,否则会panic | |||
"xorm.io/xorm" | |||
"xorm.io/xorm/log" | |||
"applet/app/cfg" | |||
"applet/app/utils/logx" | |||
) | |||
var Db *xorm.Engine | |||
// 根据DB配置文件初始化数据库 | |||
func InitDB(c *cfg.DBCfg) error { | |||
fmt.Println("db host::::", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4", c.User, c.Psw, c.Host, c.Name)) | |||
var ( | |||
err error | |||
f *os.File | |||
) | |||
//创建Orm引擎 | |||
if Db, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4", c.User, c.Psw, c.Host, c.Name)); err != nil { | |||
return err | |||
} | |||
Db.SetConnMaxLifetime(c.MaxLifetime * time.Second) //设置最长连接时间 | |||
Db.SetMaxOpenConns(c.MaxOpenConns) //设置最大打开连接数 | |||
Db.SetMaxIdleConns(c.MaxIdleConns) //设置连接池的空闲数大小 | |||
if err = Db.Ping(); err != nil { //尝试ping数据库 | |||
return err | |||
} | |||
if c.ShowLog { //根据配置文件设置日志 | |||
Db.ShowSQL(true) //设置是否打印sql | |||
Db.Logger().SetLevel(0) //设置日志等级 | |||
//修改日志文件存放路径文件名是%s.log | |||
path := fmt.Sprintf(c.Path, c.Name) | |||
f, err = os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0777) | |||
if err != nil { | |||
os.RemoveAll(c.Path) | |||
if f, err = os.OpenFile(c.Path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0777); err != nil { | |||
return err | |||
} | |||
} | |||
logger := log.NewSimpleLogger(f) | |||
logger.ShowSQL(true) | |||
Db.SetLogger(logger) | |||
} | |||
return nil | |||
} | |||
/********************************************* 公用方法 *********************************************/ | |||
// 数据批量插入 | |||
func DbInsertBatch(Db *xorm.Engine, m ...interface{}) error { | |||
if len(m) == 0 { | |||
return nil | |||
} | |||
id, err := Db.Insert(m...) | |||
if id == 0 || err != nil { | |||
return logx.Warn("cannot insert data :", err) | |||
} | |||
return nil | |||
} | |||
// QueryNativeString 查询原生sql | |||
func QueryNativeString(Db *xorm.Engine, sql string, args ...interface{}) ([]map[string]string, error) { | |||
results, err := Db.SQL(sql, args...).QueryString() | |||
return results, err | |||
} | |||
// UpdateComm common update | |||
func UpdateComm(Db *xorm.Engine, id interface{}, model interface{}) (int64, error) { | |||
row, err := Db.ID(id).Update(model) | |||
return row, err | |||
} | |||
// InsertComm common insert | |||
func InsertComm(Db *xorm.Engine, model interface{}) (int64, error) { | |||
row, err := Db.InsertOne(model) | |||
return row, err | |||
} | |||
// ExecuteOriginalSql 执行原生sql | |||
func ExecuteOriginalSql(session *xorm.Session, sql string) (sql.Result, error) { | |||
result, err := session.Exec(sql) | |||
if err != nil { | |||
_ = logx.Warn(err) | |||
return nil, err | |||
} | |||
return result, nil | |||
} | |||
// GetComm | |||
// payload *model | |||
// return *model,has,err | |||
func GetComm(Db *xorm.Engine, model interface{}) (interface{}, bool, error) { | |||
has, err := Db.Get(model) | |||
if err != nil { | |||
_ = logx.Warn(err) | |||
return nil, false, err | |||
} | |||
return model, has, nil | |||
} | |||
// InsertCommWithSession common insert | |||
func InsertCommWithSession(session *xorm.Session, model interface{}) (int64, error) { | |||
row, err := session.InsertOne(model) | |||
return row, err | |||
} |
@@ -0,0 +1,44 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
"strings" | |||
"xorm.io/xorm" | |||
) | |||
func NewAdminBindMediumDb(engine *xorm.Engine) dao.AdminBindMediumDao { | |||
return &AdminBindMediumDb{Db: engine} | |||
} | |||
type AdminBindMediumDb struct { | |||
Db *xorm.Engine | |||
} | |||
func (a AdminBindMediumDb) FindAll(adminId int) (list []model.AdminBindMedium) { | |||
sess := a.Db.Where("admin_id=?", adminId) | |||
err := sess.Find(&list) | |||
if err != nil { | |||
return nil | |||
} | |||
return | |||
} | |||
func (a AdminBindMediumDb) GetAdminByMediumId(adminId, mediumId int) (list *model.AdminBindMedium) { | |||
sess := a.Db.Where("medium_id=? and admin_id=?", mediumId, adminId) | |||
get, err := sess.Get(&list) | |||
if get == false || err != nil { | |||
return nil | |||
} | |||
return | |||
} | |||
func (a AdminBindMediumDb) FindMediumList(mediumId string, adminId, page, limit int) (list []model.AdminBindMedium, total int64, err error) { | |||
sess := a.Db.Where("admin_id=?", adminId).Desc("id").Limit(limit, (page-1)*limit) | |||
if mediumId != "" { | |||
sess.In("medium_id", strings.Split(mediumId, ",")) | |||
} | |||
total, err = sess.FindAndCount(&list) | |||
if err != nil { | |||
return nil, 0, err | |||
} | |||
return | |||
} |
@@ -0,0 +1,126 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
zhios_order_relate_logx "code.fnuoos.com/zhimeng/model.git/utils/logx" | |||
"reflect" | |||
"xorm.io/xorm" | |||
) | |||
func NewAdminDb(engine *xorm.Engine) dao.AdminDao { | |||
return &AdminDb{Db: engine} | |||
} | |||
type AdminDb struct { | |||
Db *xorm.Engine | |||
} | |||
func (a AdminDb) CreateAdminId() (admId int, err error) { | |||
m := new(model.Admin) | |||
has, err := a.Db.Desc("adm_id").Get(m) | |||
if err != nil { | |||
return 0, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return 0, nil | |||
} | |||
admId = m.AdmId + 1 | |||
return admId, nil | |||
} | |||
func (a AdminDb) AdminDeleteBySession(session *xorm.Session, admId interface{}) (int64, error) { | |||
if reflect.TypeOf(admId).Kind() == reflect.Slice { | |||
return session.In("adm_id", admId).Delete(model.Admin{}) | |||
} else { | |||
return session.Where("adm_id = ?", admId).Delete(model.Admin{}) | |||
} | |||
} | |||
func (a AdminDb) GetAdmin(id int) (m *model.Admin, err error) { | |||
m = new(model.Admin) | |||
has, err := a.Db.Where("adm_id =?", id).Get(m) | |||
if err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return nil, nil | |||
} | |||
return m, nil | |||
} | |||
func (a AdminDb) GetSuperAdmin() (m *model.Admin, err error) { | |||
m = new(model.Admin) | |||
has, err := a.Db.Where("is_super_administrator =?", 1).Get(m) | |||
if err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return nil, nil | |||
} | |||
return m, nil | |||
} | |||
func (a AdminDb) GetAdminByUserName(userName string) (m *model.Admin, err error) { | |||
m = new(model.Admin) | |||
has, err := a.Db.Where("username =?", userName).Get(m) | |||
if err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return nil, nil | |||
} | |||
return m, nil | |||
} | |||
func (a AdminDb) GetAdminRolePermission(admId int) (list []*dao.AdminRolePermission, total int64, err error) { | |||
total, err = a.Db.Where("admin.adm_id =?", admId). | |||
Join("LEFT", "admin_role", "admin.adm_id = admin_role.adm_id"). | |||
Join("LEFT", "role", "admin_role.role_id = role.id"). | |||
Join("LEFT", "role_permission_group", "role.id = role_permission_group.role_id"). | |||
Join("LEFT", "permission_group", "role_permission_group.group_id = permission_group.id"). | |||
Join("LEFT", "permission_group_permission", "permission_group.id = permission_group_permission.group_id"). | |||
Join("LEFT", "permission", "permission_group_permission.permission_id = permission.id"). | |||
FindAndCount(&list) | |||
return | |||
} | |||
func (a AdminDb) FindAdmin(username string, state, page, limit int) (list []model.Admin, total int64, err error) { | |||
sess := a.Db.Desc("adm_id").Limit(limit, (page-1)*limit) | |||
if username != "" { | |||
sess.And("username like ?", "%"+username+"%") | |||
} | |||
if state != 0 { | |||
sess.And("state = ?", state) | |||
} | |||
total, err = sess.FindAndCount(&list) | |||
if err != nil { | |||
return nil, 0, err | |||
} | |||
return | |||
} | |||
func (a AdminDb) UpdateAdmin(m *model.Admin, columns ...string) (int64, error) { | |||
affected, err := a.Db.Where("adm_id =?", m.AdmId).Cols(columns...).Update(m) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return affected, nil | |||
} | |||
func (a AdminDb) AdminInsert(m *model.Admin) (int64, error) { | |||
insertAffected, err := a.Db.InsertOne(m) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return insertAffected, nil | |||
} | |||
func (a AdminDb) FindAdminRolePermissionGroup(admId int) (list []*dao.AdminRolePermissionGroup, total int64, err error) { | |||
total, err = a.Db.Where("admin.adm_id =?", admId). | |||
Join("LEFT", "admin_role", "admin.adm_id = admin_role.adm_id"). | |||
Join("LEFT", "role", "admin_role.role_id = role.id"). | |||
//Join("LEFT", "role_permission_group", "role.id = role_permission_group.role_id"). | |||
//Join("LEFT", "permission_group", "role_permission_group.group_id = permission_group.id"). | |||
FindAndCount(&list) | |||
return | |||
} |
@@ -0,0 +1,88 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
zhios_order_relate_logx "code.fnuoos.com/zhimeng/model.git/utils/logx" | |||
"reflect" | |||
"xorm.io/xorm" | |||
) | |||
func NewAdminRoleDb(engine *xorm.Engine) dao.AdminRoleDao { | |||
return &AdminRoleDb{Db: engine} | |||
} | |||
type AdminRoleDb struct { | |||
Db *xorm.Engine | |||
} | |||
func (a AdminRoleDb) FindAdminRole(id int) (*[]model.AdminRole, error) { | |||
var m []model.AdminRole | |||
if err := a.Db.Where("adm_id =?", id).Find(&m); err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
return &m, nil | |||
} | |||
func (a AdminRoleDb) FindAdminRoleByRoleId(id int) (*[]model.AdminRole, error) { | |||
var m []model.AdminRole | |||
if err := a.Db.Where("role_id =?", id).Find(&m); err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
return &m, nil | |||
} | |||
func (a AdminRoleDb) AdminDeleteBySessionForAdmId(session *xorm.Session, admId interface{}) (int64, error) { | |||
if reflect.TypeOf(admId).Kind() == reflect.Slice { | |||
return session.In("adm_id", admId).Delete(model.AdminRole{}) | |||
} else { | |||
return session.Where("adm_id = ?", admId).Delete(model.AdminRole{}) | |||
} | |||
} | |||
func (a AdminRoleDb) GetAdminRoleByRole(id int) (m *model.AdminRole, err error) { | |||
m = new(model.AdminRole) | |||
has, err := a.Db.Where("role_id =?", id).Get(m) | |||
if err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return nil, nil | |||
} | |||
return m, nil | |||
} | |||
func (a AdminRoleDb) GetAdminRoleByAdminId(id int) (m *model.AdminRole, err error) { | |||
m = new(model.AdminRole) | |||
has, err := a.Db.Where("adm_id =?", id).Get(m) | |||
if err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return nil, nil | |||
} | |||
return m, nil | |||
} | |||
func (a AdminRoleDb) AdminRoleDeleteForRoleBySession(session *xorm.Session, roleId interface{}) (int64, error) { | |||
if reflect.TypeOf(roleId).Kind() == reflect.Slice { | |||
return session.In("role_id", roleId).Delete(model.AdminRole{}) | |||
} else { | |||
return session.Where("role_id = ?", roleId).Delete(model.AdminRole{}) | |||
} | |||
} | |||
func (a AdminRoleDb) AdminRoleDeleteBySession(session *xorm.Session, id interface{}) (int64, error) { | |||
if reflect.TypeOf(id).Kind() == reflect.Slice { | |||
return session.In("adm_id", id).Delete(model.AdminRole{}) | |||
} else { | |||
return session.Where("adm_id = ?", id).Delete(model.AdminRole{}) | |||
} | |||
} | |||
func (a AdminRoleDb) BatchAddAdminRoleBySession(session *xorm.Session, mm []*model.AdminRole) (int64, error) { | |||
affected, err := session.Insert(mm) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return affected, nil | |||
} |
@@ -0,0 +1,33 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/enum" | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
zhios_order_relate_logx "code.fnuoos.com/zhimeng/model.git/utils/logx" | |||
"xorm.io/xorm" | |||
) | |||
func NewPermissionGroupDb(engine *xorm.Engine) dao.PermissionGroupDao { | |||
return &PermissionGroupDb{Db: engine} | |||
} | |||
type PermissionGroupDb struct { | |||
Db *xorm.Engine | |||
} | |||
func (p PermissionGroupDb) FindPermissionGroup() (*[]model.PermissionGroup, error) { | |||
var m []model.PermissionGroup | |||
if err := p.Db.Where("state = ?", enum.PermissionGroupStateForNormal).Asc("id").Find(&m); err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
return &m, nil | |||
} | |||
func (p PermissionGroupDb) FindPermissionGroupV2() (*[]model.PermissionGroup, error) { | |||
var m []model.PermissionGroup | |||
if err := p.Db.OrderBy("sort desc,id asc").Find(&m); err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
return &m, nil | |||
} |
@@ -0,0 +1,14 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"xorm.io/xorm" | |||
) | |||
type PermissionGroupPermissionDb struct { | |||
Db *xorm.Engine | |||
} | |||
func NewPermissionGroupPermissionDb(engine *xorm.Engine) dao.PermissionGroupPermissionDao { | |||
return &PermissionGroupPermissionDb{Db: engine} | |||
} |
@@ -0,0 +1,14 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"xorm.io/xorm" | |||
) | |||
type PermissionDb struct { | |||
Db *xorm.Engine | |||
} | |||
func NewPermissionDb(engine *xorm.Engine) dao.PermissionDao { | |||
return &PermissionDb{Db: engine} | |||
} |
@@ -0,0 +1,73 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
zhios_order_relate_logx "code.fnuoos.com/zhimeng/model.git/utils/logx" | |||
"reflect" | |||
"xorm.io/xorm" | |||
) | |||
func NewRoleDb(engine *xorm.Engine, id int) dao.RoleDao { | |||
return &RoleDb{ | |||
Db: engine, | |||
Id: id, | |||
} | |||
} | |||
type RoleDb struct { | |||
Db *xorm.Engine | |||
Id int `json:"id"` | |||
} | |||
func (r RoleDb) FindRole() (*[]model.Role, error) { | |||
var m []model.Role | |||
if err := r.Db.Desc("id").Find(&m); err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
return &m, nil | |||
} | |||
func (r RoleDb) GetRole() (m *model.Role, err error) { | |||
m = new(model.Role) | |||
has, err := r.Db.Where("id = ?", r.Id).Get(m) | |||
if err != nil { | |||
return nil, zhios_order_relate_logx.Error(err) | |||
} | |||
if has == false { | |||
return nil, nil | |||
} | |||
return m, nil | |||
} | |||
func (r RoleDb) UpdateRole(m *model.Role, columns ...string) (int64, error) { | |||
affected, err := r.Db.Where("id =?", m.Id).Cols(columns...).Update(m) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return affected, nil | |||
} | |||
func (r RoleDb) RoleDeleteBySession(session *xorm.Session, id interface{}) (int64, error) { | |||
if reflect.TypeOf(id).Kind() == reflect.Slice { | |||
return session.In("id", id).Delete(model.Role{}) | |||
} else { | |||
return session.Where("id = ?", id).Delete(model.Role{}) | |||
} | |||
} | |||
func (r RoleDb) RoleInsert(m *model.Role) (int, error) { | |||
_, err := r.Db.InsertOne(m) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return m.Id, nil | |||
} | |||
func (r RoleDb) FindPermissionGroupByRole(roleId int) (list []*dao.RolePermissionGroup, total int64, err error) { | |||
total, err = r.Db.Where("role.id =?", roleId). | |||
Join("LEFT", "role_permission_group", "role_permission_group.role_id = role.id"). | |||
Join("LEFT", "permission_group", "permission_group.id = role_permission_group.group_id"). | |||
FindAndCount(&list) | |||
return | |||
} |
@@ -0,0 +1,32 @@ | |||
package implement | |||
import ( | |||
"code.fnuoos.com/zhimeng/model.git/src/dao" | |||
"code.fnuoos.com/zhimeng/model.git/src/model" | |||
"reflect" | |||
"xorm.io/xorm" | |||
) | |||
func NewRolePermissionGroupDb(engine *xorm.Engine) dao.RolePermissionGroupDao { | |||
return &RolePermissionGroupDb{Db: engine} | |||
} | |||
type RolePermissionGroupDb struct { | |||
Db *xorm.Engine | |||
} | |||
func (r RolePermissionGroupDb) RolePermissionGroupDeleteForRoleBySession(session *xorm.Session, roleId interface{}) (int64, error) { | |||
if reflect.TypeOf(roleId).Kind() == reflect.Slice { | |||
return session.In("role_id", roleId).Delete(model.RolePermissionGroup{}) | |||
} else { | |||
return session.Where("role_id = ?", roleId).Delete(model.RolePermissionGroup{}) | |||
} | |||
} | |||
func (r RolePermissionGroupDb) BatchAddRolePermissionGroupBySession(session *xorm.Session, mm []*model.RolePermissionGroup) (int64, error) { | |||
affected, err := session.Insert(mm) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return affected, nil | |||
} |
@@ -0,0 +1,13 @@ | |||
package model | |||
type Admin struct { | |||
AdmId int `json:"adm_id" xorm:"not null comment('管理员id') INT(11)"` | |||
Username string `json:"username" xorm:"not null default '' comment('用户名') VARCHAR(255)"` | |||
Password string `json:"password" xorm:"not null default '' comment('密码') VARCHAR(255)"` | |||
State int `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:冻结)') TINYINT(1)"` | |||
IsSuperAdministrator int `json:"is_super_administrator" xorm:"not null default 0 comment('是否为超级管理员(0:否 1:是)') TINYINT(1)"` | |||
IsObserverAdministrator int `json:"is_observer_administrator" xorm:"not null default 0 comment('是否为观察者管理员(0:否 1:是)') TINYINT(1)"` | |||
Memo string `json:"memo" xorm:"not null default '' comment('备注信息') VARCHAR(244)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
} |
@@ -0,0 +1,13 @@ | |||
package model | |||
import ( | |||
"time" | |||
) | |||
type AdminBindMedium struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
AdminId int `json:"admin_id" xorm:"default 0 comment('管理员id') INT(11)"` | |||
MediumId int `json:"medium_id" xorm:"not null default 0 comment('媒体id') INT(11)"` | |||
CreateAt time.Time `json:"create_at" xorm:"not null default CURRENT_TIMESTAMP DATETIME"` | |||
UpdateAt time.Time `json:"update_at" xorm:"not null default CURRENT_TIMESTAMP DATETIME"` | |||
} |
@@ -0,0 +1,10 @@ | |||
package model | |||
type AdminRole struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
AdmId int `json:"adm_id" xorm:"not null default 0 comment('管理员id') INT(11)"` | |||
RoleId int `json:"role_id" xorm:"not null default 0 comment('角色id') INT(11)"` | |||
State int `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:冻结)') TINYINT(1)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
} |
@@ -0,0 +1,10 @@ | |||
package model | |||
type Permission struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
Name string `json:"name" xorm:"not null default '' comment('名称') VARCHAR(255)"` | |||
Action string `json:"action" xorm:"not null default '' comment('路由') unique VARCHAR(255)"` | |||
State int `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:废弃)') TINYINT(1)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
} |
@@ -0,0 +1,12 @@ | |||
package model | |||
type PermissionGroup struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
ParentId int `json:"parent_id" xorm:"not null default 0 comment('父级id') INT(11)"` | |||
Key string `json:"key" xorm:"not null default '' VARCHAR(255)"` | |||
Name string `json:"name" xorm:"not null default '' comment('名称') VARCHAR(255)"` | |||
State int `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:废弃)') TINYINT(1)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
Sort int `json:"sort" xorm:"not null default 0 comment('') INT(11)"` | |||
} |
@@ -0,0 +1,9 @@ | |||
package model | |||
type PermissionGroupPermission struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
GroupId int `json:"group_id" xorm:"not null default 0 comment('权限组id') INT(11)"` | |||
PermissionId int `json:"permission_id" xorm:"not null default 0 comment('权限id') INT(11)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
} |
@@ -0,0 +1,14 @@ | |||
package model | |||
type Role struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
Name string `json:"name" xorm:"not null default '' comment('名称') VARCHAR(255)"` | |||
State int `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:冻结)') TINYINT(1)"` | |||
Memo string `json:"memo" xorm:"not null default '' comment('备注') VARCHAR(255)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
Logo string `json:"logo" xorm:"not null default '' VARCHAR(255)"` | |||
Label string `json:"label" xorm:"not null default '' VARCHAR(255)"` | |||
SeoLogo string `json:"seo_logo" xorm:"not null default '' VARCHAR(255)"` | |||
SeoTitle string `json:"seo_title" xorm:"not null default '' VARCHAR(255)"` | |||
} |
@@ -0,0 +1,9 @@ | |||
package model | |||
type RolePermissionGroup struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
RoleId int `json:"role_id" xorm:"not null default 0 comment('角色id') INT(11)"` | |||
GroupId int `json:"group_id" xorm:"not null default 0 comment('权限组id') INT(11)"` | |||
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"` | |||
} |
@@ -0,0 +1,7 @@ | |||
package model | |||
type SysCfg struct { | |||
K string `json:"k" xorm:"not null pk comment('键') VARCHAR(127)"` | |||
V string `json:"v" xorm:"comment('值') TEXT"` | |||
Memo string `json:"memo" xorm:"not null default '' comment('备注') VARCHAR(255)"` | |||
} |
@@ -0,0 +1,388 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"encoding/binary" | |||
"encoding/json" | |||
"fmt" | |||
"math" | |||
"reflect" | |||
"strconv" | |||
"strings" | |||
) | |||
func ToString(raw interface{}, e error) (res string) { | |||
if e != nil { | |||
return "" | |||
} | |||
return AnyToString(raw) | |||
} | |||
func ToInt64(raw interface{}, e error) int64 { | |||
if e != nil { | |||
return 0 | |||
} | |||
return AnyToInt64(raw) | |||
} | |||
func IsNil(i interface{}) bool { | |||
vi := reflect.ValueOf(i) | |||
if vi.Kind() == reflect.Ptr { | |||
return vi.IsNil() | |||
} | |||
return false | |||
} | |||
func AnyToBool(raw interface{}) bool { | |||
switch i := raw.(type) { | |||
case float32, float64, int, int64, uint, uint8, uint16, uint32, uint64, int8, int16, int32: | |||
return i != 0 | |||
case []byte: | |||
return i != nil | |||
case string: | |||
if i == "false" { | |||
return false | |||
} | |||
return i != "" | |||
case error: | |||
return false | |||
case nil: | |||
return true | |||
} | |||
val := fmt.Sprint(raw) | |||
val = strings.TrimLeft(val, "&") | |||
if strings.TrimLeft(val, "{}") == "" { | |||
return false | |||
} | |||
if strings.TrimLeft(val, "[]") == "" { | |||
return false | |||
} | |||
// ptr type | |||
b, err := json.Marshal(raw) | |||
if err != nil { | |||
return false | |||
} | |||
if strings.TrimLeft(string(b), "\"\"") == "" { | |||
return false | |||
} | |||
if strings.TrimLeft(string(b), "{}") == "" { | |||
return false | |||
} | |||
return true | |||
} | |||
func AnyToInt64(raw interface{}) int64 { | |||
switch i := raw.(type) { | |||
case string: | |||
res, _ := strconv.ParseInt(i, 10, 64) | |||
return res | |||
case []byte: | |||
return BytesToInt64(i) | |||
case int: | |||
return int64(i) | |||
case int64: | |||
return i | |||
case uint: | |||
return int64(i) | |||
case uint8: | |||
return int64(i) | |||
case uint16: | |||
return int64(i) | |||
case uint32: | |||
return int64(i) | |||
case uint64: | |||
return int64(i) | |||
case int8: | |||
return int64(i) | |||
case int16: | |||
return int64(i) | |||
case int32: | |||
return int64(i) | |||
case float32: | |||
return int64(i) | |||
case float64: | |||
return int64(i) | |||
case error: | |||
return 0 | |||
case bool: | |||
if i { | |||
return 1 | |||
} | |||
return 0 | |||
} | |||
return 0 | |||
} | |||
func AnyToString(raw interface{}) string { | |||
switch i := raw.(type) { | |||
case []byte: | |||
return string(i) | |||
case int: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int64: | |||
return strconv.FormatInt(i, 10) | |||
case float32: | |||
return Float64ToStr(float64(i)) | |||
case float64: | |||
return Float64ToStr(i) | |||
case uint: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint64: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case string: | |||
return i | |||
case error: | |||
return i.Error() | |||
case bool: | |||
return strconv.FormatBool(i) | |||
} | |||
return fmt.Sprintf("%#v", raw) | |||
} | |||
func AnyToFloat64(raw interface{}) float64 { | |||
switch i := raw.(type) { | |||
case []byte: | |||
f, _ := strconv.ParseFloat(string(i), 64) | |||
return f | |||
case int: | |||
return float64(i) | |||
case int64: | |||
return float64(i) | |||
case float32: | |||
return float64(i) | |||
case float64: | |||
return i | |||
case uint: | |||
return float64(i) | |||
case uint8: | |||
return float64(i) | |||
case uint16: | |||
return float64(i) | |||
case uint32: | |||
return float64(i) | |||
case uint64: | |||
return float64(i) | |||
case int8: | |||
return float64(i) | |||
case int16: | |||
return float64(i) | |||
case int32: | |||
return float64(i) | |||
case string: | |||
f, _ := strconv.ParseFloat(i, 64) | |||
return f | |||
case bool: | |||
if i { | |||
return 1 | |||
} | |||
} | |||
return 0 | |||
} | |||
func ToByte(raw interface{}, e error) []byte { | |||
if e != nil { | |||
return []byte{} | |||
} | |||
switch i := raw.(type) { | |||
case string: | |||
return []byte(i) | |||
case int: | |||
return Int64ToBytes(int64(i)) | |||
case int64: | |||
return Int64ToBytes(i) | |||
case float32: | |||
return Float32ToByte(i) | |||
case float64: | |||
return Float64ToByte(i) | |||
case uint: | |||
return Int64ToBytes(int64(i)) | |||
case uint8: | |||
return Int64ToBytes(int64(i)) | |||
case uint16: | |||
return Int64ToBytes(int64(i)) | |||
case uint32: | |||
return Int64ToBytes(int64(i)) | |||
case uint64: | |||
return Int64ToBytes(int64(i)) | |||
case int8: | |||
return Int64ToBytes(int64(i)) | |||
case int16: | |||
return Int64ToBytes(int64(i)) | |||
case int32: | |||
return Int64ToBytes(int64(i)) | |||
case []byte: | |||
return i | |||
case error: | |||
return []byte(i.Error()) | |||
case bool: | |||
if i { | |||
return []byte("true") | |||
} | |||
return []byte("false") | |||
} | |||
return []byte(fmt.Sprintf("%#v", raw)) | |||
} | |||
func Int64ToBytes(i int64) []byte { | |||
var buf = make([]byte, 8) | |||
binary.BigEndian.PutUint64(buf, uint64(i)) | |||
return buf | |||
} | |||
func BytesToInt64(buf []byte) int64 { | |||
return int64(binary.BigEndian.Uint64(buf)) | |||
} | |||
func StrToInt(s string) int { | |||
res, _ := strconv.Atoi(s) | |||
return res | |||
} | |||
func StrToInt64(s string) int64 { | |||
res, _ := strconv.ParseInt(s, 10, 64) | |||
return res | |||
} | |||
func Float32ToByte(float float32) []byte { | |||
bits := math.Float32bits(float) | |||
bytes := make([]byte, 4) | |||
binary.LittleEndian.PutUint32(bytes, bits) | |||
return bytes | |||
} | |||
func ByteToFloat32(bytes []byte) float32 { | |||
bits := binary.LittleEndian.Uint32(bytes) | |||
return math.Float32frombits(bits) | |||
} | |||
func Float64ToByte(float float64) []byte { | |||
bits := math.Float64bits(float) | |||
bytes := make([]byte, 8) | |||
binary.LittleEndian.PutUint64(bytes, bits) | |||
return bytes | |||
} | |||
func ByteToFloat64(bytes []byte) float64 { | |||
bits := binary.LittleEndian.Uint64(bytes) | |||
return math.Float64frombits(bits) | |||
} | |||
func Float64ToStr(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 2, 64) | |||
} | |||
func Float64ToStrPrec1(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 1, 64) | |||
} | |||
func Float64ToStrPrec4(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 4, 64) | |||
} | |||
func Float64ToStrPrec10(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 10, 64) | |||
} | |||
func Float64ToStrPrec8(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 8, 64) | |||
} | |||
func Float64ToStrPrec6(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 6, 64) | |||
} | |||
func Float64ToStrByPrec(f float64, prec int) string { | |||
return strconv.FormatFloat(f, 'f', prec, 64) | |||
} | |||
func Float32ToStr(f float32) string { | |||
return Float64ToStr(float64(f)) | |||
} | |||
func StrToFloat64(s string) float64 { | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} | |||
func StrToFormat(s string, prec int) string { | |||
ex := strings.Split(s, ".") | |||
if len(ex) == 2 { | |||
if StrToFloat64(ex[1]) == 0 { //小数点后面为空就是不要小数点了 | |||
return ex[0] | |||
} | |||
//看取多少位 | |||
str := ex[1] | |||
str1 := str | |||
if prec < len(str) { | |||
str1 = str[0:prec] | |||
} else { | |||
for i := 0; i < prec-len(str); i++ { | |||
str1 += "0" | |||
} | |||
} | |||
if prec > 0 { | |||
return ex[0] + "." + str1 | |||
} else { | |||
return ex[0] | |||
} | |||
} | |||
return s | |||
} | |||
func StrToFloat32(s string) float32 { | |||
res, err := strconv.ParseFloat(s, 32) | |||
if err != nil { | |||
return 0 | |||
} | |||
return float32(res) | |||
} | |||
func StrToBool(s string) bool { | |||
b, _ := strconv.ParseBool(s) | |||
return b | |||
} | |||
func BoolToStr(b bool) string { | |||
if b { | |||
return "true" | |||
} | |||
return "false" | |||
} | |||
func FloatToInt64(f float64) int64 { | |||
return int64(f) | |||
} | |||
func IntToStr(i int) string { | |||
return strconv.Itoa(i) | |||
} | |||
func Int64ToStr(i int64) string { | |||
return strconv.FormatInt(i, 10) | |||
} | |||
func IntToFloat64(i int) float64 { | |||
s := strconv.Itoa(i) | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} | |||
func Int64ToFloat64(i int64) float64 { | |||
s := strconv.FormatInt(i, 10) | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} |
@@ -0,0 +1,209 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"bytes" | |||
"crypto/tls" | |||
"fmt" | |||
"io" | |||
"io/ioutil" | |||
"net/http" | |||
"net/url" | |||
"sort" | |||
"strings" | |||
"time" | |||
) | |||
var CurlDebug bool | |||
func CurlGet(router string, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodGet, router, nil, header) | |||
} | |||
func CurlGetJson(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl_new(http.MethodGet, router, body, header) | |||
} | |||
// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string | |||
func CurlPost(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodPost, router, body, header) | |||
} | |||
func CurlPut(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodPut, router, body, header) | |||
} | |||
// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string | |||
func CurlPatch(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodPatch, router, body, header) | |||
} | |||
// CurlDelete is curl delete | |||
func CurlDelete(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodDelete, router, body, header) | |||
} | |||
func curl(method, router string, body interface{}, header map[string]string) ([]byte, error) { | |||
var reqBody io.Reader | |||
contentType := "application/json" | |||
switch v := body.(type) { | |||
case string: | |||
reqBody = strings.NewReader(v) | |||
case []byte: | |||
reqBody = bytes.NewReader(v) | |||
case map[string]string: | |||
val := url.Values{} | |||
for k, v := range v { | |||
val.Set(k, v) | |||
} | |||
reqBody = strings.NewReader(val.Encode()) | |||
contentType = "application/x-www-form-urlencoded" | |||
case map[string]interface{}: | |||
val := url.Values{} | |||
for k, v := range v { | |||
val.Set(k, v.(string)) | |||
} | |||
reqBody = strings.NewReader(val.Encode()) | |||
contentType = "application/x-www-form-urlencoded" | |||
} | |||
if header == nil { | |||
header = map[string]string{"Content-Type": contentType} | |||
} | |||
if _, ok := header["Content-Type"]; !ok { | |||
header["Content-Type"] = contentType | |||
} | |||
resp, er := CurlReq(method, router, reqBody, header) | |||
if er != nil { | |||
return nil, er | |||
} | |||
res, err := ioutil.ReadAll(resp.Body) | |||
if CurlDebug { | |||
blob := SerializeStr(body) | |||
if contentType != "application/json" { | |||
blob = HttpBuild(body) | |||
} | |||
fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n", | |||
router, | |||
time.Now().Format("2006-01-02 15:04:05.000"), | |||
method, | |||
contentType, | |||
HttpBuildQuery(header), | |||
blob, | |||
err, | |||
SerializeStr(resp.Header), | |||
string(res), | |||
) | |||
} | |||
resp.Body.Close() | |||
return res, err | |||
} | |||
func curl_new(method, router string, body interface{}, header map[string]string) ([]byte, error) { | |||
var reqBody io.Reader | |||
contentType := "application/json" | |||
if header == nil { | |||
header = map[string]string{"Content-Type": contentType} | |||
} | |||
if _, ok := header["Content-Type"]; !ok { | |||
header["Content-Type"] = contentType | |||
} | |||
resp, er := CurlReq(method, router, reqBody, header) | |||
if er != nil { | |||
return nil, er | |||
} | |||
res, err := ioutil.ReadAll(resp.Body) | |||
if CurlDebug { | |||
blob := SerializeStr(body) | |||
if contentType != "application/json" { | |||
blob = HttpBuild(body) | |||
} | |||
fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n", | |||
router, | |||
time.Now().Format("2006-01-02 15:04:05.000"), | |||
method, | |||
contentType, | |||
HttpBuildQuery(header), | |||
blob, | |||
err, | |||
SerializeStr(resp.Header), | |||
string(res), | |||
) | |||
} | |||
resp.Body.Close() | |||
return res, err | |||
} | |||
func CurlReq(method, router string, reqBody io.Reader, header map[string]string) (*http.Response, error) { | |||
req, _ := http.NewRequest(method, router, reqBody) | |||
if header != nil { | |||
for k, v := range header { | |||
req.Header.Set(k, v) | |||
} | |||
} | |||
// 绕过github等可能因为特征码返回503问题 | |||
// https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/ | |||
defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009, | |||
0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a} | |||
client := &http.Client{ | |||
Transport: &http.Transport{ | |||
TLSClientConfig: &tls.Config{ | |||
InsecureSkipVerify: true, | |||
CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...), | |||
}, | |||
}, | |||
// 获取301重定向 | |||
CheckRedirect: func(req *http.Request, via []*http.Request) error { | |||
return http.ErrUseLastResponse | |||
}, | |||
} | |||
return client.Do(req) | |||
} | |||
// 组建get请求参数,sortAsc true为小到大,false为大到小,nil不排序 a=123&b=321 | |||
func HttpBuildQuery(args map[string]string, sortAsc ...bool) string { | |||
str := "" | |||
if len(args) == 0 { | |||
return str | |||
} | |||
if len(sortAsc) > 0 { | |||
keys := make([]string, 0, len(args)) | |||
for k := range args { | |||
keys = append(keys, k) | |||
} | |||
if sortAsc[0] { | |||
sort.Strings(keys) | |||
} else { | |||
sort.Sort(sort.Reverse(sort.StringSlice(keys))) | |||
} | |||
for _, k := range keys { | |||
str += "&" + k + "=" + args[k] | |||
} | |||
} else { | |||
for k, v := range args { | |||
str += "&" + k + "=" + v | |||
} | |||
} | |||
return str[1:] | |||
} | |||
func HttpBuild(body interface{}, sortAsc ...bool) string { | |||
params := map[string]string{} | |||
if args, ok := body.(map[string]interface{}); ok { | |||
for k, v := range args { | |||
params[k] = AnyToString(v) | |||
} | |||
return HttpBuildQuery(params, sortAsc...) | |||
} | |||
if args, ok := body.(map[string]string); ok { | |||
for k, v := range args { | |||
params[k] = AnyToString(v) | |||
} | |||
return HttpBuildQuery(params, sortAsc...) | |||
} | |||
if args, ok := body.(map[string]int); ok { | |||
for k, v := range args { | |||
params[k] = AnyToString(v) | |||
} | |||
return HttpBuildQuery(params, sortAsc...) | |||
} | |||
return AnyToString(body) | |||
} |
@@ -0,0 +1,22 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"os" | |||
"path" | |||
"strings" | |||
"time" | |||
) | |||
// 获取文件后缀 | |||
func FileExt(fname string) string { | |||
return strings.ToLower(strings.TrimLeft(path.Ext(fname), ".")) | |||
} | |||
func FilePutContents(fileName string, content string) { | |||
fd, _ := os.OpenFile("./tmp/"+fileName+".logs", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) | |||
fd_time := time.Now().Format("2006-01-02 15:04:05") | |||
fd_content := strings.Join([]string{"[", fd_time, "] ", content, "\n"}, "") | |||
buf := []byte(fd_content) | |||
fd.Write(buf) | |||
fd.Close() | |||
} |
@@ -0,0 +1,59 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"math" | |||
) | |||
func CouponFormat(data string) string { | |||
switch data { | |||
case "0.00", "0", "": | |||
return "" | |||
default: | |||
return Int64ToStr(FloatToInt64(StrToFloat64(data))) | |||
} | |||
} | |||
func CommissionFormat(data string) string { | |||
if data != "" && data != "0" { | |||
return data | |||
} | |||
return "" | |||
} | |||
func HideString(src string, hLen int) string { | |||
str := []rune(src) | |||
if hLen == 0 { | |||
hLen = 4 | |||
} | |||
hideStr := "" | |||
for i := 0; i < hLen; i++ { | |||
hideStr += "*" | |||
} | |||
hideLen := len(str) / 2 | |||
showLen := len(str) - hideLen | |||
if hideLen == 0 || showLen == 0 { | |||
return hideStr | |||
} | |||
subLen := showLen / 2 | |||
if subLen == 0 { | |||
return string(str[:showLen]) + hideStr | |||
} | |||
s := string(str[:subLen]) | |||
s += hideStr | |||
s += string(str[len(str)-subLen:]) | |||
return s | |||
} | |||
//SaleCountFormat is 格式化销量 | |||
func SaleCountFormat(s string) string { | |||
return s + "已售" | |||
} | |||
// 小数格式化 | |||
func FloatFormat(f float64, i int) float64 { | |||
if i > 14 { | |||
return f | |||
} | |||
p := math.Pow10(i) | |||
return float64(int64((f+0.000000000000009)*p)) / p | |||
} |
@@ -0,0 +1,245 @@ | |||
package zhios_order_relate_logx | |||
import ( | |||
"os" | |||
"strings" | |||
"time" | |||
"go.uber.org/zap" | |||
"go.uber.org/zap/zapcore" | |||
) | |||
type LogConfig struct { | |||
AppName string `yaml:"app_name" json:"app_name" toml:"app_name"` | |||
Level string `yaml:"level" json:"level" toml:"level"` | |||
StacktraceLevel string `yaml:"stacktrace_level" json:"stacktrace_level" toml:"stacktrace_level"` | |||
IsStdOut bool `yaml:"is_stdout" json:"is_stdout" toml:"is_stdout"` | |||
TimeFormat string `yaml:"time_format" json:"time_format" toml:"time_format"` // second, milli, nano, standard, iso, | |||
Encoding string `yaml:"encoding" json:"encoding" toml:"encoding"` // console, json | |||
Skip int `yaml:"skip" json:"skip" toml:"skip"` | |||
IsFileOut bool `yaml:"is_file_out" json:"is_file_out" toml:"is_file_out"` | |||
FileDir string `yaml:"file_dir" json:"file_dir" toml:"file_dir"` | |||
FileName string `yaml:"file_name" json:"file_name" toml:"file_name"` | |||
FileMaxSize int `yaml:"file_max_size" json:"file_max_size" toml:"file_max_size"` | |||
FileMaxAge int `yaml:"file_max_age" json:"file_max_age" toml:"file_max_age"` | |||
} | |||
var ( | |||
l *LogX = defaultLogger() | |||
conf *LogConfig | |||
) | |||
// default logger setting | |||
func defaultLogger() *LogX { | |||
conf = &LogConfig{ | |||
Level: "debug", | |||
StacktraceLevel: "error", | |||
IsStdOut: true, | |||
TimeFormat: "standard", | |||
Encoding: "console", | |||
Skip: 2, | |||
} | |||
writers := []zapcore.WriteSyncer{os.Stdout} | |||
lg, lv := newZapLogger(setLogLevel(conf.Level), setLogLevel(conf.StacktraceLevel), conf.Encoding, conf.TimeFormat, conf.Skip, zapcore.NewMultiWriteSyncer(writers...)) | |||
zap.RedirectStdLog(lg) | |||
return &LogX{logger: lg, atomLevel: lv} | |||
} | |||
// initial standard log, if you don't init, it will use default logger setting | |||
func InitDefaultLogger(cfg *LogConfig) { | |||
var writers []zapcore.WriteSyncer | |||
if cfg.IsStdOut || (!cfg.IsStdOut && !cfg.IsFileOut) { | |||
writers = append(writers, os.Stdout) | |||
} | |||
if cfg.IsFileOut { | |||
writers = append(writers, NewRollingFile(cfg.FileDir, cfg.FileName, cfg.FileMaxSize, cfg.FileMaxAge)) | |||
} | |||
lg, lv := newZapLogger(setLogLevel(cfg.Level), setLogLevel(cfg.StacktraceLevel), cfg.Encoding, cfg.TimeFormat, cfg.Skip, zapcore.NewMultiWriteSyncer(writers...)) | |||
zap.RedirectStdLog(lg) | |||
if cfg.AppName != "" { | |||
lg = lg.With(zap.String("app", cfg.AppName)) // 加上应用名称 | |||
} | |||
l = &LogX{logger: lg, atomLevel: lv} | |||
} | |||
// create a new logger | |||
func NewLogger(cfg *LogConfig) *LogX { | |||
var writers []zapcore.WriteSyncer | |||
if cfg.IsStdOut || (!cfg.IsStdOut && !cfg.IsFileOut) { | |||
writers = append(writers, os.Stdout) | |||
} | |||
if cfg.IsFileOut { | |||
writers = append(writers, NewRollingFile(cfg.FileDir, cfg.FileName, cfg.FileMaxSize, cfg.FileMaxAge)) | |||
} | |||
lg, lv := newZapLogger(setLogLevel(cfg.Level), setLogLevel(cfg.StacktraceLevel), cfg.Encoding, cfg.TimeFormat, cfg.Skip, zapcore.NewMultiWriteSyncer(writers...)) | |||
zap.RedirectStdLog(lg) | |||
if cfg.AppName != "" { | |||
lg = lg.With(zap.String("app", cfg.AppName)) // 加上应用名称 | |||
} | |||
return &LogX{logger: lg, atomLevel: lv} | |||
} | |||
// create a new zaplog logger | |||
func newZapLogger(level, stacktrace zapcore.Level, encoding, timeType string, skip int, output zapcore.WriteSyncer) (*zap.Logger, *zap.AtomicLevel) { | |||
encCfg := zapcore.EncoderConfig{ | |||
TimeKey: "T", | |||
LevelKey: "L", | |||
NameKey: "N", | |||
CallerKey: "C", | |||
MessageKey: "M", | |||
StacktraceKey: "S", | |||
LineEnding: zapcore.DefaultLineEnding, | |||
EncodeCaller: zapcore.ShortCallerEncoder, | |||
EncodeDuration: zapcore.NanosDurationEncoder, | |||
EncodeLevel: zapcore.LowercaseLevelEncoder, | |||
} | |||
setTimeFormat(timeType, &encCfg) // set time type | |||
atmLvl := zap.NewAtomicLevel() // set level | |||
atmLvl.SetLevel(level) | |||
encoder := zapcore.NewJSONEncoder(encCfg) // 确定encoder格式 | |||
if encoding == "console" { | |||
encoder = zapcore.NewConsoleEncoder(encCfg) | |||
} | |||
return zap.New(zapcore.NewCore(encoder, output, atmLvl), zap.AddCaller(), zap.AddStacktrace(stacktrace), zap.AddCallerSkip(skip)), &atmLvl | |||
} | |||
// set log level | |||
func setLogLevel(lvl string) zapcore.Level { | |||
switch strings.ToLower(lvl) { | |||
case "panic": | |||
return zapcore.PanicLevel | |||
case "fatal": | |||
return zapcore.FatalLevel | |||
case "error": | |||
return zapcore.ErrorLevel | |||
case "warn", "warning": | |||
return zapcore.WarnLevel | |||
case "info": | |||
return zapcore.InfoLevel | |||
default: | |||
return zapcore.DebugLevel | |||
} | |||
} | |||
// set time format | |||
func setTimeFormat(timeType string, z *zapcore.EncoderConfig) { | |||
switch strings.ToLower(timeType) { | |||
case "iso": // iso8601 standard | |||
z.EncodeTime = zapcore.ISO8601TimeEncoder | |||
case "sec": // only for unix second, without millisecond | |||
z.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | |||
enc.AppendInt64(t.Unix()) | |||
} | |||
case "second": // unix second, with millisecond | |||
z.EncodeTime = zapcore.EpochTimeEncoder | |||
case "milli", "millisecond": // millisecond | |||
z.EncodeTime = zapcore.EpochMillisTimeEncoder | |||
case "nano", "nanosecond": // nanosecond | |||
z.EncodeTime = zapcore.EpochNanosTimeEncoder | |||
default: // standard format | |||
z.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | |||
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) | |||
} | |||
} | |||
} | |||
func GetLevel() string { | |||
switch l.atomLevel.Level() { | |||
case zapcore.PanicLevel: | |||
return "panic" | |||
case zapcore.FatalLevel: | |||
return "fatal" | |||
case zapcore.ErrorLevel: | |||
return "error" | |||
case zapcore.WarnLevel: | |||
return "warn" | |||
case zapcore.InfoLevel: | |||
return "info" | |||
default: | |||
return "debug" | |||
} | |||
} | |||
func SetLevel(lvl string) { | |||
l.atomLevel.SetLevel(setLogLevel(lvl)) | |||
} | |||
// temporary add call skip | |||
func AddCallerSkip(skip int) *LogX { | |||
l.logger.WithOptions(zap.AddCallerSkip(skip)) | |||
return l | |||
} | |||
// permanent add call skip | |||
func AddDepth(skip int) *LogX { | |||
l.logger = l.logger.WithOptions(zap.AddCallerSkip(skip)) | |||
return l | |||
} | |||
// permanent add options | |||
func AddOptions(opts ...zap.Option) *LogX { | |||
l.logger = l.logger.WithOptions(opts...) | |||
return l | |||
} | |||
func AddField(k string, v interface{}) { | |||
l.logger.With(zap.Any(k, v)) | |||
} | |||
func AddFields(fields map[string]interface{}) *LogX { | |||
for k, v := range fields { | |||
l.logger.With(zap.Any(k, v)) | |||
} | |||
return l | |||
} | |||
// Normal log | |||
func Debug(e interface{}, args ...interface{}) error { | |||
return l.Debug(e, args...) | |||
} | |||
func Info(e interface{}, args ...interface{}) error { | |||
return l.Info(e, args...) | |||
} | |||
func Warn(e interface{}, args ...interface{}) error { | |||
return l.Warn(e, args...) | |||
} | |||
func Error(e interface{}, args ...interface{}) error { | |||
return l.Error(e, args...) | |||
} | |||
func Panic(e interface{}, args ...interface{}) error { | |||
return l.Panic(e, args...) | |||
} | |||
func Fatal(e interface{}, args ...interface{}) error { | |||
return l.Fatal(e, args...) | |||
} | |||
// Format logs | |||
func Debugf(format string, args ...interface{}) error { | |||
return l.Debugf(format, args...) | |||
} | |||
func Infof(format string, args ...interface{}) error { | |||
return l.Infof(format, args...) | |||
} | |||
func Warnf(format string, args ...interface{}) error { | |||
return l.Warnf(format, args...) | |||
} | |||
func Errorf(format string, args ...interface{}) error { | |||
return l.Errorf(format, args...) | |||
} | |||
func Panicf(format string, args ...interface{}) error { | |||
return l.Panicf(format, args...) | |||
} | |||
func Fatalf(format string, args ...interface{}) error { | |||
return l.Fatalf(format, args...) | |||
} | |||
func formatFieldMap(m FieldMap) []Field { | |||
var res []Field | |||
for k, v := range m { | |||
res = append(res, zap.Any(k, v)) | |||
} | |||
return res | |||
} |
@@ -0,0 +1,105 @@ | |||
package zhios_order_relate_logx | |||
import ( | |||
"bytes" | |||
"io" | |||
"os" | |||
"path/filepath" | |||
"time" | |||
"gopkg.in/natefinch/lumberjack.v2" | |||
) | |||
// output interface | |||
type WriteSyncer interface { | |||
io.Writer | |||
Sync() error | |||
} | |||
// split writer | |||
func NewRollingFile(dir, filename string, maxSize, MaxAge int) WriteSyncer { | |||
s, err := os.Stat(dir) | |||
if err != nil || !s.IsDir() { | |||
os.RemoveAll(dir) | |||
if err := os.MkdirAll(dir, 0766); err != nil { | |||
panic(err) | |||
} | |||
} | |||
return newLumberjackWriteSyncer(&lumberjack.Logger{ | |||
Filename: filepath.Join(dir, filename), | |||
MaxSize: maxSize, // megabytes, MB | |||
MaxAge: MaxAge, // days | |||
LocalTime: true, | |||
Compress: false, | |||
}) | |||
} | |||
type lumberjackWriteSyncer struct { | |||
*lumberjack.Logger | |||
buf *bytes.Buffer | |||
logChan chan []byte | |||
closeChan chan interface{} | |||
maxSize int | |||
} | |||
func newLumberjackWriteSyncer(l *lumberjack.Logger) *lumberjackWriteSyncer { | |||
ws := &lumberjackWriteSyncer{ | |||
Logger: l, | |||
buf: bytes.NewBuffer([]byte{}), | |||
logChan: make(chan []byte, 5000), | |||
closeChan: make(chan interface{}), | |||
maxSize: 1024, | |||
} | |||
go ws.run() | |||
return ws | |||
} | |||
func (l *lumberjackWriteSyncer) run() { | |||
ticker := time.NewTicker(1 * time.Second) | |||
for { | |||
select { | |||
case <-ticker.C: | |||
if l.buf.Len() > 0 { | |||
l.sync() | |||
} | |||
case bs := <-l.logChan: | |||
_, err := l.buf.Write(bs) | |||
if err != nil { | |||
continue | |||
} | |||
if l.buf.Len() > l.maxSize { | |||
l.sync() | |||
} | |||
case <-l.closeChan: | |||
l.sync() | |||
return | |||
} | |||
} | |||
} | |||
func (l *lumberjackWriteSyncer) Stop() { | |||
close(l.closeChan) | |||
} | |||
func (l *lumberjackWriteSyncer) Write(bs []byte) (int, error) { | |||
b := make([]byte, len(bs)) | |||
for i, c := range bs { | |||
b[i] = c | |||
} | |||
l.logChan <- b | |||
return 0, nil | |||
} | |||
func (l *lumberjackWriteSyncer) Sync() error { | |||
return nil | |||
} | |||
func (l *lumberjackWriteSyncer) sync() error { | |||
defer l.buf.Reset() | |||
_, err := l.Logger.Write(l.buf.Bytes()) | |||
if err != nil { | |||
return err | |||
} | |||
return nil | |||
} |
@@ -0,0 +1,192 @@ | |||
package zhios_order_relate_logx | |||
import ( | |||
"errors" | |||
"fmt" | |||
"strconv" | |||
"go.uber.org/zap" | |||
) | |||
type LogX struct { | |||
logger *zap.Logger | |||
atomLevel *zap.AtomicLevel | |||
} | |||
type Field = zap.Field | |||
type FieldMap map[string]interface{} | |||
// 判断其他类型--start | |||
func getFields(msg string, format bool, args ...interface{}) (string, []Field) { | |||
var str []interface{} | |||
var fields []zap.Field | |||
if len(args) > 0 { | |||
for _, v := range args { | |||
if f, ok := v.(Field); ok { | |||
fields = append(fields, f) | |||
} else if f, ok := v.(FieldMap); ok { | |||
fields = append(fields, formatFieldMap(f)...) | |||
} else { | |||
str = append(str, AnyToString(v)) | |||
} | |||
} | |||
if format { | |||
return fmt.Sprintf(msg, str...), fields | |||
} | |||
str = append([]interface{}{msg}, str...) | |||
return fmt.Sprintln(str...), fields | |||
} | |||
return msg, []Field{} | |||
} | |||
func (l *LogX) Debug(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Debug(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Info(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Info(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Warn(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Warn(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Error(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Error(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) DPanic(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.DPanic(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Panic(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Panic(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Fatal(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Fatal(msg, field...) | |||
} | |||
return e | |||
} | |||
func checkErr(s interface{}) (string, error) { | |||
switch e := s.(type) { | |||
case error: | |||
return e.Error(), e | |||
case string: | |||
return e, errors.New(e) | |||
case []byte: | |||
return string(e), nil | |||
default: | |||
return "", nil | |||
} | |||
} | |||
func (l *LogX) LogError(err error) error { | |||
return l.Error(err.Error()) | |||
} | |||
func (l *LogX) Debugf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Debug(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Infof(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Info(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Warnf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Warn(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Errorf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Error(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) DPanicf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.DPanic(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Panicf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Panic(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Fatalf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Fatal(s, f...) | |||
return errors.New(s) | |||
} | |||
func AnyToString(raw interface{}) string { | |||
switch i := raw.(type) { | |||
case []byte: | |||
return string(i) | |||
case int: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int64: | |||
return strconv.FormatInt(i, 10) | |||
case float32: | |||
return strconv.FormatFloat(float64(i), 'f', 2, 64) | |||
case float64: | |||
return strconv.FormatFloat(i, 'f', 2, 64) | |||
case uint: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint64: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case string: | |||
return i | |||
case error: | |||
return i.Error() | |||
} | |||
return fmt.Sprintf("%#v", raw) | |||
} |
@@ -0,0 +1,23 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"encoding/json" | |||
) | |||
func Serialize(data interface{}) []byte { | |||
res, err := json.Marshal(data) | |||
if err != nil { | |||
return []byte{} | |||
} | |||
return res | |||
} | |||
func Unserialize(b []byte, dst interface{}) { | |||
if err := json.Unmarshal(b, dst); err != nil { | |||
dst = nil | |||
} | |||
} | |||
func SerializeStr(data interface{}, arg ...interface{}) string { | |||
return string(Serialize(data)) | |||
} |
@@ -0,0 +1,203 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"fmt" | |||
"github.com/syyongx/php2go" | |||
"math/rand" | |||
"reflect" | |||
"sort" | |||
"strings" | |||
"time" | |||
) | |||
func Implode(glue string, args ...interface{}) string { | |||
data := make([]string, len(args)) | |||
for i, s := range args { | |||
data[i] = fmt.Sprint(s) | |||
} | |||
return strings.Join(data, glue) | |||
} | |||
//字符串是否在数组里 | |||
func InArr(target string, str_array []string) bool { | |||
for _, element := range str_array { | |||
if target == element { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
func InArrToInt(target int, str_array []int) bool { | |||
for _, element := range str_array { | |||
if target == element { | |||
return true | |||
} | |||
} | |||
return false | |||
} | |||
//把数组的值放到key里 | |||
func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) { | |||
result = make(map[string]interface{}) | |||
t := reflect.TypeOf(array) | |||
v := reflect.ValueOf(array) | |||
if t.Kind() != reflect.Slice { | |||
return nil, nil | |||
} | |||
if v.Len() == 0 { | |||
return nil, nil | |||
} | |||
for i := 0; i < v.Len(); i++ { | |||
indexv := v.Index(i) | |||
if indexv.Type().Kind() != reflect.Struct { | |||
return nil, nil | |||
} | |||
mapKeyInterface := indexv.FieldByName(key) | |||
if mapKeyInterface.Kind() == reflect.Invalid { | |||
return nil, nil | |||
} | |||
mapKeyString, err := InterfaceToString(mapKeyInterface.Interface()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
result[mapKeyString] = indexv.Interface() | |||
} | |||
return result, err | |||
} | |||
//转string | |||
func InterfaceToString(v interface{}) (result string, err error) { | |||
switch reflect.TypeOf(v).Kind() { | |||
case reflect.Int64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: | |||
result = fmt.Sprintf("%v", v) | |||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | |||
result = fmt.Sprintf("%v", v) | |||
case reflect.String: | |||
result = v.(string) | |||
default: | |||
err = nil | |||
} | |||
return result, err | |||
} | |||
func HideTrueName(name string) string { | |||
res := "**" | |||
if name != "" { | |||
runs := []rune(name) | |||
leng := len(runs) | |||
if leng <= 3 { | |||
res = string(runs[0:1]) + res | |||
} else if leng < 5 { | |||
res = string(runs[0:2]) + res | |||
} else if leng < 10 { | |||
res = string(runs[0:2]) + "***" + string(runs[leng-2:leng]) | |||
} else if leng < 16 { | |||
res = string(runs[0:3]) + "****" + string(runs[leng-3:leng]) | |||
} else { | |||
res = string(runs[0:4]) + "*****" + string(runs[leng-4:leng]) | |||
} | |||
} | |||
return res | |||
} | |||
func GetQueryParam(uri string) map[string]string { | |||
//根据问号分割路由还是query参数 | |||
uriList := strings.Split(uri, "?") | |||
var query = make(map[string]string, 0) | |||
//有参数才处理 | |||
if len(uriList) == 2 { | |||
//分割query参数 | |||
var queryList = strings.Split(uriList[1], "&") | |||
if len(queryList) > 0 { | |||
//key value 分别赋值 | |||
for _, v := range queryList { | |||
var valueList = strings.Split(v, "=") | |||
if len(valueList) == 2 { | |||
value, _ := php2go.URLDecode(valueList[1]) | |||
if value == "" { | |||
value = valueList[1] | |||
} | |||
query[valueList[0]] = value | |||
} | |||
} | |||
} | |||
} | |||
return query | |||
} | |||
//JoinStringsInASCII 按照规则,参数名ASCII码从小到大排序后拼接 | |||
//data 待拼接的数据 | |||
//sep 连接符 | |||
//onlyValues 是否只包含参数值,true则不包含参数名,否则参数名和参数值均有 | |||
//includeEmpty 是否包含空值,true则包含空值,否则不包含,注意此参数不影响参数名的存在 | |||
//exceptKeys 被排除的参数名,不参与排序及拼接 | |||
func JoinStringsInASCII(data map[string]string, sep string, onlyValues, includeEmpty bool, exceptKeys ...string) string { | |||
var list []string | |||
var keyList []string | |||
m := make(map[string]int) | |||
if len(exceptKeys) > 0 { | |||
for _, except := range exceptKeys { | |||
m[except] = 1 | |||
} | |||
} | |||
for k := range data { | |||
if _, ok := m[k]; ok { | |||
continue | |||
} | |||
value := data[k] | |||
if !includeEmpty && value == "" { | |||
continue | |||
} | |||
if onlyValues { | |||
keyList = append(keyList, k) | |||
} else { | |||
list = append(list, fmt.Sprintf("%s=%s", k, value)) | |||
} | |||
} | |||
if onlyValues { | |||
sort.Strings(keyList) | |||
for _, v := range keyList { | |||
list = append(list, AnyToString(data[v])) | |||
} | |||
} else { | |||
sort.Strings(list) | |||
} | |||
return strings.Join(list, sep) | |||
} | |||
//x的y次方 | |||
func RandPow(l int) string { | |||
var i = "1" | |||
for j := 0; j < l; j++ { | |||
i += "0" | |||
} | |||
k := StrToInt64(i) | |||
n := rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(k) | |||
ls := "%0" + IntToStr(l) + "v" | |||
str := fmt.Sprintf(ls, n) | |||
//min := int(math.Pow10(l - 1)) | |||
//max := int(math.Pow10(l) - 1) | |||
return str | |||
} | |||
//根据显示长度截取字符串 | |||
func ShowSubstr(s string, l int) string { | |||
if len(s) <= l { | |||
return s | |||
} | |||
ss, sl, rl, rs := "", 0, 0, []rune(s) | |||
for _, r := range rs { | |||
rint := int(r) | |||
if rint < 128 { | |||
rl = 1 | |||
} else { | |||
rl = 2 | |||
} | |||
if sl+rl > l { | |||
break | |||
} | |||
sl += rl | |||
ss += string(r) | |||
} | |||
return ss | |||
} |
@@ -0,0 +1,29 @@ | |||
package zhios_order_relate_utils | |||
import "time" | |||
func Time2String(date time.Time, format string) string { | |||
if format == "" { | |||
format = "2006-01-02 15:04:05" | |||
} | |||
timeS := date.Format(format) | |||
if timeS == "0001-01-01 00:00:00" { | |||
return "" | |||
} | |||
return timeS | |||
} | |||
func String2Time(timeStr string) time.Time { | |||
toTime, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local) | |||
if err != nil { | |||
return time.Now() | |||
} | |||
return toTime | |||
} | |||
//GetDiffDays 获取两个时间相差的天数,0表同一天,正数表t1>t2,负数表t1<t2 | |||
func GetDiffDays(t1, t2 time.Time) int { | |||
t1 = time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, time.Local) | |||
t2 = time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, time.Local) | |||
return int(t1.Sub(t2).Hours() / 24) | |||
} |