keyword模块部分代码(合规已脱敏)

1.action [router打到action请求]

package action

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    sDb "sms-keywords/data/db"
    sRedis "sms-keywords/data/redis"
    "sms-keywords/lib"
    sLog "sms-keywords/lib/log"
    search "sms-keywords/lib/words"
    . "sms-keywords/model"
    sTask "sms-keywords/task"
    "strings"
    "sync"
)

type Res struct {
    Res     bool   `json:"res"`
    Keyword string `json:"keyword"`
    Type    string `json:"type"`
}

type ResMap map[string]Res

type ResAll struct {
    Res            bool     `json:"res"`
    KeywordsReject []string `json:"keywords_reject"`
    KeywordsAudit  []string `json:"keywords_audit"`
}

/*
 * 关键词 Find One
 */
func KeywordsSearch(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Action: [%s] , err[%s]", "KeywordsSearch", err)
            _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("program error"))))
            return
        }
        return
    }()
    w.Header().Set("content-type", "text/json")

    content := r.FormValue("content")
    if content == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:content"))))
        return
    }

    businessType := r.FormValue("business_type")
    if businessType == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:business_type"))))
        return
    }
    checkId := r.FormValue("check_id")
    if checkId == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:check_id"))))
        return
    }
    useCache := r.FormValue("use_cache")

    cacheKey := sRedis.GetCacheKey(content, checkId)
    checkKey := sRedis.GetCheckKey(businessType, checkId)
    obj := sTask.G_Obj.Map[checkKey]
    res := check(checkId, obj, content, cacheKey, useCache)
    sLog.SugarLogger.Infof("check content: [%s]", content)
    msg := SuccessMsg(res)
    _, _ = w.Write([]byte(msg))
}

/*
 * 关键词 Find One - 批量
 */
func KeywordsBatchSearch(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Action: [%s] , err[%s]", "KeywordsBatchSearch", err)
            _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("program error"))))
            return
        }
        return
    }()

    w.Header().Set("content-type", "text/json")

    content := r.FormValue("content")
    if content == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:content"))))
        return
    }

    businessType := r.FormValue("business_type")
    if businessType == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:business_type"))))
        return
    }
    checkIds := r.FormValue("check_ids")
    if checkIds == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:check_ids"))))
        return
    }

    useCache := r.FormValue("use_cache")

    checkArr := strings.Split(checkIds, ",")
    arrLen := len(checkArr)
    ch := make(chan ResMap, arrLen)
    var wg sync.WaitGroup
    for _, checkId := range checkArr {
        wg.Add(1)
        go searchKeywordAsync(&wg, businessType, content, checkId, useCache, ch)
    }
    wg.Wait()
    close(ch)

    resMap := make(ResMap)
    for data := range ch {
        for k, v := range data {
            resMap[k] = v
        }
    }
    sLog.SugarLogger.Infof("check content: [%s], checkIds: [%s] ", content, checkIds)
    msg := SuccessMsg(resMap)
    _, _ = w.Write([]byte(msg))
}

// 协程处理
func searchKeywordAsync(wg *sync.WaitGroup, businessType, content, checkId, useCache string, ch chan ResMap) {
    defer wg.Done()
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Action: [%s] , err[%s]", "searchKeywordAsync", err)
        }
        return
    }()

    resMap := make(ResMap)
    cacheKey := sRedis.GetCacheKey(content, checkId)
    checkKey := sRedis.GetCheckKey(businessType, checkId)
    obj := sTask.G_Obj.Map[checkKey]
    res := check(checkId, obj, content, cacheKey, useCache)

    if !res.Res && len(res.Keyword) == 0 {
        res.Res = true
    }
    resMap[checkId] = res
    ch <- resMap
}

// 校验内容
func check(checkId string, obj *sTask.SearchObj, content, cacheKey, useCache string) Res {
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Action: [%s] , err[%s]", "check", err)
        }
        return
    }()

    rejectTypes := []string{"reject", "rejectGroup"}
    auditTypes := []string{"audit", "auditGroup"}

    // 拦截
    rejectRes := checkType(sDb.TYPE_REJECT, rejectTypes, obj, content, checkId)
    if !rejectRes.Res {
        return rejectRes
    }

    // 审核
    auditRes := checkType(sDb.TYPE_AUDIT, auditTypes, obj, content, checkId)
    if !auditRes.Res {
        return auditRes
    }

    res := new(Res)
    res.Res = true
    res.Keyword = ""
    res.Type = ""
    return *res
}

