Commit 6d6d85bcbfc0f3b178a9c85b5961ccb960bf973f
1 parent
2af431f1
Exists in
master
and in
1 other branch
feat:util-lx相关库整理
Showing
12 changed files
with
1528 additions
and
0 deletions
Show diff stats
| ... | ... | @@ -0,0 +1,269 @@ |
| 1 | +package lxalilog | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "fmt" | |
| 5 | + "os" | |
| 6 | + "os/signal" | |
| 7 | + "runtime" | |
| 8 | + "strings" | |
| 9 | + "time" | |
| 10 | + | |
| 11 | + sls "github.com/aliyun/aliyun-log-go-sdk" | |
| 12 | + | |
| 13 | + "github.com/aliyun/aliyun-log-go-sdk/producer" | |
| 14 | + "github.com/astaxie/beego/logs" | |
| 15 | + lconv "github.com/lixu-any/go-tools/conv" | |
| 16 | + ltime "github.com/lixu-any/go-tools/time" | |
| 17 | +) | |
| 18 | + | |
| 19 | +var ( | |
| 20 | + LXAliProducer *producer.Producer | |
| 21 | + LXAliDefaultConfig MapAlilogConfig //默认配置 | |
| 22 | +) | |
| 23 | + | |
| 24 | +type MapAlilogConfig struct { | |
| 25 | + Endpoint string | |
| 26 | + AccessKeyId string | |
| 27 | + AppNaame string | |
| 28 | + AccessKeySecret string | |
| 29 | + Project string | |
| 30 | + On string | |
| 31 | + Debug string | |
| 32 | + | |
| 33 | + TableError string | |
| 34 | + TableDebug string | |
| 35 | + Env string | |
| 36 | +} | |
| 37 | + | |
| 38 | +// 初始化阿里云日志 | |
| 39 | +func InitAliLog(config MapAlilogConfig) { | |
| 40 | + | |
| 41 | + LXAliDefaultConfig = config | |
| 42 | + | |
| 43 | + if config.On != "1" { | |
| 44 | + return | |
| 45 | + } | |
| 46 | + | |
| 47 | + producerConfig := producer.GetDefaultProducerConfig() | |
| 48 | + | |
| 49 | + producerConfig.Endpoint = config.Endpoint | |
| 50 | + producerConfig.AccessKeyID = config.AccessKeyId | |
| 51 | + producerConfig.AccessKeySecret = config.AccessKeySecret | |
| 52 | + | |
| 53 | + LXAliProducer = producer.InitProducer(producerConfig) | |
| 54 | + | |
| 55 | + ch := make(chan os.Signal) | |
| 56 | + | |
| 57 | + signal.Notify(ch) | |
| 58 | + | |
| 59 | + LXAliProducer.Start() | |
| 60 | + | |
| 61 | + //LXAliProducer.SafeClose() // 安全关闭 | |
| 62 | +} | |
| 63 | + | |
| 64 | +func FormatLog(f interface{}, v ...interface{}) string { | |
| 65 | + return formatLog(f, v) | |
| 66 | +} | |
| 67 | + | |
| 68 | +func formatLog(f interface{}, v ...interface{}) string { | |
| 69 | + var msg string | |
| 70 | + switch f := f.(type) { | |
| 71 | + case string: | |
| 72 | + msg = f | |
| 73 | + if len(v) == 0 { | |
| 74 | + return msg | |
| 75 | + } | |
| 76 | + if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") { | |
| 77 | + //format string | |
| 78 | + } else { | |
| 79 | + //do not contain format char | |
| 80 | + msg += strings.Repeat(" %v", len(v)) | |
| 81 | + } | |
| 82 | + default: | |
| 83 | + msg = fmt.Sprint(f) | |
| 84 | + if len(v) == 0 { | |
| 85 | + return msg | |
| 86 | + } | |
| 87 | + msg += strings.Repeat(" %v", len(v)) | |
| 88 | + } | |
| 89 | + return fmt.Sprintf(msg, v...) | |
| 90 | +} | |
| 91 | + | |
| 92 | +// 写日志到阿里云 | |
| 93 | +func Writelog(s string, topic string, ip string, config map[string]string) (err error) { | |
| 94 | + | |
| 95 | + if LXAliDefaultConfig.On != "1" { | |
| 96 | + return | |
| 97 | + } | |
| 98 | + | |
| 99 | + if LXAliDefaultConfig.Env != "" { | |
| 100 | + config["env"] = LXAliDefaultConfig.Env | |
| 101 | + } | |
| 102 | + | |
| 103 | + log := producer.GenerateLog(uint32(time.Now().Unix()), config) | |
| 104 | + | |
| 105 | + err = LXAliProducer.SendLog(LXAliDefaultConfig.Project, s, topic, ip, log) | |
| 106 | + | |
| 107 | + if err != nil { | |
| 108 | + return | |
| 109 | + } | |
| 110 | + | |
| 111 | + return | |
| 112 | + | |
| 113 | +} | |
| 114 | + | |
| 115 | +// 获取正在运行的函数名 | |
| 116 | +func runFuncName(l int) (string, string, int) { | |
| 117 | + | |
| 118 | + pc, file, line, _ := runtime.Caller(l) | |
| 119 | + | |
| 120 | + name := runtime.FuncForPC(pc).Name() | |
| 121 | + | |
| 122 | + split := strings.Split(name, ".") | |
| 123 | + | |
| 124 | + funname := split[len(split)-1] | |
| 125 | + | |
| 126 | + return funname, file, line | |
| 127 | +} | |
| 128 | + | |
| 129 | +// ErrorCode 错误日志 | |
| 130 | +func ErrorCode(code interface{}, v ...interface{}) { | |
| 131 | + | |
| 132 | + funname, file, line := runFuncName(3) | |
| 133 | + | |
| 134 | + logd := make(map[string]string) | |
| 135 | + | |
| 136 | + logd["fun"] = funname | |
| 137 | + | |
| 138 | + logd["file"] = file | |
| 139 | + | |
| 140 | + logd["app"] = LXAliDefaultConfig.AppNaame | |
| 141 | + | |
| 142 | + logd["line"] = fmt.Sprintf("%d", line) | |
| 143 | + | |
| 144 | + logd["msg"] = formatLog(code, v) | |
| 145 | + | |
| 146 | + logd["time"] = lconv.Int64ToStr(ltime.UninxTime()) | |
| 147 | + | |
| 148 | + logs.Error("file::", file, ",line::", line, ",fun::", funname, "[", logd["msg"], "],time::", logd["time"]) | |
| 149 | + | |
| 150 | + if LXAliDefaultConfig.TableError != "" { | |
| 151 | + go Writelog(LXAliDefaultConfig.TableError, funname, "127.0.0.1", logd) | |
| 152 | + } | |
| 153 | + | |
| 154 | +} | |
| 155 | + | |
| 156 | +// 错误日志 | |
| 157 | +func Errors(f interface{}, v ...interface{}) { | |
| 158 | + | |
| 159 | + funname, file, line := runFuncName(2) | |
| 160 | + | |
| 161 | + logd := make(map[string]string) | |
| 162 | + | |
| 163 | + logd["fun"] = funname | |
| 164 | + | |
| 165 | + logd["file"] = file | |
| 166 | + | |
| 167 | + logd["app"] = LXAliDefaultConfig.AppNaame | |
| 168 | + | |
| 169 | + logd["line"] = fmt.Sprintf("%d", line) | |
| 170 | + | |
| 171 | + logd["msg"] = formatLog(f, v) | |
| 172 | + | |
| 173 | + logd["time"] = lconv.Int64ToStr(ltime.UninxTime()) | |
| 174 | + | |
| 175 | + logs.Error("file::", file, ",line::", line, ",fun::", funname, "[", logd["msg"], "],time::", logd["time"]) | |
| 176 | + | |
| 177 | + if LXAliDefaultConfig.TableError != "" { | |
| 178 | + go Writelog(LXAliDefaultConfig.TableError, funname, "127.0.0.1", logd) | |
| 179 | + } | |
| 180 | + | |
| 181 | +} | |
| 182 | + | |
| 183 | +// 调试日志 | |
| 184 | +func Debug(f interface{}, v ...interface{}) { | |
| 185 | + | |
| 186 | + funname, file, line := runFuncName(2) | |
| 187 | + | |
| 188 | + logd := make(map[string]string) | |
| 189 | + | |
| 190 | + logd["fun"] = funname | |
| 191 | + | |
| 192 | + logd["file"] = file | |
| 193 | + | |
| 194 | + logd["app"] = LXAliDefaultConfig.AppNaame | |
| 195 | + | |
| 196 | + logd["line"] = fmt.Sprintf("%d", line) | |
| 197 | + | |
| 198 | + logd["msg"] = formatLog(f, v) | |
| 199 | + | |
| 200 | + logd["time"] = lconv.Int64ToStr(ltime.UninxTime()) | |
| 201 | + | |
| 202 | + logs.Debug("file::", file, ",line::", line, ",fun::", funname, "[", logd["msg"], "],time::", logd["time"]) | |
| 203 | + | |
| 204 | + if LXAliDefaultConfig.Debug == "1" && LXAliDefaultConfig.TableDebug != "" { | |
| 205 | + go Writelog(LXAliDefaultConfig.TableDebug, funname, "127.0.0.1", logd) | |
| 206 | + } | |
| 207 | +} | |
| 208 | + | |
| 209 | +type LogParams struct { | |
| 210 | + Project string | |
| 211 | + PowerSql bool | |
| 212 | +} | |
| 213 | + | |
| 214 | +// 查询日志 | |
| 215 | +func GetLog(logname, sql string, starttime, endtime int64, nums int64, p ...LogParams) (lst []map[string]string, err error) { | |
| 216 | + | |
| 217 | + var dproject = LXAliDefaultConfig.Project | |
| 218 | + | |
| 219 | + if len(p) > 0 { | |
| 220 | + if p[0].Project != "" { | |
| 221 | + dproject = p[0].Project | |
| 222 | + } | |
| 223 | + } | |
| 224 | + | |
| 225 | + // 创建日志服务Client。 | |
| 226 | + client := sls.CreateNormalInterface(LXAliDefaultConfig.Endpoint, LXAliDefaultConfig.AccessKeyId, LXAliDefaultConfig.AccessKeySecret, "") | |
| 227 | + | |
| 228 | + resp, err := client.GetLogs(dproject, logname, "", starttime, endtime, sql, nums, 0, true) | |
| 229 | + if err != nil { | |
| 230 | + return | |
| 231 | + } | |
| 232 | + | |
| 233 | + logs := resp.Logs | |
| 234 | + for i := range logs { | |
| 235 | + var item = make(map[string]string) | |
| 236 | + for k, v := range logs[i] { | |
| 237 | + item[k] = v | |
| 238 | + } | |
| 239 | + lst = append(lst, item) | |
| 240 | + } | |
| 241 | + | |
| 242 | + return | |
| 243 | +} | |
| 244 | + | |
| 245 | +func GetLog1(logname, sql string, starttime, endtime int64, nums int64, pas int64) (lst []map[string]string, err error) { | |
| 246 | + | |
| 247 | + // 创建日志服务Client。 | |
| 248 | + client := sls.CreateNormalInterface(LXAliDefaultConfig.Endpoint, LXAliDefaultConfig.AccessKeyId, LXAliDefaultConfig.AccessKeySecret, "") | |
| 249 | + | |
| 250 | + resp, err := client.GetLogs(LXAliDefaultConfig.Project, logname, "", starttime, endtime, sql, nums, pas*nums, true) | |
| 251 | + if err != nil { | |
| 252 | + return | |
| 253 | + } | |
| 254 | + | |
| 255 | + logs := resp.Logs | |
| 256 | + for i := range logs { | |
| 257 | + var item = make(map[string]string) | |
| 258 | + for k, v := range logs[i] { | |
| 259 | + item[k] = v | |
| 260 | + } | |
| 261 | + lst = append(lst, item) | |
| 262 | + } | |
| 263 | + | |
| 264 | + return | |
| 265 | +} | |
| 266 | + | |
| 267 | +func GetLogV2(logname, sql string, starttime, endtime int64, nums int64, pas int64) (lst []map[string]string, err error) { | |
| 268 | + return GetLog1(logname, sql, starttime, endtime, nums, pas) | |
| 269 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | +package lxarray | |
| 2 | + | |
| 3 | +// InArray 判断字符串在数组内 | |
| 4 | +func InArray(s string, d []string) bool { | |
| 5 | + for _, v := range d { | |
| 6 | + if s == v { | |
| 7 | + return true | |
| 8 | + } | |
| 9 | + } | |
| 10 | + return false | |
| 11 | +} | |
| 12 | + | |
| 13 | +// SplitArray sources源数组,num拆分份数,size每份的大小 | |
| 14 | +func SplitArray(sources []string, num, pageSize int64) [][]string { | |
| 15 | + max := int64(len(sources)) | |
| 16 | + if max < num { | |
| 17 | + return nil | |
| 18 | + } | |
| 19 | + var segmens = make([][]string, 0) | |
| 20 | + quantity := pageSize | |
| 21 | + end := int64(0) | |
| 22 | + for i := int64(1); i <= num; i++ { | |
| 23 | + qu := i * quantity | |
| 24 | + if i != num { | |
| 25 | + segmens = append(segmens, sources[i-1+end:qu]) | |
| 26 | + } else { | |
| 27 | + segmens = append(segmens, sources[i-1+end:]) | |
| 28 | + } | |
| 29 | + end = qu - i | |
| 30 | + } | |
| 31 | + return segmens | |
| 32 | +} | |
| 33 | + | |
| 34 | +// SplitArrayCnt sourceslen源数组长度,pageSize页数据量 | |
| 35 | +func SplitArrayCnt(sourceslen, pageSize int) int { | |
| 36 | + if sourceslen < pageSize { | |
| 37 | + return 1 | |
| 38 | + } | |
| 39 | + s := sourceslen / pageSize | |
| 40 | + y := sourceslen % pageSize | |
| 41 | + if y > 0 { | |
| 42 | + return s + 1 | |
| 43 | + } else { | |
| 44 | + return s | |
| 45 | + } | |
| 46 | +} | |
| 47 | + | |
| 48 | +// DeleteRepeatString 数组去重 | |
| 49 | +func DeleteRepeatString(arr []string) []string { | |
| 50 | + // 创建一个新的切片,用于存储去重后的元素 | |
| 51 | + result := make([]string, 0, len(arr)) | |
| 52 | + // 遍历原始数组 | |
| 53 | + for _, item := range arr { | |
| 54 | + // 如果元素不在结果切片中,则将其添加到结果切片中 | |
| 55 | + if !containsString(result, item) { | |
| 56 | + result = append(result, item) | |
| 57 | + } | |
| 58 | + } | |
| 59 | + return result | |
| 60 | +} | |
| 61 | + | |
| 62 | +func containsString(arr []string, se string) bool { | |
| 63 | + // 遍历结果切片 | |
| 64 | + for _, n := range arr { | |
| 65 | + // 如果找到匹配的元素,则返回 true | |
| 66 | + if n == se { | |
| 67 | + return true | |
| 68 | + } | |
| 69 | + } | |
| 70 | + return false | |
| 71 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | +package lxconv | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "crypto/md5" | |
| 5 | + "crypto/sha1" | |
| 6 | + "encoding/hex" | |
| 7 | + "fmt" | |
| 8 | +) | |
| 9 | + | |
| 10 | +// EncryMD5 MD5 字符串 | |
| 11 | +func EncryMD5(text string) string { | |
| 12 | + ctx := md5.New() | |
| 13 | + ctx.Write([]byte(text)) | |
| 14 | + return hex.EncodeToString(ctx.Sum(nil)) | |
| 15 | +} | |
| 16 | + | |
| 17 | +// EncrySHA1 SHA1 字符串 | |
| 18 | +func EncrySHA1(text string) string { | |
| 19 | + ctx := sha1.New() | |
| 20 | + ctx.Write([]byte(text)) | |
| 21 | + return fmt.Sprintf("%x", ctx.Sum(nil)) | |
| 22 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,245 @@ |
| 1 | +package lxconv | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "encoding/json" | |
| 5 | + "fmt" | |
| 6 | + "strconv" | |
| 7 | + "strings" | |
| 8 | +) | |
| 9 | + | |
| 10 | +// IntToStr 数字转换字符串 | |
| 11 | +func IntToStr(i int) string { | |
| 12 | + return strconv.Itoa(i) | |
| 13 | +} | |
| 14 | + | |
| 15 | +// Int64ToStr 64位数字转换字符串 | |
| 16 | +func Int64ToStr(i int64) string { | |
| 17 | + return strconv.FormatInt(i, 10) | |
| 18 | +} | |
| 19 | + | |
| 20 | +// StrToInt 字符串转换位int | |
| 21 | +func StrToInt(str string) int { | |
| 22 | + intnum, _ := strconv.Atoi(str) | |
| 23 | + return intnum | |
| 24 | +} | |
| 25 | + | |
| 26 | +// StrToInt64 字符串转换位int64 | |
| 27 | +func StrToInt64(str string) int64 { | |
| 28 | + intnum, _ := strconv.ParseInt(str, 10, 64) | |
| 29 | + return intnum | |
| 30 | +} | |
| 31 | + | |
| 32 | +// StrToFloat64 字符串转换浮点数 | |
| 33 | +func StrToFloat64(str string, i int) float64 { | |
| 34 | + v2, _ := strconv.ParseFloat(str, i) | |
| 35 | + return v2 | |
| 36 | +} | |
| 37 | + | |
| 38 | +// ParseInt64 字符串转换位int64 | |
| 39 | +func ParseInt64(val interface{}) int64 { | |
| 40 | + | |
| 41 | + if val == nil { | |
| 42 | + return 0 | |
| 43 | + } | |
| 44 | + | |
| 45 | + switch ret := val.(type) { | |
| 46 | + case string: | |
| 47 | + return StrToInt64(ret) | |
| 48 | + case int8: | |
| 49 | + return int64(ret) | |
| 50 | + case uint8: | |
| 51 | + return int64(ret) | |
| 52 | + case int16: | |
| 53 | + return int64(ret) | |
| 54 | + case uint16: | |
| 55 | + return int64(ret) | |
| 56 | + case int: | |
| 57 | + return int64(ret) | |
| 58 | + case uint: | |
| 59 | + return int64(ret) | |
| 60 | + case int64: | |
| 61 | + return int64(ret) | |
| 62 | + case uint64: | |
| 63 | + return int64(ret) | |
| 64 | + case float32: | |
| 65 | + return int64(ret) | |
| 66 | + case float64: | |
| 67 | + return int64(ret) | |
| 68 | + } | |
| 69 | + | |
| 70 | + return 0 | |
| 71 | +} | |
| 72 | + | |
| 73 | +// ParseInt 字符串转换位int | |
| 74 | +func ParseInt(val interface{}) int { | |
| 75 | + | |
| 76 | + if val == nil { | |
| 77 | + return 0 | |
| 78 | + } | |
| 79 | + | |
| 80 | + switch ret := val.(type) { | |
| 81 | + case string: | |
| 82 | + return StrToInt(ret) | |
| 83 | + case int8: | |
| 84 | + return int(ret) | |
| 85 | + case uint8: | |
| 86 | + return int(ret) | |
| 87 | + case int16: | |
| 88 | + return int(ret) | |
| 89 | + case uint16: | |
| 90 | + return int(ret) | |
| 91 | + case int: | |
| 92 | + return int(ret) | |
| 93 | + case uint: | |
| 94 | + return int(ret) | |
| 95 | + case int64: | |
| 96 | + return int(ret) | |
| 97 | + case uint64: | |
| 98 | + return int(ret) | |
| 99 | + case float32: | |
| 100 | + return int(ret) | |
| 101 | + case float64: | |
| 102 | + return int(ret) | |
| 103 | + } | |
| 104 | + | |
| 105 | + return 0 | |
| 106 | +} | |
| 107 | + | |
| 108 | +// FloatTostr 浮点数转换int卡类型 | |
| 109 | +func FloatTostr(floatstr float64, i int) string { | |
| 110 | + return strconv.FormatFloat(floatstr, 'E', -1, i) | |
| 111 | +} | |
| 112 | + | |
| 113 | +// JsonEncode json转字符串 | |
| 114 | +func JsonEncode(data interface{}) string { | |
| 115 | + datastr, _ := json.Marshal(data) | |
| 116 | + return string(datastr) | |
| 117 | +} | |
| 118 | + | |
| 119 | +// ToInt 任意类型强转int | |
| 120 | +func ToInt(a interface{}) int { | |
| 121 | + | |
| 122 | + ai := 0 | |
| 123 | + | |
| 124 | + switch a := a.(type) { | |
| 125 | + case float64: | |
| 126 | + ai = int(a) | |
| 127 | + case float32: | |
| 128 | + ai = int(a) | |
| 129 | + case int: | |
| 130 | + ai = a | |
| 131 | + case int32: | |
| 132 | + ai = int(a) | |
| 133 | + case int64: | |
| 134 | + ai = int(a) | |
| 135 | + case string: | |
| 136 | + ai = StrToInt(a) | |
| 137 | + | |
| 138 | + default: | |
| 139 | + | |
| 140 | + } | |
| 141 | + | |
| 142 | + return ai | |
| 143 | +} | |
| 144 | + | |
| 145 | +// ToInt64 任意类型强转int64 | |
| 146 | +func ToInt64(a interface{}) int64 { | |
| 147 | + | |
| 148 | + var ai int64 | |
| 149 | + | |
| 150 | + switch a := a.(type) { | |
| 151 | + case float64: | |
| 152 | + ai = int64(a) | |
| 153 | + case float32: | |
| 154 | + ai = int64(a) | |
| 155 | + case int: | |
| 156 | + ai = int64(a) | |
| 157 | + case int32: | |
| 158 | + ai = int64(a) | |
| 159 | + case int64: | |
| 160 | + ai = a | |
| 161 | + case string: | |
| 162 | + ai = StrToInt64(a) | |
| 163 | + | |
| 164 | + default: | |
| 165 | + | |
| 166 | + } | |
| 167 | + | |
| 168 | + return ai | |
| 169 | +} | |
| 170 | + | |
| 171 | +// ToFloat64 任意类型强转float64 | |
| 172 | +func ToFloat64(a interface{}) float64 { | |
| 173 | + | |
| 174 | + var ai float64 | |
| 175 | + | |
| 176 | + switch a := a.(type) { | |
| 177 | + case float64: | |
| 178 | + ai = a | |
| 179 | + case float32: | |
| 180 | + ai = float64(a) | |
| 181 | + case int: | |
| 182 | + ai = float64(a) | |
| 183 | + case int32: | |
| 184 | + ai = float64(a) | |
| 185 | + case int64: | |
| 186 | + ai = float64(a) | |
| 187 | + case string: | |
| 188 | + ai = StrToFloat64(a, 64) | |
| 189 | + | |
| 190 | + default: | |
| 191 | + | |
| 192 | + } | |
| 193 | + | |
| 194 | + return ai | |
| 195 | +} | |
| 196 | + | |
| 197 | +// ToString 任意类型强转字符串 | |
| 198 | +func ToString(a interface{}) string { | |
| 199 | + | |
| 200 | + var ai string | |
| 201 | + | |
| 202 | + switch a := a.(type) { | |
| 203 | + case float64: | |
| 204 | + ai = strconv.FormatFloat(a, 'E', -1, 64) | |
| 205 | + case float32: | |
| 206 | + ai = strconv.FormatFloat(float64(a), 'E', -1, 64) | |
| 207 | + case int: | |
| 208 | + ai = fmt.Sprintf("%d", a) | |
| 209 | + case int32: | |
| 210 | + ai = fmt.Sprintf("%d", a) | |
| 211 | + case int64: | |
| 212 | + ai = fmt.Sprintf("%d", a) | |
| 213 | + case string: | |
| 214 | + ai = fmt.Sprintf("%s", a) | |
| 215 | + default: | |
| 216 | + ai = fmt.Sprintf("%v", a) | |
| 217 | + | |
| 218 | + } | |
| 219 | + | |
| 220 | + return ai | |
| 221 | +} | |
| 222 | + | |
| 223 | +func InterfaceToStr(v interface{}) string { | |
| 224 | + str := "" | |
| 225 | + switch v.(type) { | |
| 226 | + case string: | |
| 227 | + str = v.(string) | |
| 228 | + default: | |
| 229 | + jsonbyte, _ := json.Marshal(v) | |
| 230 | + str = string(jsonbyte) | |
| 231 | + } | |
| 232 | + return str | |
| 233 | +} | |
| 234 | + | |
| 235 | +// ToBool 转换 bool类型 | |
| 236 | +func ToBool(a interface{}) bool { | |
| 237 | + | |
| 238 | + s := ToString(a) | |
| 239 | + if s == "1" || strings.ToLower(s) == "true" { | |
| 240 | + return true | |
| 241 | + } | |
| 242 | + | |
| 243 | + return false | |
| 244 | + | |
| 245 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | +package lxconv | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "net/url" | |
| 5 | + "strings" | |
| 6 | +) | |
| 7 | + | |
| 8 | +func UrlEncode(str string) string { | |
| 9 | + encodeurl := url.QueryEscape(str) | |
| 10 | + encodeurl = strings.ReplaceAll(encodeurl, "\"", "%22") | |
| 11 | + return encodeurl | |
| 12 | +} | |
| 13 | + | |
| 14 | +func UrlDecode(str string) string { | |
| 15 | + decodeurl, _ := url.QueryUnescape(str) | |
| 16 | + return decodeurl | |
| 17 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,267 @@ |
| 1 | +package lxlimit | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "apigame/lx-util/lxconv" | |
| 5 | + "encoding/json" | |
| 6 | + "fmt" | |
| 7 | + "github.com/astaxie/beego/logs" | |
| 8 | + redigo "github.com/garyburd/redigo/redis" | |
| 9 | + "hash/fnv" | |
| 10 | + "strconv" | |
| 11 | + "strings" | |
| 12 | +) | |
| 13 | + | |
| 14 | +// api限流 | |
| 15 | +// 创建时间:2023/11/24 11:23 | |
| 16 | +// 创建人:lixu | |
| 17 | + | |
| 18 | +type LimitConfig struct { | |
| 19 | + Redis MapRedisConfig `json:"redis"` | |
| 20 | + Func MFuncConfig `json:"func"` | |
| 21 | +} | |
| 22 | + | |
| 23 | +type MFuncItem struct { | |
| 24 | + Name string `json:"name"` | |
| 25 | + Times int `json:"times"` // 每几秒 | |
| 26 | + Nums int `json:"nums"` // 限制多少次 | |
| 27 | +} | |
| 28 | + | |
| 29 | +type MFuncConfig struct { | |
| 30 | + FunName string `json:"fun_name"` | |
| 31 | + Open bool `json:"open"` | |
| 32 | + Ip MFuncItem `json:"ip"` | |
| 33 | + Kernel MFuncItem `json:"kernel"` | |
| 34 | + BodyBy []byte `json:"bodyBy"` | |
| 35 | + Url string `json:"url"` | |
| 36 | + Params map[string]string `json:"params"` | |
| 37 | + DelGameIDS []string `json:"delGameIDS"` // 删除某个游戏 | |
| 38 | + Member MFuncItem `json:"member"` | |
| 39 | +} | |
| 40 | + | |
| 41 | +type LimitVar struct { | |
| 42 | + RedisConfig MapRedisConfig | |
| 43 | + RedisPool *redigo.Pool | |
| 44 | + FuncConfig MFuncConfig | |
| 45 | +} | |
| 46 | + | |
| 47 | +var LXLIMITCL LimitVar | |
| 48 | + | |
| 49 | +// InitDefault 初始化 | |
| 50 | +func InitDefault(cfg LimitConfig) (err error) { | |
| 51 | + | |
| 52 | + err = initRedis(cfg.Redis) | |
| 53 | + if err != nil { | |
| 54 | + logs.Error("InitDefault", "initRedis error::", err) | |
| 55 | + return | |
| 56 | + } | |
| 57 | + | |
| 58 | + LXLIMITCL.FuncConfig = cfg.Func | |
| 59 | + | |
| 60 | + return | |
| 61 | +} | |
| 62 | + | |
| 63 | +// CheckLimit 检查是否超 出限制 | |
| 64 | +func CheckLimit(cfg MFuncConfig) (gameid, tp string) { | |
| 65 | + var ( | |
| 66 | + times = 0 | |
| 67 | + postdata map[string]interface{} | |
| 68 | + ) | |
| 69 | + | |
| 70 | + postdata = make(map[string]interface{}) | |
| 71 | + | |
| 72 | + if len(cfg.BodyBy) > 0 { | |
| 73 | + _ = json.Unmarshal([]byte(cfg.BodyBy), &postdata) | |
| 74 | + if postdata["gameid"] != nil { | |
| 75 | + gameid = lxconv.ToString(postdata["gameid"]) | |
| 76 | + } | |
| 77 | + } | |
| 78 | + | |
| 79 | + if !LXLIMITCL.FuncConfig.Open || cfg.FunName == "" { | |
| 80 | + return | |
| 81 | + } | |
| 82 | + | |
| 83 | + if len(cfg.DelGameIDS) > 0 { | |
| 84 | + | |
| 85 | + if cfg.Url != "" { | |
| 86 | + for _, gameid := range cfg.DelGameIDS { | |
| 87 | + if strings.Contains(cfg.Url, gameid) { | |
| 88 | + tp = "gameid" | |
| 89 | + break | |
| 90 | + } | |
| 91 | + } | |
| 92 | + if tp != "" { | |
| 93 | + return | |
| 94 | + } | |
| 95 | + } | |
| 96 | + | |
| 97 | + if postdata["gameid"] != nil { | |
| 98 | + pgameid := lxconv.ToString(postdata["gameid"]) | |
| 99 | + for _, gid := range cfg.DelGameIDS { | |
| 100 | + if pgameid == gid { | |
| 101 | + tp = "gameid" | |
| 102 | + break | |
| 103 | + } | |
| 104 | + } | |
| 105 | + if tp != "" { | |
| 106 | + return | |
| 107 | + } | |
| 108 | + } | |
| 109 | + } | |
| 110 | + | |
| 111 | + if cfg.Ip.Name != "" { | |
| 112 | + if cfg.Ip.Times == 0 { | |
| 113 | + cfg.Ip.Times = LXLIMITCL.FuncConfig.Ip.Times | |
| 114 | + } | |
| 115 | + if cfg.Ip.Nums == 0 { | |
| 116 | + cfg.Ip.Nums = LXLIMITCL.FuncConfig.Ip.Nums | |
| 117 | + } | |
| 118 | + } | |
| 119 | + | |
| 120 | + if cfg.Kernel.Name != "" { | |
| 121 | + if cfg.Kernel.Times == 0 { | |
| 122 | + cfg.Kernel.Times = LXLIMITCL.FuncConfig.Kernel.Times | |
| 123 | + } | |
| 124 | + if cfg.Kernel.Nums == 0 { | |
| 125 | + cfg.Kernel.Nums = LXLIMITCL.FuncConfig.Kernel.Nums | |
| 126 | + } | |
| 127 | + } | |
| 128 | + | |
| 129 | + if cfg.Member.Times == 0 { | |
| 130 | + cfg.Member.Times = LXLIMITCL.FuncConfig.Member.Times | |
| 131 | + } | |
| 132 | + if cfg.Member.Nums == 0 { | |
| 133 | + cfg.Member.Nums = LXLIMITCL.FuncConfig.Member.Nums | |
| 134 | + } | |
| 135 | + | |
| 136 | + _rds := LXredis{} | |
| 137 | + | |
| 138 | + ipif := (cfg.Ip.Times > 0 && cfg.Ip.Name != "") | |
| 139 | + | |
| 140 | + if ipif { | |
| 141 | + _rds.Name = "ip::" + cfg.Ip.Name | |
| 142 | + _rds.Name += getRedisKey(cfg.FunName, cfg.Ip.Name) | |
| 143 | + // ip | |
| 144 | + if isx, _ := _rds.IsExist(); isx { | |
| 145 | + gstr, _ := _rds.GET() | |
| 146 | + if gstr != "" { | |
| 147 | + times, _ = strconv.Atoi(gstr) | |
| 148 | + if times >= cfg.Ip.Nums { | |
| 149 | + tp = "ip" | |
| 150 | + return | |
| 151 | + } | |
| 152 | + } | |
| 153 | + _rds.INCR() | |
| 154 | + //logs.Error("ip:::11::", lxconv.JsonEncode(cfg.Ip)) | |
| 155 | + } else { | |
| 156 | + //logs.Error("ip:::22::", lxconv.JsonEncode(cfg.Ip)) | |
| 157 | + _rds.Val = "1" | |
| 158 | + _rds.setTime(cfg.Ip.Times) | |
| 159 | + } | |
| 160 | + | |
| 161 | + ex, _ := _rds.TTL() | |
| 162 | + if ex < 0 { | |
| 163 | + _rds.EXPIRE(cfg.Ip.Times) | |
| 164 | + } | |
| 165 | + | |
| 166 | + } | |
| 167 | + | |
| 168 | + if ipif && cfg.Kernel.Times > 0 && cfg.Kernel.Name != "" { | |
| 169 | + _rds.Name = "kernel::" + cfg.Ip.Name | |
| 170 | + _rds.Name += getRedisKey(cfg.FunName, cfg.Ip.Name, cfg.Kernel.Name) | |
| 171 | + // ip | |
| 172 | + if isx, _ := _rds.IsExist(); isx { | |
| 173 | + gstr, _ := _rds.GET() | |
| 174 | + if gstr != "" { | |
| 175 | + times, _ = strconv.Atoi(gstr) | |
| 176 | + if times >= cfg.Kernel.Nums { | |
| 177 | + tp = "kernel" | |
| 178 | + return | |
| 179 | + } | |
| 180 | + } | |
| 181 | + _rds.INCR() | |
| 182 | + //logs.Error("Kernel:::11::", lxconv.JsonEncode(cfg.Kernel)) | |
| 183 | + } else { | |
| 184 | + _rds.Val = "1" | |
| 185 | + _rds.setTime(cfg.Kernel.Times) | |
| 186 | + //logs.Error("Kernel:::22::", lxconv.JsonEncode(cfg.Kernel)) | |
| 187 | + } | |
| 188 | + | |
| 189 | + ex, _ := _rds.TTL() | |
| 190 | + if ex < 0 { | |
| 191 | + _rds.EXPIRE(cfg.Kernel.Times) | |
| 192 | + } | |
| 193 | + | |
| 194 | + } | |
| 195 | + | |
| 196 | + var uid string | |
| 197 | + | |
| 198 | + if cfg.Member.Name != "" { | |
| 199 | + if strings.Contains(cfg.Member.Name, "{gameid}") && postdata["gameid"] != nil { | |
| 200 | + gameid = lxconv.InterfaceToStr(postdata["gameid"]) | |
| 201 | + cfg.Member.Name = strings.Replace(cfg.Member.Name, "{gameid}", gameid, -1) | |
| 202 | + } | |
| 203 | + | |
| 204 | + if strings.Contains(cfg.Member.Name, "{uid}") && postdata["uid"] != nil { | |
| 205 | + uid = lxconv.InterfaceToStr(postdata["uid"]) | |
| 206 | + cfg.Member.Name = strings.Replace(cfg.Member.Name, "{uid}", uid, -1) | |
| 207 | + } | |
| 208 | + } | |
| 209 | + | |
| 210 | + if cfg.Member.Times > 0 && cfg.Member.Name != "" { | |
| 211 | + _rds.Name = "member::" + cfg.Member.Name | |
| 212 | + _rds.Name += getRedisKey(cfg.FunName) | |
| 213 | + // ip | |
| 214 | + if isx, _ := _rds.IsExist(); isx { | |
| 215 | + gstr, _ := _rds.GET() | |
| 216 | + if gstr != "" { | |
| 217 | + times, _ = strconv.Atoi(gstr) | |
| 218 | + if times >= cfg.Member.Nums { | |
| 219 | + tp = "member" | |
| 220 | + return | |
| 221 | + } | |
| 222 | + } | |
| 223 | + _rds.INCR() | |
| 224 | + //logs.Error("Member:::11::", lxconv.JsonEncode(cfg.Member)) | |
| 225 | + } else { | |
| 226 | + _rds.Val = "1" | |
| 227 | + _rds.setTime(cfg.Member.Times) | |
| 228 | + //logs.Error("Member:::22::", lxconv.JsonEncode(cfg.Member)) | |
| 229 | + } | |
| 230 | + | |
| 231 | + ex, _ := _rds.TTL() | |
| 232 | + if ex < 0 { | |
| 233 | + _rds.EXPIRE(cfg.Member.Times) | |
| 234 | + } | |
| 235 | + | |
| 236 | + } | |
| 237 | + | |
| 238 | + return | |
| 239 | +} | |
| 240 | + | |
| 241 | +func hashMod(key string, modulus int) int { | |
| 242 | + // 使用FNV哈希算法计算哈希值 | |
| 243 | + hash := fnv.New32a() | |
| 244 | + hash.Write([]byte(key)) | |
| 245 | + hashValue := hash.Sum32() | |
| 246 | + | |
| 247 | + // 对哈希值取模得到结果 | |
| 248 | + result := int(hashValue % uint32(modulus)) | |
| 249 | + return result | |
| 250 | +} | |
| 251 | + | |
| 252 | +func getRedisKey(ccs ...interface{}) (k string) { | |
| 253 | + | |
| 254 | + var pms string | |
| 255 | + | |
| 256 | + for _, cc := range ccs { | |
| 257 | + pms += lxconv.InterfaceToStr(cc) | |
| 258 | + } | |
| 259 | + | |
| 260 | + mds := hashMod(pms, 100000) | |
| 261 | + | |
| 262 | + k = "::" + lxconv.EncryMD5(pms) | |
| 263 | + | |
| 264 | + k += fmt.Sprintf("%d", mds) | |
| 265 | + | |
| 266 | + return | |
| 267 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,212 @@ |
| 1 | +package lxlimit | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "fmt" | |
| 5 | + redigo "github.com/garyburd/redigo/redis" | |
| 6 | +) | |
| 7 | + | |
| 8 | +// redis | |
| 9 | +// 创建时间:2023/11/24 11:25 | |
| 10 | +// 创建人:lixu | |
| 11 | + | |
| 12 | +type MapRedisConfig struct { | |
| 13 | + Host string `json:"host"` | |
| 14 | + Port string `json:"port"` | |
| 15 | + Pwd string `json:"pwd"` | |
| 16 | + Db string `json:"Db"` | |
| 17 | + Prefix string `json:"prefix"` | |
| 18 | +} | |
| 19 | + | |
| 20 | +func getRedis() redigo.Conn { | |
| 21 | + return LXLIMITCL.RedisPool.Get() | |
| 22 | +} | |
| 23 | + | |
| 24 | +type LXredis struct { | |
| 25 | + Name string `json:"name"` | |
| 26 | + Val string `json:"val"` | |
| 27 | + Db string `json:"db"` | |
| 28 | + Prefix string `json:"prefix"` | |
| 29 | +} | |
| 30 | + | |
| 31 | +// initRedis 初始化Redis | |
| 32 | +func initRedis(config MapRedisConfig) (err error) { | |
| 33 | + | |
| 34 | + LXLIMITCL.RedisConfig = config | |
| 35 | + | |
| 36 | + pool_size := 20 | |
| 37 | + | |
| 38 | + LXLIMITCL.RedisPool = redigo.NewPool(func() (redigo.Conn, error) { | |
| 39 | + c, err := redigo.Dial("tcp", fmt.Sprintf("%s:%s", LXLIMITCL.RedisConfig.Host, LXLIMITCL.RedisConfig.Port)) | |
| 40 | + if err != nil { | |
| 41 | + return nil, err | |
| 42 | + } | |
| 43 | + if _, err := c.Do("AUTH", LXLIMITCL.RedisConfig.Pwd); err != nil { | |
| 44 | + c.Close() | |
| 45 | + return nil, err | |
| 46 | + } | |
| 47 | + if _, err := c.Do("SELECT", LXLIMITCL.RedisConfig.Db); err != nil { | |
| 48 | + c.Close() | |
| 49 | + return nil, err | |
| 50 | + } | |
| 51 | + | |
| 52 | + return c, nil | |
| 53 | + }, pool_size) | |
| 54 | + | |
| 55 | + return | |
| 56 | +} | |
| 57 | + | |
| 58 | +// SetTime 设置redis字符串 加过期时间 | |
| 59 | +func (con *LXredis) setTime(times int) (err error) { | |
| 60 | + | |
| 61 | + var nname string | |
| 62 | + | |
| 63 | + if con.Prefix != "" { | |
| 64 | + nname = con.Prefix + con.Name | |
| 65 | + } else { | |
| 66 | + nname = LXLIMITCL.RedisConfig.Prefix + con.Name | |
| 67 | + } | |
| 68 | + | |
| 69 | + redis := getRedis() | |
| 70 | + | |
| 71 | + defer redis.Close() | |
| 72 | + | |
| 73 | + if con.Db != "" { | |
| 74 | + if _, err = redis.Do("SELECT", con.Db); err != nil { | |
| 75 | + return | |
| 76 | + } | |
| 77 | + } | |
| 78 | + | |
| 79 | + _, err = redis.Do("set", nname, con.Val, "EX", times) | |
| 80 | + | |
| 81 | + return | |
| 82 | +} | |
| 83 | + | |
| 84 | +// GET 获取redis | |
| 85 | +func (con *LXredis) GET() (gstr string, err error) { | |
| 86 | + | |
| 87 | + var nname string | |
| 88 | + | |
| 89 | + if con.Prefix != "" { | |
| 90 | + nname = con.Prefix + con.Name | |
| 91 | + } else { | |
| 92 | + nname = LXLIMITCL.RedisConfig.Prefix + con.Name | |
| 93 | + } | |
| 94 | + | |
| 95 | + redis := getRedis() | |
| 96 | + | |
| 97 | + defer redis.Close() | |
| 98 | + | |
| 99 | + if con.Db != "" { | |
| 100 | + if _, err = redis.Do("SELECT", con.Db); err != nil { | |
| 101 | + return | |
| 102 | + } | |
| 103 | + | |
| 104 | + } | |
| 105 | + | |
| 106 | + gstr, err = redigo.String(redis.Do("GET", nname)) | |
| 107 | + | |
| 108 | + return | |
| 109 | +} | |
| 110 | + | |
| 111 | +// IsExist 判断key是否存在 | |
| 112 | +func (con *LXredis) IsExist() (isexit bool, err error) { | |
| 113 | + | |
| 114 | + var nname string | |
| 115 | + | |
| 116 | + if con.Prefix != "" { | |
| 117 | + nname = con.Prefix + con.Name | |
| 118 | + } else { | |
| 119 | + nname = LXLIMITCL.RedisConfig.Prefix + con.Name | |
| 120 | + } | |
| 121 | + | |
| 122 | + redis := getRedis() | |
| 123 | + | |
| 124 | + defer redis.Close() | |
| 125 | + | |
| 126 | + if con.Db != "" { | |
| 127 | + if _, err = redis.Do("SELECT", con.Db); err != nil { | |
| 128 | + return | |
| 129 | + } | |
| 130 | + } | |
| 131 | + | |
| 132 | + isexit, err = redigo.Bool(redis.Do("EXISTS", nname)) | |
| 133 | + return | |
| 134 | +} | |
| 135 | + | |
| 136 | +// INCR 自增 | |
| 137 | +func (con *LXredis) INCR() (nums int64, err error) { | |
| 138 | + | |
| 139 | + var nname string | |
| 140 | + | |
| 141 | + if con.Prefix != "" { | |
| 142 | + nname = con.Prefix + con.Name | |
| 143 | + } else { | |
| 144 | + nname = LXLIMITCL.RedisConfig.Prefix + con.Name | |
| 145 | + } | |
| 146 | + | |
| 147 | + redis := getRedis() | |
| 148 | + | |
| 149 | + defer redis.Close() | |
| 150 | + | |
| 151 | + if con.Db != "" { | |
| 152 | + if _, err = redis.Do("SELECT", con.Db); err != nil { | |
| 153 | + return | |
| 154 | + } | |
| 155 | + } | |
| 156 | + | |
| 157 | + nums, err = redigo.Int64(redis.Do("INCR", nname)) | |
| 158 | + | |
| 159 | + return | |
| 160 | +} | |
| 161 | + | |
| 162 | +// TTL 查看过期时间 | |
| 163 | +func (con *LXredis) TTL() (ttl int, err error) { | |
| 164 | + | |
| 165 | + var nname string | |
| 166 | + | |
| 167 | + if con.Prefix != "" { | |
| 168 | + nname = con.Prefix + con.Name | |
| 169 | + } else { | |
| 170 | + nname = LXLIMITCL.RedisConfig.Prefix + con.Name | |
| 171 | + } | |
| 172 | + | |
| 173 | + redis := getRedis() | |
| 174 | + | |
| 175 | + defer redis.Close() | |
| 176 | + | |
| 177 | + if con.Db != "" { | |
| 178 | + if _, err = redis.Do("SELECT", con.Db); err != nil { | |
| 179 | + return | |
| 180 | + } | |
| 181 | + } | |
| 182 | + | |
| 183 | + ttl, err = redigo.Int(redis.Do("ttl", nname)) | |
| 184 | + | |
| 185 | + return | |
| 186 | +} | |
| 187 | + | |
| 188 | +// EXPIRE 设置过期时间 | |
| 189 | +func (con *LXredis) EXPIRE(times int) (err error) { | |
| 190 | + | |
| 191 | + var nname string | |
| 192 | + | |
| 193 | + if con.Prefix != "" { | |
| 194 | + nname = con.Prefix + con.Name | |
| 195 | + } else { | |
| 196 | + nname = LXLIMITCL.RedisConfig.Prefix + con.Name | |
| 197 | + } | |
| 198 | + | |
| 199 | + redis := getRedis() | |
| 200 | + | |
| 201 | + defer redis.Close() | |
| 202 | + | |
| 203 | + if con.Db != "" { | |
| 204 | + if _, err = redis.Do("SELECT", con.Db); err != nil { | |
| 205 | + return | |
| 206 | + } | |
| 207 | + } | |
| 208 | + | |
| 209 | + _, err = redigo.Int(redis.Do("EXPIRE", nname, times)) | |
| 210 | + | |
| 211 | + return | |
| 212 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,96 @@ |
| 1 | +package lxmysql | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "github.com/astaxie/beego/orm" | |
| 5 | + "io/ioutil" | |
| 6 | + "os" | |
| 7 | + "strings" | |
| 8 | +) | |
| 9 | + | |
| 10 | +type ExecSqlConfig struct { | |
| 11 | + Sql string //表名 | |
| 12 | + TableName string //表名 | |
| 13 | + DBIndex string //指定数据库 | |
| 14 | + Orm orm.Ormer //实例化 ORM | |
| 15 | + CreaeSql string //创建表的SQL语句 | |
| 16 | + CreatePath string //创建表的SQL文件路径 | |
| 17 | +} | |
| 18 | + | |
| 19 | +func ExecSql(config ExecSqlConfig) (err error) { | |
| 20 | + | |
| 21 | + var ( | |
| 22 | + tcount int | |
| 23 | + ) | |
| 24 | + | |
| 25 | + if config.Orm == nil { | |
| 26 | + config.Orm = orm.NewOrm() | |
| 27 | + } | |
| 28 | + | |
| 29 | + if config.DBIndex == "" { | |
| 30 | + config.DBIndex = "default" | |
| 31 | + } | |
| 32 | + | |
| 33 | +RSTART: | |
| 34 | + | |
| 35 | + config.Orm.Using(config.DBIndex) | |
| 36 | + | |
| 37 | + _, err = config.Orm.Raw(config.Sql).Exec() | |
| 38 | + if err != nil { | |
| 39 | + if b := strings.Contains(err.Error(), "doesn't exist"); b && (config.CreaeSql != "" || config.CreatePath != "") && tcount == 0 { | |
| 40 | + if config.CreaeSql == "" { | |
| 41 | + config.CreaeSql, _ = readFilesql(config.CreatePath, config.TableName) | |
| 42 | + } | |
| 43 | + | |
| 44 | + //表不存在 去创建 | |
| 45 | + err = CreateTable(config.CreaeSql, config.Orm, config.DBIndex) | |
| 46 | + if err != nil { | |
| 47 | + return | |
| 48 | + } | |
| 49 | + | |
| 50 | + tcount++ | |
| 51 | + //重新执行一次 | |
| 52 | + goto RSTART | |
| 53 | + } | |
| 54 | + | |
| 55 | + return | |
| 56 | + | |
| 57 | + } | |
| 58 | + | |
| 59 | + return | |
| 60 | +} | |
| 61 | + | |
| 62 | +func CreateTable(csql string, o orm.Ormer, dbindex string) (err error) { | |
| 63 | + | |
| 64 | + o.Using(dbindex) | |
| 65 | + | |
| 66 | + _, err = o.Raw(csql).Exec() | |
| 67 | + if err != nil { | |
| 68 | + return | |
| 69 | + } | |
| 70 | + | |
| 71 | + return | |
| 72 | +} | |
| 73 | + | |
| 74 | +func readFilesql(pth, tbname string) (sql string, err error) { | |
| 75 | + filePtr, err := os.Open(pth) | |
| 76 | + if err != nil { | |
| 77 | + return | |
| 78 | + } | |
| 79 | + defer filePtr.Close() | |
| 80 | + | |
| 81 | + by, err := ioutil.ReadAll(filePtr) | |
| 82 | + if err != nil { | |
| 83 | + return | |
| 84 | + } | |
| 85 | + | |
| 86 | + sql = strings.Replace(string(by), "{tablename}", tbname, -1) | |
| 87 | + | |
| 88 | + return | |
| 89 | +} | |
| 90 | + | |
| 91 | +func ReadFilesql(pth, tbname string) (sql string, err error) { | |
| 92 | + | |
| 93 | + pth += ".sql" | |
| 94 | + | |
| 95 | + return readFilesql(pth, tbname) | |
| 96 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | +package lxmysql | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "apigame/lx-util/lxconv" | |
| 5 | + lconv "github.com/lixu-any/go-tools/conv" | |
| 6 | +) | |
| 7 | + | |
| 8 | +// HashCode 计算 SQL 语句的哈希码 | |
| 9 | +func HashCode(sql string, args []interface{}) int { | |
| 10 | + hash := 17 | |
| 11 | + hash = hash*31 + len(sql) | |
| 12 | + for _, arg := range args { | |
| 13 | + hash = hash*31 + HashCodeOfArg(arg) | |
| 14 | + } | |
| 15 | + return hash | |
| 16 | +} | |
| 17 | + | |
| 18 | +// HashCodeOfArg 计算参数的哈希码 | |
| 19 | +func HashCodeOfArg(arg interface{}) int { | |
| 20 | + switch v := arg.(type) { | |
| 21 | + case int: | |
| 22 | + return v | |
| 23 | + case int8: | |
| 24 | + return int(v) | |
| 25 | + case int16: | |
| 26 | + return int(v) | |
| 27 | + case int32: | |
| 28 | + return int(v) | |
| 29 | + case int64: | |
| 30 | + return int(v) | |
| 31 | + case uint: | |
| 32 | + return int(v) | |
| 33 | + case uint8: | |
| 34 | + return int(v) | |
| 35 | + case uint16: | |
| 36 | + return int(v) | |
| 37 | + case uint32: | |
| 38 | + return int(v) | |
| 39 | + case uint64: | |
| 40 | + return int(v) | |
| 41 | + case float32: | |
| 42 | + return int(v) | |
| 43 | + case float64: | |
| 44 | + return int(v) | |
| 45 | + case string: | |
| 46 | + return len(v) | |
| 47 | + default: | |
| 48 | + return 0 | |
| 49 | + } | |
| 50 | +} | |
| 51 | + | |
| 52 | +// GenCacheKey 生成缓存名字 | |
| 53 | +func GenCacheKey(sql string, args []interface{}) string { | |
| 54 | + return lxconv.EncryMD5(sql + lconv.JsonEncode(args)) | |
| 55 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | +package lxmysql | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "github.com/astaxie/beego/orm" | |
| 5 | + _ "github.com/go-sql-driver/mysql" | |
| 6 | +) | |
| 7 | + | |
| 8 | +const ( | |
| 9 | + DEFAULT_EXPIRE = 300 //默认缓存5分钟 | |
| 10 | + DEFAULT_MAXCOUNT = 100 //默认最大条数 | |
| 11 | +) | |
| 12 | + | |
| 13 | +type MapMysqlConn struct { | |
| 14 | + Name string | |
| 15 | + SqlCon string | |
| 16 | +} | |
| 17 | + | |
| 18 | +// InitMysqls 初始化MySQL | |
| 19 | +func InitMysqls(conns []MapMysqlConn, cachedb string) (err error) { | |
| 20 | + | |
| 21 | + LXMYSQLCACHEDB = cachedb | |
| 22 | + | |
| 23 | + err = orm.RegisterDriver("mysql", orm.DRMySQL) | |
| 24 | + if err != nil { | |
| 25 | + return | |
| 26 | + } | |
| 27 | + | |
| 28 | + for _, v := range conns { | |
| 29 | + err = orm.RegisterDataBase(v.Name, "mysql", v.SqlCon) | |
| 30 | + if err != nil { | |
| 31 | + return | |
| 32 | + } | |
| 33 | + } | |
| 34 | + | |
| 35 | + return | |
| 36 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,132 @@ |
| 1 | +package lxmysql | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "apigame/lx-util/lxredis" | |
| 5 | + "encoding/json" | |
| 6 | + "github.com/astaxie/beego/orm" | |
| 7 | + lconv "github.com/lixu-any/go-tools/conv" | |
| 8 | + "strings" | |
| 9 | +) | |
| 10 | + | |
| 11 | +var LXMYSQLCACHEDB string //默认缓存数据库 | |
| 12 | + | |
| 13 | +type QueryCacheConfig struct { | |
| 14 | + SQL string //sql | |
| 15 | + DBIndex string //指定数据库 | |
| 16 | + CacheDB string //数据库缓存 Redis数据库索引 | |
| 17 | + CacheName string //缓存的名字 | |
| 18 | + Orm orm.Ormer //实例化 ORM | |
| 19 | + Exexpire int //缓存过期时间 -1不使用缓存 | |
| 20 | +} | |
| 21 | + | |
| 22 | +type QueryConfig struct { | |
| 23 | + SQL string //sql | |
| 24 | + DBIndex string //指定数据库 | |
| 25 | + Orm orm.Ormer //实例化 ORM | |
| 26 | +} | |
| 27 | + | |
| 28 | +// QueryWithCache 查询数据 | |
| 29 | +func QueryWithCache(config QueryCacheConfig, result interface{}, args ...interface{}) (err error) { | |
| 30 | + | |
| 31 | + var cacheKey string | |
| 32 | + | |
| 33 | + if len(config.CacheName) > 0 { | |
| 34 | + cacheKey = config.CacheName | |
| 35 | + } else { | |
| 36 | + cacheKey = "mysql::" + GenCacheKey(config.SQL, args) | |
| 37 | + } | |
| 38 | + | |
| 39 | + if config.Exexpire == 0 { | |
| 40 | + config.Exexpire = DEFAULT_EXPIRE | |
| 41 | + } | |
| 42 | + | |
| 43 | + if config.CacheDB == "" { | |
| 44 | + config.CacheDB = LXMYSQLCACHEDB | |
| 45 | + } | |
| 46 | + | |
| 47 | + _redis := lxredis.LXredis{ | |
| 48 | + Name: cacheKey, | |
| 49 | + Db: config.CacheDB, | |
| 50 | + } | |
| 51 | + | |
| 52 | + if config.Exexpire > 0 { | |
| 53 | + if b, _ := _redis.IsExist(); b { | |
| 54 | + str, _ := _redis.GET() | |
| 55 | + if str != "" { | |
| 56 | + // 如果缓存中有数据,则直接返回数据 | |
| 57 | + err = json.Unmarshal([]byte(str), result) | |
| 58 | + if err == nil { | |
| 59 | + return | |
| 60 | + } | |
| 61 | + } | |
| 62 | + } | |
| 63 | + } | |
| 64 | + | |
| 65 | + if config.Orm == nil { | |
| 66 | + config.Orm = orm.NewOrm() | |
| 67 | + } | |
| 68 | + | |
| 69 | + if len(config.DBIndex) > 0 { | |
| 70 | + config.Orm.Using(config.DBIndex) | |
| 71 | + } | |
| 72 | + | |
| 73 | + if _, err = config.Orm.Raw(config.SQL).QueryRows(result); err != nil { | |
| 74 | + | |
| 75 | + if strings.Contains(err.Error(), "doesn't exist") { | |
| 76 | + err = nil | |
| 77 | + return | |
| 78 | + } | |
| 79 | + return | |
| 80 | + } | |
| 81 | + | |
| 82 | + if config.Exexpire > 0 { | |
| 83 | + _redis.Val = lconv.JsonEncode(result) | |
| 84 | + _redis.SetTime(config.Exexpire) | |
| 85 | + } | |
| 86 | + | |
| 87 | + return | |
| 88 | +} | |
| 89 | + | |
| 90 | +// Query 查询数据 | |
| 91 | +func Query(config QueryConfig, result interface{}, args ...interface{}) (err error) { | |
| 92 | + | |
| 93 | + if config.Orm == nil { | |
| 94 | + config.Orm = orm.NewOrm() | |
| 95 | + } | |
| 96 | + | |
| 97 | + if len(config.DBIndex) > 0 { | |
| 98 | + config.Orm.Using(config.DBIndex) | |
| 99 | + } | |
| 100 | + | |
| 101 | + if _, err = config.Orm.Raw(config.SQL).QueryRows(result); err != nil { | |
| 102 | + if strings.Contains(err.Error(), "doesn't exist") { | |
| 103 | + err = nil | |
| 104 | + return | |
| 105 | + } | |
| 106 | + return | |
| 107 | + } | |
| 108 | + | |
| 109 | + return | |
| 110 | +} | |
| 111 | + | |
| 112 | +// FindOne 查询一条数据 | |
| 113 | +func FindOne(config QueryConfig, result interface{}, args ...interface{}) (err error) { | |
| 114 | + | |
| 115 | + if config.Orm == nil { | |
| 116 | + config.Orm = orm.NewOrm() | |
| 117 | + } | |
| 118 | + | |
| 119 | + if len(config.DBIndex) > 0 { | |
| 120 | + config.Orm.Using(config.DBIndex) | |
| 121 | + } | |
| 122 | + | |
| 123 | + if err = config.Orm.Raw(config.SQL).QueryRow(result); err != nil { | |
| 124 | + if strings.Contains(err.Error(), "doesn't exist") { | |
| 125 | + err = nil | |
| 126 | + return | |
| 127 | + } | |
| 128 | + return | |
| 129 | + } | |
| 130 | + | |
| 131 | + return | |
| 132 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,106 @@ |
| 1 | +package lxtime | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "fmt" | |
| 5 | + "time" | |
| 6 | +) | |
| 7 | + | |
| 8 | +// NowUninx 当前的时间戳 (秒) | |
| 9 | +func NowUninx() int64 { | |
| 10 | + return time.Now().Unix() | |
| 11 | +} | |
| 12 | + | |
| 13 | +//// NowUnixMilli 当前的时间戳 (毫秒) | |
| 14 | +//func NowUnixMilli() int64 { | |
| 15 | +// return time.Now().UnixMilli() | |
| 16 | +//} | |
| 17 | + | |
| 18 | +//// NowUnixMicro 当前的时间戳 (微秒) | |
| 19 | +//func NowUnixMicro() int64 { | |
| 20 | +// return time.Now().UnixMicro() | |
| 21 | +//} | |
| 22 | + | |
| 23 | +// NowUnixNano 当前的时间戳 (纳秒) | |
| 24 | +func NowUnixNano() int64 { | |
| 25 | + return time.Now().UnixNano() | |
| 26 | +} | |
| 27 | + | |
| 28 | +// NowDate 当前日期字符串 | |
| 29 | +func NowDate() string { | |
| 30 | + return GetDate(NowUninx()) | |
| 31 | +} | |
| 32 | + | |
| 33 | +// NowTime 当前时间字符串 | |
| 34 | +func NowTime() string { | |
| 35 | + return GetTime(NowUninx()) | |
| 36 | +} | |
| 37 | + | |
| 38 | +// NowYear 当前时间字符串 年 | |
| 39 | +func NowYear() string { | |
| 40 | + return GetYear(NowUninx()) | |
| 41 | +} | |
| 42 | + | |
| 43 | +// NowMonth 当前时间字符串 月 | |
| 44 | +func NowMonth() string { | |
| 45 | + return GetMonth(NowUninx()) | |
| 46 | +} | |
| 47 | + | |
| 48 | +// NowDay 当前时间字符串 日 | |
| 49 | +func NowDay() string { | |
| 50 | + return GetDay(NowUninx()) | |
| 51 | +} | |
| 52 | + | |
| 53 | +// NowDateTime 当前日期时间字符串 | |
| 54 | +func NowDateTime() string { | |
| 55 | + return GetDateTime(NowUninx()) | |
| 56 | +} | |
| 57 | + | |
| 58 | +// NowZeroUninxTime 0点的时间戳 | |
| 59 | +func NowZeroUninxTime() int64 { | |
| 60 | + tim := time.Unix(NowUninx(), 0).Format("2006-01-02") | |
| 61 | + t, _ := time.ParseInLocation("2006-01-02 15:04:05", tim+" 00:00:00", time.Local) | |
| 62 | + return t.Unix() | |
| 63 | +} | |
| 64 | + | |
| 65 | +// GetDate 时间戳转换 日期字符串 | |
| 66 | +func GetDate(utime int64) string { | |
| 67 | + tim := time.Unix(utime, 0).Format("2006-01-02") | |
| 68 | + return fmt.Sprintf("%s", tim) | |
| 69 | +} | |
| 70 | + | |
| 71 | +// GetTime 时间戳转换 时间字符串 | |
| 72 | +func GetTime(utime int64) string { | |
| 73 | + tim := time.Unix(utime, 0).Format("15:04:05") | |
| 74 | + return fmt.Sprintf("%s", tim) | |
| 75 | +} | |
| 76 | + | |
| 77 | +// GetDateTime 时间戳转换 日期时间字符串 | |
| 78 | +func GetDateTime(utime int64) string { | |
| 79 | + tim := time.Unix(utime, 0).Format("2006-01-02 15:04:05") | |
| 80 | + return fmt.Sprintf("%s", tim) | |
| 81 | +} | |
| 82 | + | |
| 83 | +// GetMonth 时间戳转换 月 | |
| 84 | +func GetMonth(utime int64) string { | |
| 85 | + tim := time.Unix(utime, 0).Format("01") | |
| 86 | + return fmt.Sprintf("%s", tim) | |
| 87 | +} | |
| 88 | + | |
| 89 | +// GetYear 时间戳转换 年 | |
| 90 | +func GetYear(utime int64) string { | |
| 91 | + tim := time.Unix(utime, 0).Format("2006") | |
| 92 | + return fmt.Sprintf("%s", tim) | |
| 93 | +} | |
| 94 | + | |
| 95 | +// GetDay 时间戳转换 日 | |
| 96 | +func GetDay(utime int64) string { | |
| 97 | + tim := time.Unix(utime, 0).Format("02") | |
| 98 | + return fmt.Sprintf("%s", tim) | |
| 99 | +} | |
| 100 | + | |
| 101 | +// GetZeroUninxTime 计算0点的时间戳 | |
| 102 | +func GetZeroUninxTime(utime int64) int64 { | |
| 103 | + tim := time.Unix(utime, 0).Format("2006-01-02") | |
| 104 | + t, _ := time.ParseInLocation("2006-01-02 15:04:05", tim+" 00:00:00", time.Local) | |
| 105 | + return t.Unix() | |
| 106 | +} | ... | ... |