README
¶
1. Elasticsearch
s := map[string]interface{}{
"id": note.ID,
"user_id": note.UserId,
"title": note.Title,
"content": note.Content,
"status": note.Status,
}
_, err := config.EsClient.Index().
Index("note").
Id(strconv.FormatInt(note.ID, 10)).
BodyJson(s).
Do(context.Background())
1.2
boolQuery := elastic.NewBoolQuery()
match := elastic.NewMatchQuery("",)
boolQuery.Must(match)
terms := elastic.NewMatchQuery("",)
boolQuery.Must(terms)
termss := elastic.NewMatchQuery("series", req.Series)
boolQuery.Must(termss)
rangeQuery := elastic.NewRangeQuery("").Gte().Lte()
boolQuery.Must(rangeQuery)
sort := elastic.NewFieldSort("_score").Desc()
split := strings.Split(req.Splice, "_")
if len(split) == 2 && split[0] == "" {
sort = elastic.NewFieldSort("")
if split[1] == "desc" {
sort.Desc()
} else {
sort.Asc()
}
}
highlight := elastic.NewHighlight()
highlight = highlight.Field("").
PreTags("<span style=\"color:red;\">").
PostTags("</span>")
res, err := config.Esc.Search("").
Query().
From().
Size().
SortBy().
Highlight().
Do(context.Background())
var list []*
for _, hit := range res.Hits.Hits {
p := new()
err := json.Unmarshal(hit.Source, p)
if h, ok := hit.Highlight[""]; ok { p.Title = strings.Join(h, " ") }
if err != nil {
return nil, errors.New("解析失败")
}
list = append(list, p)
}
count := res.TotalHits()
1.3
id := strconv.FormatInt(, 10)
getResult, err := config.EsClient.Get().
Index("").
Id(id).
Do(context.Background())
if err != nil {
return err
}
json.Unmarshal(getResult.Source, &)
b, _ := json.Marshal()
_, err = config.EsClient.Index().
Index("").
Id().
BodyJson(string(b)).
Do(context.Background())
1.4
id := strconv.FormatInt(, 10)
_, err := config.EsClient.Delete().
Index("").
Id().
Do(context.Background())
if elastic.IsNotFound(err) {
return nil
}
2
rdb.Set(context.Background(), "key", "value", time.Hour)
val, err := rdb.Get(context.Background(), "key").Result()
if err == redis.Nil {
// key 不存在
}
2.1
b, _ := json.Marshal()
rdb.Set(context.Background(),kry, b, 30*time.Minute)
err := json.Unmarshal([]byte(rdb.Get(context.Background(), key).Val()), &cached)
if err != nil {
// 缓存未命中或格式错误,从数据库查
}
2.3
key := fmt.Sprintf("sms:%s:%s", source, mobile)
count, _ := rdb.Incr(context.Background(), key).Result()
if count == 1 {
rdb.Expire(context.Background(), key, time.Minute)
}
if count > 3 {
return errors.New("发送过于频繁,请稍后再试")
}
2.4
key := fmt.Sprintf("lock:%d", id)
ok, _ := rdb.SetNX(context.Background(), key, "1", 10*time.Second).Result()
if !ok {
return errors.New("操作进行中,请稍后重试")
}
defer rdb.Del(context.Background(), key)
3 推
const FeedMaxSize = 1000
func notePushToFansFeed(noteId int, fans []*model.Follow) {
pipe := rdb.GetClient().Pipeline()
ctx := context.Background()
for _, v := range fans {
key := fmt.Sprintf("feed:follow:%d", v.FollowdId)
pipe.ZAdd(context.Background(), key, redis.Z{
Score: float64(time.Now().Unix()),
Member: fmt.Sprintf("%d", noteId),
})
pipe.ZRemRangeByRank(ctx, key, 0, int64(-FeedMaxSize-1))
}
_, err := pipe.Exec(ctx)
if err != nil {
fmt.Println("", err)
logger.Error(err.Error())
return
}
}
3.1 拉
const BigVlatestKey = "big:v:latest"
const BigVPoolMaxSize = 10000
func addToBigVPool(noteId int) {
pipe := rdb.GetClient().Pipeline()
ctx := context.Background()
pipe.ZAdd(ctx, BigVlatestKey, redis.Z{
Score: float64(time.Now().Unix()),
Member: fmt.Sprintf("%d", noteId),
})
pipe.ZRemRangeByRank(ctx, BigVlatestKey, 0, int64(-BigVPoolMaxSize-1))
}
3.2
var data producter.AuditMsg
err := json.Unmarshal(msg.Value, &data)
if err != nil {
fmt.Println("msg解析失败:", err)
logger.Error(err.Error())
_ = kafka.SendDeadLetter("", string(msg.Value),err.Error())
return
}
text := data.Title + data.Content
var wordList []model.SensitiveWord
score := 0
database.GetMySQL().Model(&model.SensitiveWord{}).Find(&wordList)
fmt.Println(wordList)
for _, v := range wordList {
if strings.Contains(text, v.Remark) {
score += int(v.Point)
}
}
db := database.GetMySQL()
if score <= 30 {
for _, v := range follows {
ss := producter.NoteMsg{
UserId: v.FollowrId,
NoteId: data.NoteId,
}
producter.SendNoteToFansFeed(ss)
}
}
4 jwt
clientType := form.ClientType
if clientType == 0 {
clientType = token.ClientWeb
}
pair, err := token.IssuePair(resp.Id, 1, clientType)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "签发token失败", "data": nil})
return
}
4.1 退
tokenStr := c.GetHeader("token")
if tokenStr == "" {
c.JSON(http.StatusOK, gin.H{"code": 200, "message": "退出成功"})
return
}
claims, err := pkgjwt.NewJWT().ParseToken(tokenStr)
if err == nil && claims.StandardClaims.Id != "" {
ttl := time.Until(time.Unix(claims.StandardClaims.ExpiresAt, 0))
_ = token.Blacklist(c.Request.Context(), claims.StandardClaims.Id, ttl)
}
5 卡
p, err := kafka.NewSyncProducer()
if err != nil {
fmt.Println("创建生产者失败", err)
return
}
defer p.Close()
data, _ := json.Marshal(ss)
_, _, err = p.SendMessage("", string(data))
if err != nil {
fmt.Println("发送消息失败", err)
}
5 通
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
type node struct {
Conn *websocket.Conn
Data chan []byte
}
var nodeMap map[string]*node = make(map[string]*node)
var mu sync.Mutex
const ChatTopic = "chat_message"
type ChatMessage struct {
SenderId string `json:"sender_id"`
ReceiverId string `json:"receiver_id"`
Content string `json:"content"`
CreatedAt string `json:"created_at"`
Status string `json:"status"`
}
const OfflineMessageCollection = "offline_messages"
func Chat(c *gin.Context) {
ownId := c.Query("ownId")
targetId := c.Query("targetId")
if ownId == "" || targetId == "" {
c.JSON(400, gin.H{
"msg": "ownId or targetId is empty",
})
return
}
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
log.Println(err)
return
}
myNode := &node{
Conn: conn,
Data: make(chan []byte),
}
mu.Lock()
nodeMap[ownId] = myNode
mu.Unlock()
go ReceiveMessage(myNode, ownId, targetId)
go SendMessage(myNode)
go HeartBeat(myNode, ownId)
}
func HeartBeat(n *node, uid string) {
tick := time.NewTicker(10 * time.Second)
defer tick.Stop()
for range tick.C {
if _, ok := nodeMap[uid]; !ok {
nodeMap[uid] = n
}
}
}
func ReceiveMessage(node *node, ownId string, targetId string) {
for {
_, p, err := node.Conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
msg := ChatMessage{
SenderId: ownId,
ReceiverId: targetId,
Content: string(p),
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
if _, ok := nodeMap[targetId]; ok {
nodeMap[targetId].Data <- p
}
sendMessageTokafka(msg)
}
}
func sendMessageTokafka(msg ChatMessage) {
data, err := json.Marshal(msg)
if err != nil {
log.Println("聊天消息转 json 失败:", err)
return
}
producer, err := kafka.NewSyncProducer()
if err != nil {
log.Println("创建kafka生产者失败:", err)
return
}
defer producer.Close()
if _, _, err = producer.SendMessage(ChatTopic, string(data)); err != nil {
log.Println("发送聊天到kafka 失败:", err)
return
}
}
func SendMessage(node *node) {
for {
p := <-node.Data
if p == nil {
continue
}
if err := node.Conn.WriteMessage(websocket.TextMessage, p); err != nil {
log.Println(err)
return
}
}
}
5.2
type ChatMessage struct {
SenderId int64 `bson:"sender_id"`
ReceiverId int64 `bson:"receiver_id"`
Content string `bson:"content"`
Status string `bson:"status"`
CreatedAt int64 `bson:"created_at"`
}
func SendOfflineMessage(userId int64) {
coll := database.MongoDB("offline_messages")
var msgs []ChatMessage
coll.Find(ctx, bson.M{
"receiver_id": userId, "status": "offline",
}).All(&msgs)
for _, m := range msgs {
nodeMap[userId].Data <- []byte(m.Content)
}
coll.UpdateMany(ctx,
bson.M{"receiver_id": userId, "status": "offline"},
bson.M{"$set": bson.M{"status": "delivered"}},
)
}
6
func Pay(orderSn string, total float64) string {
data := config.Cfg.Alipay
appId := data.Appid
privateKey := data.Key
client, err := alipay.New(appId, privateKey, false)
if err != nil {
fmt.Println(err)
return ""
}
var p = alipay.TradeWapPay{}
p.NotifyURL = data.Url + "/pay/notify"
p.ReturnURL = "http://xxx"
p.Subject = "在线支付"
p.OutTradeNo = orderSn
p.TotalAmount = strconv.FormatFloat(total, 'f', 2, 64)
p.ProductCode = "QUICK_WAP_WAY"
url, err := client.TradeWapPay(p)
if err != nil {
fmt.Println(err)
return ""
}
var payURL = url.String()
return payURL
}
6.4
c := cron.New()
c.AddFunc("* * * * *", api.HandlerExpireOrder)
c.Start()
func Notify(c *gin.Context) {
err := c.Request.ParseForm()
if err != nil {
fmt.Println("解析失败:", err)
c.String(200, "fail")
return
}
notifyMap := make(map[string]string)
for s, v := range c.Request.PostForm {
notifyMap[s] = v[0]
}
fmt.Println(notifyMap)
orderno := notifyMap["out_trade_no"]
if orderno == "" {
fmt.Println("订单号为空")
c.String(200, "fail")
return
}
if notifyMap["trade_status"] != "TRADE_SUCCESS" {
fmt.Println("支付失败,trade_status:", notifyMap["trade_status"])
c.String(200, "fail")
return
}
if strings.Contains(orderno, "") {
var order model.Order
err = order.FindOrderByDrugSn(config.DB, orderno)
if err != nil {
fmt.Println("预约单不存在")
c.String(200, "fail")
return
}
order.Status = 2
order.PayType = 2
err = order.Save(config.DB)
if err != nil {
fmt.Println("预约状态更新失败")
c.String(200, "fail")
return
}
c.String(200, "success")
return
}
}
func HandlerExpireOrder() {
var
config.DB.Where().Where().Find()
if len() == 0 {
fmt.Println()
return
}
for _, o := range order {
tx := config.DB.Begin()
var
if err := tx.Where().Find().Error; err != nil {
tx.Rollback()
fmt.Println(err)
continue
}
for _, i := range {
var
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First().Error; err != nil {
tx.Rollback()
fmt.Println()
continue
}
if err := tx.Save(&).Error; err != nil {
tx.Rollback()
fmt.Println(err)
continue
}
}
o.Status = 3
if err := tx.Save(&order).Error; err != nil {
tx.Rollback()
fmt.Println(err)
continue
}
if err := tx.Commit().Error; err != nil {
fmt.Println(err)
continue
}
fmt.Printf()
}
}
7
time.Now().Add(15 * time.Minute)
time.Parse
t.Before(time.Now())
8
const strUrl = "https://api.ihuyi.com/sms/Submit.json"
func SendSms(mobile string, code string) (T, error) {
data := config.Cfg.Sendsms
v := url.Values{}
v.Set("account", data.Account)
v.Set("password", data.Password)
v.Set("mobile", mobile)
v.Set("content", "您的验证码是:"+code+"。请不要把验证码泄露给其他人。")
body := strings.NewReader(v.Encode())
client := &http.Client{}
req, _ := http.NewRequest("POST", strUrl, body)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
res, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(res))
var t T
json.Unmarshal(res, &t)
return t, err
}
type T struct {
Code int `json:"code"`
Msg string `json:"msg"`
Smsid string `json:"smsid"`
}
Click to show internal directories.
Click to hide internal directories.