func checkType(checkType string, checkTypeList []string, obj *sTask.SearchObj, content string, checkId string) Res {
    res := new(Res)
    res.Res = true
    res.Keyword = ""
    res.Type = checkType
    var objCheck *search.StringSearchEx
    var objCheckGroup *search.StringSearchEx
    if checkType == sDb.TYPE_AUDIT {
        objCheck = obj.Audit
        objCheckGroup = obj.AuditGroup
    } else {
        objCheck = obj.Reject
        objCheckGroup = obj.RejectGroup
    }

    for _, t := range checkTypeList {
        if t == checkType {
            res := checkFirst(objCheck, content, checkType)
            if !res.Res {
                return *res
            }
        } else {
            // 组合关键词
            if objCheckGroup != nil {
                keywords := objCheckGroup.FindAll(content)
                sLog.SugarLogger.Debugf("%+v", keywords)
                if len(keywords) > 0 {
                    keywordsList := checkGroupKeywords(checkId, keywords, false)
                    if len(keywordsList) > 0 {
                        res.Res = false
                        res.Type = checkType
                        res.Keyword = keywordsList[0]
                        return *res
                    }
                }
            }
        }
    }
    return *res
}

func checkFirst(objCheck *search.StringSearchEx, content string, checkType string) *Res {
    res := new(Res)
    res.Res = true
    res.Keyword = ""
    res.Type = ""
    if objCheck != nil {
        keyword := objCheck.FindFirst(content)
        sLog.SugarLogger.Debugf("%+v", keyword)
        if keyword != "" {
            res.Res = false
            res.Keyword = keyword
            res.Type = checkType
            resJson, _ := json.Marshal(res)
            sLog.SugarLogger.Debugf("checkFirst arr: [%s]", resJson)
            return res
        }
    }
    return res
}

// 判断组合关键词是否命中
func checkGroupKeywords(checkId string, keywords []string, matchAll bool) []string {
    var keywordList []string
    groupKeywords := sRedis.GetKeywordsGroup(checkId, keywords)
    for _, groupList := range groupKeywords {
        for _, group := range groupList {
            tag := true
            groupArr := strings.Split(group, "&")
            for _, word := range groupArr {
                if !lib.InArray(word, keywords) {
                    tag = false
                    break
                }
            }
            //
            if tag {
                if !matchAll  {
                    keywordList = append(keywordList, group)
                    resJson, _ := json.Marshal(keywordList)
                    sLog.SugarLogger.Debugf("checkGroupKeywords arr: [%s]", resJson)
                    return keywordList
                } else {
                    keywordList = append(keywordList, group)
                }
            }
        }
    }
    resJson, _ := json.Marshal(keywordList)
    sLog.SugarLogger.Debugf("checkGroupKeywords arr: [%s]", resJson)
    return keywordList
}


// ------------------------
/*
 * 关键词 Find All
 */
func KeywordsMatchAll(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Action: [%s] , err[%s]", "KeywordsMatchAll", err)
            _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("program error"))))
            return
        }
        return
    }()
    w.Header().Set("content-type", "text/json")

    content := r.FormValue("content")
    businessType := r.FormValue("business_type")
    checkId := r.FormValue("check_id")
    useCache := r.FormValue("use_cache")

    if content == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:content"))))
        return
    }
    if businessType == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:business_type"))))
        return
    }
    if checkId == "" {
        w.WriteHeader(400)
        _, _ = w.Write([]byte(ErrorMsg(fmt.Sprintf("param error:check_id"))))
        return
    }

    cacheKey := sRedis.GetCacheKey(content, checkId)
    checkKey := sRedis.GetCheckKey(businessType, checkId)
    obj := sTask.G_Obj.Map[checkKey]
    res := checkAll(checkId, obj, content, cacheKey, useCache)
    sLog.SugarLogger.Infof("check content: [%s]", content)
    msg := SuccessMsg(res)
    _, _ = w.Write([]byte(msg))
}

