From 36c67636dc6c9b018ea31476d69a37c6d6e61503 Mon Sep 17 00:00:00 2001 From: dongth Date: Wed, 31 Jul 2024 15:47:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20dbop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dbop/georedis.go | 31 +++++++++++ dbop/mysqlop.go | 121 +++++++++++++++++++++++++++++++++++++++++ dbop/redisop.go | 112 ++++++++++++++++++++++++++++++++++++++ dbop/selfcache.go | 66 +++++++++++++++++++++++ dbop/user.go | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 463 insertions(+) create mode 100644 dbop/georedis.go create mode 100644 dbop/mysqlop.go create mode 100644 dbop/redisop.go create mode 100644 dbop/selfcache.go create mode 100644 dbop/user.go diff --git a/dbop/georedis.go b/dbop/georedis.go new file mode 100644 index 0000000..da563c3 --- /dev/null +++ b/dbop/georedis.go @@ -0,0 +1,31 @@ +package dbop + +import ( + + + "github.com/shockliu/logger" +) + +const ( + Location = "dqkposition" + Maintain = "maintain" +) + +func GetPlace(client int) (place int) { + err := MDb.QueryRow("select location from dqk_client where id=?;", client).Scan(&place) + if err != nil { + logger.Debugf("获取设备位置错误%s\n", err) + return 0 + } + return +} + +// func GetDistance(place int, Lat, Long float64) float64 { +// var plat, plong float64 +// err := MDb.QueryRow("select lon,lat from place_table where id=?;", place).Scan(&plong, &plat) +// if err != nil { +// logger.Debugf("获取定位%d信息失败%s\n", place, err) +// return -1 +// } +// return dmap.Distance(plat, Lat, plong, Long) +// } diff --git a/dbop/mysqlop.go b/dbop/mysqlop.go new file mode 100644 index 0000000..a878d18 --- /dev/null +++ b/dbop/mysqlop.go @@ -0,0 +1,121 @@ +package dbop + +import ( + "database/sql" + "fmt" + "time" + + "github.com/shockliu/logger" + + _ "github.com/go-sql-driver/mysql" +) + +var ( + MDb *sql.DB + err error // 错误信息 + client map[string]string //设备信息,根据client_code查询 + clientname map[string]string // 设备名称 + +) + +// 初始化链接 +func init() { + //"用户名:密码@[连接方式](主机名:端口号)/数据库名" + const ( + USER_NAME = "eshc" + PASS_WORD = "Eshc88$*" + HOST = "47.118.40.174" + PORT = "3306" + DATABASE = "eshc_dev" + CHARSET = "utf8mb4" + ) + + // 豆曲咖数据库 + //dsn := "eshc:Eshc88$*@tcp(47.118.40.174:3306)/eshc_dev" + dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=true", USER_NAME, PASS_WORD, HOST, PORT, DATABASE, CHARSET) + // 打开连接失败 + MDb, err = sql.Open("mysql", dbDSN) + //defer MysqlDb.Close(); + if err != nil { + logger.Error("dbDSN: " + dbDSN) + panic("数据源配置不正确: " + err.Error()) + } + + // 最大连接数 + MDb.SetMaxOpenConns(10) + // 闲置连接数 + MDb.SetMaxIdleConns(5) + // 最大连接周期 + MDb.SetConnMaxLifetime(100 * time.Second) + if err = MDb.Ping(); nil != err { + panic("数据库链接失败: " + err.Error()) + } +} + +func GetUserUnionID(openId string) (unionId string) { + MDb.QueryRow("select union_id from wechat_member where open_Id=?;", openId).Scan(&unionId) + return +} + +func AddMpUser(openId, unionId string, scribeTime int32) { + var id int64 + var uid string + // 已经有这个openID,则需要更新UnionID + err := MDb.QueryRow("select id,IFNULL(extra,'') from user_relation where openId=?;", openId).Scan(&id, &uid) + if err != nil { + logger.Errorf("获取用户%s信息失败:%s\n", openId, err) + } else if uid != unionId { + _, err = MDb.Exec("update user_relation set extra=? where openID=?;", unionId, openId) + if err != nil { + logger.Errorf("更新用户%s-%s信息失败:%s\n", openId, unionId, err) + } + } + + if len(uid) > 0 { + _, err := MDb.Exec("UPDATE wxmp_user set statu=1,unionId=?,scribeTime=now() where openId=?;", unionId, openId) + if err != nil { + logger.Errorf("更新用户open[%s]union[%s]状态信息失败:%s\n", openId, unionId, err) + } + } else { + _, err := MDb.Exec("INSERT into wxmp_user (openId,unionId,scribeTime,statu)values(?,?,from_unixtime(?),1);", openId, unionId, scribeTime) + if err != nil { + logger.Errorf("插入公众号用户表失败:%s\n", err) + } + if len(unionId) > 0 { + err = MDb.QueryRow("select id from user_relation where extra=?;", unionId).Scan(&id) + if err == nil { + _, err = MDb.Exec("insert into user_relation (id,channel,openId,extra,`time`) values(?,1,?,?,now());", id, openId, unionId) + if err != nil { + logger.Debugf("插入user_relation表id[%d][%s][%s]失败:%s\n", id, openId, unionId, err) + } + return + } + } + + //创建新用户 + rst, err := MDb.Exec("insert into dqk_user (name,nickname,registerTime) values('公众号用户','公众号用户',now());") + if err != nil { + logger.Debugf("创建用户失败:%s\n", err) + return + } + id, err = rst.LastInsertId() + if err != nil { + logger.Debugf("获取新建用户ID失败:%s\n", err) + return + } + _, err = MDb.Exec("insert into user_relation (id,channel,openId,extra,`time`) values(?,1,?,?,now());", id, openId, unionId) + if err != nil { + logger.Debugf("插入user_relation表失败:%s\n", err) + return + } + } +} + +func GetUserId(openid, unionId string) (id int) { + logger.Debugf("用户鉴权openid:%s\n", openid) + err := MDb.QueryRow("select a.user_id from user_account a where a.open_id = ?;", openid).Scan(&id) + if err != nil { + return -1 + } + return id +} diff --git a/dbop/redisop.go b/dbop/redisop.go new file mode 100644 index 0000000..c14bec7 --- /dev/null +++ b/dbop/redisop.go @@ -0,0 +1,112 @@ +package dbop + +import ( + "encoding/json" + "time" + + "github.com/shockliu/logger" + + "github.com/go-redis/redis" + //"errors" +) + +const ( + RD_TRADE_HEAD = "ORDER:" + RD_MACHINE_HEAD = "ZDDevice:" + RD_SESSION_HEAD = "SessionKey:" + RD_SALERSESSION_HEAD = "SalerSessionKey:" + RD_ICCARD_HEAD = "IC:" + RD_SALE_HEAD = "SALE:" + RD_DEVSTAT_HEAD = "MACHINE:" + RD_ALARM_HEAD = "ALARM:" +) + +var ( + RDb *redis.Client +) + +// Redis 预订单状态存储,临时存储,支付后就进入数据库 +type OrderInfo struct { + McId string `json:"mcId"` // 机器 + TradeNo string `json:"tradeNo"` // 订单 + ProdName string `json:"ProdName"` // 产品名称 + ProdCode string `json:"ProdCode"` // 产品编码 + FavorCode string `json:"FavorCode"` // 口味ID,下发制作使用 + Amount int `json:"amount"` // 价格 + PayType string `json:"payType"` // 支付类型 +} + +// 初始化连接 +func init() { + RDb = redis.NewClient(&redis.Options{ + Addr: "47.118.40.174:6379", + Password: "88480288", // no password set + DB: 0, // use default DB + PoolSize: 100, // 连接池大小 + }) + _, err = RDb.Ping().Result() + if err != nil { + panic("Redis初始化失败") + } +} + +/* +// 待支付订单列表 dbop.InsertTrade(McId,tradeNo,data.ProdName,data.amount,"wxpay") +func InsertRedisTrade(McId,tradeNo,Name,code string,amount int,pchan string){ + s,_:=json.Marshal(OrderInfo{McId,tradeNo,Name,code,amount,pchan}) + RDb.Set(RD_TRADE_HEAD+tradeNo,s,30*time.Minute) +} +*/ +/* +// 订单状态修改 +func UpdateRedisTrade(tradeNo,status string) bool{ + s,err:=RDb.Get(RD_TRADE_HEAD+tradeNo).Result() + if(err==redis.Nil){ + return false + } + var data OrderInfo + _ = json.Unmarshal([]byte(s), &data) + data.PayStatus=status + st,_:=json.Marshal(data) + RDb.Set(RD_TRADE_HEAD+tradeNo,string(st),10*time.Minute) + return true +} +*/ +// 获取订单支付信息 +func GetRedisTradeInfo(TradeNo string) (rst OrderInfo, ok bool) { + s, err := RDb.Get(RD_TRADE_HEAD + TradeNo).Result() + if err != nil { + //if(err==redis.Nil){ + logger.Errorf("获取Redis订单信息[%s]失败:%v\n", RD_TRADE_HEAD+TradeNo, err) + return + } // 其它错误未捕获 err!=nil + _ = json.Unmarshal([]byte(s), &rst) + ok = true + return +} + +/* +// 获取订单支付状态 +func GetRedisTradeStatus(TradeNo string) string{ + s,err:=RDb.Get(RD_TRADE_HEAD+TradeNo).Result() + if(err==redis.Nil){ + logger.Warnf("Redis no Key\n") + return "NO_EXIST" + } // 其它错误未捕获 err!=nil + var data OrderInfo + _ = json.Unmarshal([]byte(s), &data) + return data.PayStatus +} +*/ + +func SaveSalerSessionKey(openid, sessionkey string) { + RDb.Set(RD_SALERSESSION_HEAD+openid, sessionkey, 240*time.Hour) +} + +func SaveSessionKey(openid, sessionkey string) { + RDb.Set(RD_SESSION_HEAD+openid, sessionkey, 240*time.Hour) +} + +func ClearSessionKey(openid string) { + RDb.Del(RD_SESSION_HEAD + openid) +} diff --git a/dbop/selfcache.go b/dbop/selfcache.go new file mode 100644 index 0000000..b75a3bf --- /dev/null +++ b/dbop/selfcache.go @@ -0,0 +1,66 @@ +package dbop + +import ( + "encoding/json" + "time" + + "github.com/shockliu/logger" +) + +const ( + selfkeyhead = "sjwx:" +) + +type SelfCache struct { + Prefix string +} + +// NewMemory create new memcache +func NewSelfCache(key string) *SelfCache { + return &SelfCache{Prefix: selfkeyhead + key} +} + +// Get return cached value +func (c *SelfCache) Get(key string) any { + key = c.Prefix + key + s, err := RDb.Get(key).Result() + if err != nil { + return nil + } + var reply any + if err = json.Unmarshal([]byte(s), &reply); err != nil { + return nil + } + logger.Debugf("微信小程序获取access_token[%v]\n", reply) + return reply +} + +// IsExist check value exists in memcache. +func (c *SelfCache) IsExist(key string) bool { + key = c.Prefix + key + + a := RDb.Exists(key) + logger.Debugf("微信小程序确认access_token是否存在%d\n", a.Val()) + return a.Val() > 0 +} + +// Set cached value with key and expire time. +func (c *SelfCache) Set(key string, val any, timeout time.Duration) (err error) { + key = c.Prefix + key + + var data []byte + if data, err = json.Marshal(val); err != nil { + return + } + RDb.Set(key, data, timeout) + logger.Debugf("微信小程序确认access_token保存[%s]\n", data) + return +} + +// deleteKey +func (c *SelfCache) Delete(key string) (err error) { + key = c.Prefix + key + RDb.Del(key) + logger.Debugf("微信小程序删除access_token\n") + return nil +} diff --git a/dbop/user.go b/dbop/user.go new file mode 100644 index 0000000..c9a9f2b --- /dev/null +++ b/dbop/user.go @@ -0,0 +1,133 @@ +package dbop + +import ( + "bytes" + "crypto/des" + "crypto/md5" + "encoding/base64" + "encoding/hex" + "errors" + + "github.com/shockliu/logger" +) + +const ( + codekey = "HY&XC&MW" +) + +var ( + uOpenID map[int64]string +) + +func init() { + uOpenID = make(map[int64]string) +} + +func PKCS5Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +// ECB+PKCS5加密 +func EncryptDES_ECB(data []byte) []byte { + block, err := des.NewCipher([]byte(codekey)) + if err != nil { + panic(err) + } + bs := block.BlockSize() + //对明文数据进行补码 + data = PKCS5Padding(data, bs) + out := make([]byte, len(data)) + dst := out + for len(data) > 0 { + //对明文按照blocksize进行分块加密 + //必要时可以使用go关键字进行并行加密 + block.Encrypt(dst, data[:bs]) + data = data[bs:] + dst = dst[bs:] + } + // return fmt.Sprintf("%X", out) + return out +} + +// 测试验证发现,密码加密方式位 +func EncryptPwd(code string) string { + enc := base64.StdEncoding.EncodeToString(EncryptDES_ECB([]byte(code))) + h := md5.New() + h.Write([]byte(enc)) + return hex.EncodeToString(h.Sum(nil)) +} + +func SavePasswd(user int, passwd string) bool { + _, err := MDb.Exec("update aos_user set password=? where id=?;", EncryptPwd(passwd), user) + return err == nil +} + +func PasswdAuth(user int, passwd string) bool { + var encPwd string + err := MDb.QueryRow("select password from aos_user where id=?;", user).Scan(&encPwd) + if err != nil { + logger.Debugf("获取用户[%d]密码失败%s\n", user, err) + return false + } + return EncryptPwd(passwd) == encPwd +} + +func AppUserAuth(user, passwd string) (bool, string, int, error) { + var encPwd, name string + var id int + err := MDb.QueryRow("select password,id,name from aos_user where account=?;", user).Scan(&encPwd, &id, &name) + if err != nil { + return false, "", 0, err + } + // 密码md5计算后比较 + //enc := EncryptPwd(passwd) + //logger.Debugf("[%s]->[%s]===[%s]\n", passwd, enc, encPwd) + if EncryptPwd(passwd) == encPwd { + return true, name, id, nil + } + return false, "", 0, errors.New("账号密码鉴权失败") +} + +func ExistWxUser(user string) bool { + if len(user) == 0 { + return false + } + var cnt int + err := MDb.QueryRow("select count(1) from wxmp_user where openId=? and statu=1 ;", user).Scan(&cnt) + return (err == nil && cnt > 0) +} + +func GetOpenId(id int64) string { + if openID, ok := uOpenID[id]; ok { + return openID + } else { + err := MDb.QueryRow("select openId from user_relation where channel=3 and id = ?;", id).Scan(&openID) + if err != nil { + logger.Debugf("查询用户商城openID失败%s\n", err) + } else { + uOpenID[id] = openID // 缓存 + } + return openID + } +} + +func GetMaintainer(id int) (user []int) { + rows, err := MDb.Query("select d.id from maintenance_user_place a RIGHT JOIN dqk_client b on a.place_id=b.location LEFT JOIN aos_user c on a.user_id=c.id left join dqk_user d on c.account=d.name where b.id=?;", id) + if err != nil { + logger.Debugf("查询设备[%d]维护人员失败%s\n", id, err) + return + } + defer rows.Close() + var uid int + for rows.Next() { + err = rows.Scan(&uid) + if err != nil { + logger.Warnf("获取设备%d维护人员失败%s\n", id, err) + continue + } + user = append(user, uid) + } + return +}