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)
}
博主真是太厉害了!!!
想想你的文章写的特别好https://www.jiwenlaw.com/
想想你的文章写的特别好https://www.237fa.com/
看的我热血沸腾啊https://www.ea55.com/
想想你的文章写的特别好www.jiwenlaw.com
兄弟写的非常好 https://www.cscnn.com/
《你好,星期六》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/142636.html
你的才华让人惊叹,你是我的榜样。 https://www.4006400989.com/qyvideo/44733.html
你的文章让我心情愉悦,真是太棒了! http://www.55baobei.com/G73qS08San.html
你的才华让人惊叹,你是我的榜样。 https://www.4006400989.com/qyvideo/44733.html
你的文章让我感受到了艺术的魅力,谢谢! http://www.55baobei.com/QOJBLKjtjr.html
你的文章内容非常用心,让人感动。 https://www.4006400989.com/qyvideo/40372.html
《遇见闪亮的自己第二季》大陆综艺高清在线免费观看:https://www.jgz518.com/xingkong/43972.html
你的文章让我学到了很多知识,非常感谢。 http://www.55baobei.com/vVODDKEFmN.html
《越过山丘》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/143923.html
每次看到你的文章,我都觉得时间过得好快。 https://www.yonboz.com/video/47480.html
看到你的文章,我仿佛感受到了生活中的美好。 https://www.yonboz.com/video/41393.html
你的文章让我感受到了正能量,非常棒! http://www.55baobei.com/9btoFjuMq4.html
你的文章充满了创意,真是让人惊喜。 https://www.4006400989.com/qyvideo/42652.html
你的文章让我感受到了正能量,非常棒! http://www.55baobei.com/4FTHhaXKAs.html
《出租车司机2017》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/22556.html
《越过山丘》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/143923.html
你的文章让我感受到了不一样的风景,谢谢分享。 https://www.yonboz.com/video/71949.html
你的文章让我感受到了不一样的风景,谢谢分享。 http://www.55baobei.com/VVnPUpilpI.html
《数学与美味的碰撞》连续剧高清在线免费观看:https://www.jgz518.com/xingkong/167563.html
哈哈哈,写的太好了https://www.lawjida.com/
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
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
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
华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?
华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?
华纳东方明珠客服电话是多少?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
华纳东方明珠开户专线联系方式?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
新盛客服电话是多少?(?183-8890-9465—《?薇-STS5099】【
新盛开户专线联系方式?(?183-8890--9465—《?薇-STS5099】【?扣6011643??】
新盛客服开户电话全攻略,让娱乐更顺畅!(?183-8890--9465—《?薇-STS5099】客服开户流程,华纳新盛客服开户流程图(?183-8890--9465—《?薇-STS5099】
新盛客服电话是多少?(?183-8890-9465—《?薇-STS5099】【
新盛开户专线联系方式?(?183-8890--9465—《?薇-STS5099】【?扣6011643??】
新盛客服开户电话全攻略,让娱乐更顺畅!(?183-8890--9465—《?薇-STS5099】客服开户流程,华纳新盛客服开户流程图(?183-8890--9465—《?薇-STS5099】
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
华纳圣淘沙开户步骤详解(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】
华纳圣淘沙开户步骤详解(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】
华纳圣淘沙公司开户新手教程
零基础学会(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)