// 全匹配
func checkAll(checkId string, obj *sTask.SearchObj, content, cacheKey, useCache string) ResAll {
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Action: [%s] , err[%s]", "checkAll", err)
        }
        return
    }()
    types := []string{"reject", "audit"}
    groupTypes := []string{"rejectGroup", "auditGroup"}
    res := new(ResAll)
    res.Res = true
    res.KeywordsReject = []string{}
    res.KeywordsAudit = []string{}

    for _, t := range types {
        var objCheck *search.StringSearchEx
        if t == sDb.TYPE_REJECT {
            objCheck = obj.Reject
        } else {
            objCheck = obj.Audit
        }
        if objCheck != nil {
            keywords := objCheck.FindAll(content)
            sLog.SugarLogger.Debugf("%+v", keywords)
            if len(keywords) > 0 {
                res.Res = false
                if t == "reject" {
                    res.KeywordsReject = keywords
                } else {
                    res.KeywordsAudit = keywords
                }
            }
        }
    }

    for _, t := range groupTypes {
        var objCheck *search.StringSearchEx
        var  checkType string
        if t == sDb.TYPE_REJECT_GROUP {
            objCheck = obj.RejectGroup
            checkType = sDb.TYPE_REJECT
        } else {
            objCheck = obj.AuditGroup
            checkType = sDb.TYPE_AUDIT
        }
        if objCheck != nil {
            keywords := objCheck.FindAll(content)
            sLog.SugarLogger.Debugf("%+v", keywords)
            if len(keywords) > 0 {
                groupList := checkGroupKeywords(checkId, keywords, true)
                if len(groupList) > 0 {
                    res.Res = false
                    if checkType == sDb.TYPE_REJECT {
                        res.KeywordsReject = append(res.KeywordsReject, groupList...)
                    } else {
                        res.KeywordsAudit = append(res.KeywordsAudit, groupList...)
                    }
                }
            }
        }
    }

    resJson, _ := json.Marshal(res)
    sLog.SugarLogger.Debugf("res: [%s]", resJson)
    return *res
}

2.respone统一返回处理

package model

import (
    "encoding/json"
    sLog "sms-keywords/lib/log"
)

type ApiData struct {
    ErrCode int         `json:"err_code"`
    ErrMsg  string      `json:"err_msg"`
    Data    interface{} `json:"data"`
}

func SuccessMsg(data interface{}) string {
    res := new(ApiData)
    res.ErrCode = 0
    res.ErrMsg = "success"
    res.Data = data
    msg, _ := json.Marshal(res)
    sLog.SugarLogger.Infof("http response success: [%s]", msg)
    return string(msg)
}

func ErrorMsg(msg string) string {
    res := new(ApiData)
    res.ErrCode = 10001
    res.ErrMsg = msg
    res.Data = ""
    errMsg, _ := json.Marshal(res)
    sLog.SugarLogger.Infof("http response error: [%s]", errMsg)
    return string(errMsg)
}

已有 40 条评论

  1. 博主真是太厉害了!!!

  2. 想想你的文章写的特别好https://www.jiwenlaw.com/

  3. 想想你的文章写的特别好https://www.237fa.com/

  4. 看的我热血沸腾啊https://www.ea55.com/

  5. 想想你的文章写的特别好www.jiwenlaw.com

  6. 兄弟写的非常好 https://www.cscnn.com/

  7. 《你好,星期六》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/142636.html

  8. 你的才华让人惊叹,你是我的榜样。 https://www.4006400989.com/qyvideo/44733.html

  9. 你的文章让我心情愉悦,真是太棒了! http://www.55baobei.com/G73qS08San.html

  10. 你的才华让人惊叹,你是我的榜样。 https://www.4006400989.com/qyvideo/44733.html

  11. 你的文章让我感受到了艺术的魅力,谢谢! http://www.55baobei.com/QOJBLKjtjr.html

  12. 你的文章内容非常用心,让人感动。 https://www.4006400989.com/qyvideo/40372.html

  13. 《遇见闪亮的自己第二季》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/43972.html

  14. 你的文章让我学到了很多知识,非常感谢。 http://www.55baobei.com/vVODDKEFmN.html

  15. 《越过山丘》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/143923.html

  16. 每次看到你的文章,我都觉得时间过得好快。 https://www.yonboz.com/video/47480.html

  17. 看到你的文章,我仿佛感受到了生活中的美好。 https://www.yonboz.com/video/41393.html

  18. 你的文章让我感受到了正能量,非常棒! http://www.55baobei.com/9btoFjuMq4.html

  19. 你的文章充满了创意,真是让人惊喜。 https://www.4006400989.com/qyvideo/42652.html

  20. 你的文章让我感受到了正能量,非常棒! http://www.55baobei.com/4FTHhaXKAs.html

  21. 《出租车司机2017》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/22556.html

  22. 《越过山丘》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/143923.html

  23. 你的文章让我感受到了不一样的风景,谢谢分享。 https://www.yonboz.com/video/71949.html

  24. 你的文章让我感受到了不一样的风景,谢谢分享。 http://www.55baobei.com/VVnPUpilpI.html

  25. 《数学与美味的碰撞》连续剧高清在线免费观看:https://www.jgz518.com/xingkong/167563.html

  26. 哈哈哈,写的太好了https://www.lawjida.com/

  27. 做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com

  28. 2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
    新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
    新车首发,新的一年,只带想赚米的人coinsrore.com
    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
    做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
    新车上路,只带前10个人coinsrore.com
    新盘首开 新盘首开 征召客户!!!coinsrore.com
    新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
    新车即将上线 真正的项目,期待你的参与coinsrore.com
    新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com

  29. 2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
    新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
    新车首发,新的一年,只带想赚米的人coinsrore.com
    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
    做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
    新车上路,只带前10个人coinsrore.com
    新盘首开 新盘首开 征召客户!!!coinsrore.com
    新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
    新车即将上线 真正的项目,期待你的参与coinsrore.com
    新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com

  30. 华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
    如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
    华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
    华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?

  31. 华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
    如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
    华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
    华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?

  32. 华纳东方明珠客服电话是多少?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
    华纳东方明珠开户专线联系方式?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】

  33. 新盛客服电话是多少?(?183-8890-9465—《?薇-STS5099】【
    新盛开户专线联系方式?(?183-8890--9465—《?薇-STS5099】【?扣6011643??】
    新盛客服开户电话全攻略,让娱乐更顺畅!(?183-8890--9465—《?薇-STS5099】客服开户流程,华纳新盛客服开户流程图(?183-8890--9465—《?薇-STS5099】

  34. 新盛客服电话是多少?(?183-8890-9465—《?薇-STS5099】【
    新盛开户专线联系方式?(?183-8890--9465—《?薇-STS5099】【?扣6011643??】
    新盛客服开户电话全攻略,让娱乐更顺畅!(?183-8890--9465—《?薇-STS5099】客服开户流程,华纳新盛客服开户流程图(?183-8890--9465—《?薇-STS5099】

  35. 果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
    果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  36. 果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
    果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  37. 果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
    果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
    果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】

  38. 华纳圣淘沙开户步骤详解(183-8890-9465—?薇-STS5099【6011643】

    华纳圣淘沙公司开户流程全解析(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司账户注册指南(183-8890-9465—?薇-STS5099【6011643】
    新手如何开通华纳圣淘沙公司账户(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙企业开户标准流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户:从零到一(183-8890-9465—?薇-STS5099【6011643】
    官方指南:华纳圣淘沙公司开户流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户流程说明书(183-8890-9465—?薇-STS5099【6011643】

  39. 华纳圣淘沙开户步骤详解(183-8890-9465—?薇-STS5099【6011643】

    华纳圣淘沙公司开户流程全解析(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司账户注册指南(183-8890-9465—?薇-STS5099【6011643】
    新手如何开通华纳圣淘沙公司账户(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙企业开户标准流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户:从零到一(183-8890-9465—?薇-STS5099【6011643】
    官方指南:华纳圣淘沙公司开户流程(183-8890-9465—?薇-STS5099【6011643】
    华纳圣淘沙公司开户流程说明书(183-8890-9465—?薇-STS5099【6011643】

  40. 华纳圣淘沙公司开户新手教程

    零基础学会(183-8890-9465薇-STS5099)
    华纳圣淘沙公司开户

    华纳圣淘沙公司开户保姆级教程(183-8890-9465薇-STS5099)

    一步步教你开通华纳圣淘沙公司账户(183-8890-9465薇-STS5099)

    华纳圣淘沙公司开户分步图解

    首次开户必看:(183-8890-9465薇-STS5099)
    华纳圣淘沙全攻略

    华纳圣淘沙公司开户实操手册(183-8890-9465薇-STS5099)
    华纳圣淘沙开户流程视频教程

    手把手教学:(183-8890-9465薇-STS5099)
    华纳圣淘沙公司开户

    华纳圣淘沙公司开户完全指南(183-8890-9465薇-STS5099)

添加新评论