123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- package jy
- import (
- "app.yhyue.com/moapp/jybase/sms"
- "encoding/json"
- "fmt"
- "log"
- "net/http"
- "regexp"
- "sort"
- "strings"
- "time"
- util "app.yhyue.com/moapp/jybase/common"
- . "app.yhyue.com/moapp/jybase/date"
- "app.yhyue.com/moapp/jybase/es"
- "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
- "app.yhyue.com/moapp/jybase/mail"
- . "app.yhyue.com/moapp/jybase/mongodb"
- "app.yhyue.com/moapp/jybase/redis"
- qrpc "app.yhyue.com/moapp/jybase/rpc"
- . "app.yhyue.com/moapp/jypkg/middleground"
- "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
- )
- // 获取用户合并以前,合并以后的openid
- func GetOldOpenid(s_m_openid, a_m_openid, s_phone string, mergeorder interface{}) string {
- a_mergeorder, _ := mergeorder.([]interface{})
- openid := ""
- if len(a_mergeorder) > 0 {
- first, _ := a_mergeorder[0].(string)
- if first == "s_m_openid" {
- openid = s_m_openid
- } else if first == "a_m_openid" {
- openid = a_m_openid
- } else if first == "s_phone" {
- openid = s_phone
- }
- } else {
- if s_m_openid != "" {
- openid = s_m_openid
- } else if a_m_openid != "" {
- openid = a_m_openid
- } else if s_phone != "" {
- openid = s_phone
- }
- }
- return openid
- }
- var ClearHtml = regexp.MustCompile("<[^>]*>")
- var MatchSpace = regexp.MustCompile("\\s+")
- var filterReg_3 = regexp.MustCompile("(项目|公告|公示)$")
- var filterReg_2 = regexp.MustCompile("^[)\\)>》】\\]}}〕,,;;::'\"“”。.\\??、/+=\\_—*&……\\^%$¥@!!`~·(\\(<《【\\[{{〔]+$")
- var filterReg_1 = regexp.MustCompile("^([0-9]{1,3}|[零一二三四五六七八九十]{1,2}|联系人?|电话|地址|编号|采购|政府采购|成交|更正|招标|中标|变更|结果)$")
- var filterReg = regexp.MustCompile("^[的人号时元万公告项目地址电话邮编日期联系招标中结果成交项目项目采购采购项目政府采购公告更正公告]+$")
- var PhoneReg = regexp.MustCompile("^[1][3-9][0-9]{9}$")
- var EmailPattern = regexp.MustCompile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")
- var filterReg_4 = regexp.MustCompile("([)>》】\\]\\}}〕。,,;;::'\"“”。\\.\\??、/\\+=\\\\_—\\*&……\\^%$¥@!!`~·(\\(<《【\\[\\{{〔])")
- // P279删除通用过滤词,例如“公告”
- func FilteKey(k string) string {
- k = strings.TrimSpace(k)
- // k = filterReg_3.ReplaceAllString(k, "")
- k = filterReg_4.ReplaceAllString(k, " ")
- // k = filterReg_1.ReplaceAllString(k, "")
- // k = filterReg.ReplaceAllString(k, "")
- return k
- }
- // InterceptSearchKW 超过20个字,截断
- // 返回截取后的字符串和截取掉中的前3个字
- func InterceptSearchKW(word string, keywordsLimit int, isFilter bool) (b_word, a_word, s_word string) {
- if word == "" {
- return
- }
- if isFilter {
- word = FilteKey(word)
- }
- word = MatchSpace.ReplaceAllString(strings.TrimSpace(word), " ")
- words := []rune(word)
- if len(words) > keywordsLimit {
- b_word = string(words[:keywordsLimit])
- b_word = strings.TrimSpace(b_word)
- if len(words) > keywordsLimit+3 {
- a_word = string(words[keywordsLimit : keywordsLimit+3])
- } else {
- a_word = string(words[keywordsLimit:])
- }
- } else {
- b_word = word
- }
- a_word = strings.TrimSpace(a_word)
- s_word = MatchSpace.ReplaceAllString(b_word, " ")
- return
- }
- func HttpEs(ques, analyzer, esAddress string) string {
- return es.Analyze(ques, "bidding", analyzer)
- }
- // 发送邮箱验证码
- func SendMailIdentCode(to, code string, auth []*mail.GmailAuth) bool {
- html := fmt.Sprintf(`<div>
- <div>
- %s,您好!
- </div>
- <div style="padding: 20px 70px 10px 70px;">
- <p>您正在进行绑定邮箱地址验证,请在邮件验证码输入框输入下方验证码:</p>
- <span style="font-weight: bold;font-size: x-large;">%s</span>
- <p>请勿向任何人泄露您收到的验证码。</p>
- <p>如果您没有使用剑鱼标讯,请忽略此邮件。</p>
- <p>此为系统邮件,请勿回复。</p>
- <p>如有疑问,请联系客服 400-108-6670。</p>
- </div>
- <div>
- <p>此致</p>
- <p>剑鱼标讯</p>
- </div>
- </div>`, to, code)
- for k, v := range auth {
- if mail.GSendMail("剑鱼标讯", to, "", "", "剑鱼标讯邮箱校验", html, "", "", v) {
- log.Println(to, fmt.Sprintf("使用%s发送邮件成功", v.User))
- return true
- }
- if k < len(auth)-1 {
- log.Println(to, fmt.Sprintf("使用%s发送邮件失败!3s后使用其他邮箱尝试", v.User))
- } else {
- log.Println(to, fmt.Sprintf("使用%s发送邮件失败!", v.User))
- }
- time.Sleep(time.Second * 3)
- }
- return false
- }
- func SendSMS(r *http.Request, address, mobile string, params ...string) {
- sms.SendSms(util.GetIp(r), address, "01", mobile, params...)
- return
- }
- // 发送验证码
- // 增加sessionKey字段 更换手机号防止绕过身份校验
- func SendPhoneIdentCode(r *http.Request, address, phone string, session *httpsession.Session, sessionKey ...string) bool {
- sessionKeyFlag := defaultPhoneFlag
- if len(sessionKey) > 0 && sessionKey[0] != "" {
- sessionKeyFlag = sessionKey[0]
- }
- lastSentTime := util.Int64All(session.Get(fmt.Sprintf("%sTime", sessionKeyFlag)))
- //60秒之内不允许重复发
- if lastSentTime > 0 && time.Now().Unix()-lastSentTime <= 60 {
- return false
- }
- s_ranNum := util.GetRandom(6) //生成随机数
- //s_ranNum = "111111"
- session.Set(fmt.Sprintf("%sValue", sessionKeyFlag), s_ranNum)
- session.Set(fmt.Sprintf("%sKey", sessionKeyFlag), phone)
- session.Set(fmt.Sprintf("%sTime", sessionKeyFlag), time.Now().Unix())
- //发送短信
- log.Println("短信验证码", phone, s_ranNum)
- SendSMS(r, address, phone, s_ranNum)
- return true
- }
- const (
- defaultPhoneFlag = "identCode"
- ExperienceSign = "EXPERIENCESIGN"
- )
- // 短信验证码校验
- func CheckPhoneIdent(session *httpsession.Session, code string, sessionKey ...string) string {
- sessionKeyFlag := defaultPhoneFlag
- if len(sessionKey) > 0 && sessionKey[0] != "" {
- sessionKeyFlag = sessionKey[0]
- }
- identCodeValue, _ := session.Get(fmt.Sprintf("%sValue", sessionKeyFlag)).(string)
- if identCodeValue != "" && identCodeValue == code {
- identCodeKey, _ := session.Get(fmt.Sprintf("%sKey", sessionKeyFlag)).(string)
- ClearPhoneIdentSession(session, sessionKey...)
- return identCodeKey
- }
- return ""
- }
- // 删除短信验证码有关的session
- func ClearPhoneIdentSession(session *httpsession.Session, sessionKey ...string) {
- sessionKeyFlag := defaultPhoneFlag
- if len(sessionKey) > 0 && sessionKey[0] != "" {
- sessionKeyFlag = sessionKey[0]
- }
- session.Del(fmt.Sprintf("%sValue", sessionKeyFlag))
- session.Del(fmt.Sprintf("%sKey", sessionKeyFlag))
- session.Del(fmt.Sprintf("%sTime", sessionKeyFlag))
- }
- // 邮箱校验
- func IsEmail(value string) bool {
- return EmailPattern.MatchString(value)
- }
- // 手机号校验
- func IsPhone(phone string) bool {
- return PhoneReg.MatchString(phone)
- }
- // 获取信息行业
- func Getindustrys(industryname string, mongodb MongodbSim) (industry map[string][]string, sortArray []string) {
- industry = map[string][]string{}
- sortArray = []string{}
- classdata, ok1 := mongodb.FindOneByField("rc_task", `{"s_name":"`+industryname+`"}`, `{"s_class":1}`)
- if ok1 && len(*classdata) > 0 {
- classid := ""
- if util.ObjToString((*classdata)["s_class"]) != "" {
- classids := strings.Split(util.ObjToString((*classdata)["s_class"]), ",")
- for k, v := range classids {
- if k > 0 {
- classid += `,`
- }
- classid += `"` + v + `"`
- }
- }
- industryData, ok := mongodb.Find("rc_rule", `{"s_pid":{"$ne":""},"s_classid":{"$in":[`+classid+`]}}`, `{"i_order":1}`, `{"_id":1,"s_name":1}`, false, -1, -1)
- if ok && industryData != nil && len(*industryData) > 0 {
- for _, v := range *industryData {
- fatFlag := 0
- industryname, _ := v["s_name"].(string)
- if strings.Contains(industryname, "_") {
- fat := strings.Split(industryname, "_")[0]
- child := strings.Split(industryname, "_")[1]
- if len(industry[fat]) == 0 {
- sortArray = append(sortArray, fat)
- }
- for _, fv := range industry[fat] {
- if fv == strings.Trim(child, " ") {
- fatFlag = 1
- break
- }
- }
- if fatFlag != 1 {
- industry[fat] = append(industry[fat], child)
- }
- }
- }
- }
- }
- return industry, sortArray
- }
- // 对应月份
- func GetMonth(mon string) int {
- month := map[string]int{
- "January": 1,
- "February": 2,
- "March": 3,
- "April": 4,
- "May": 5,
- "June": 6,
- "July": 7,
- "August": 8,
- "September": 9,
- "October": 10,
- "November": 11,
- "December": 12,
- }
- return month[mon]
- }
- // value unlimited 并发限制登陆用户
- func LoginRedisKey(userid string) string {
- return fmt.Sprintf("unlimited_%s", userid)
- }
- // 获取loginSess
- func GetLoginSess(userid string) []string {
- key := LoginRedisKey(userid)
- if data, ok := redis.Get("other", key).([]interface{}); ok {
- return util.ObjArrToStringArr(data)
- }
- return []string{}
- }
- // 判断是否在内
- func IsInLoginSess(key string, arr []string) bool {
- for _, v := range arr {
- if key == v {
- return true
- }
- }
- return false
- }
- type TtlMap struct {
- key string //sessionid
- value int //ttl
- }
- type AppLoginPush struct {
- JgPushId string `json:"jpushId"`
- OtherPushId string `json:"opushId"`
- PhoneType string `json:"phoneType"`
- }
- // 更新存储用户sessionid的队列 【sessionid ttl小于三天的清除】 key:sessionid
- func PutLoginSess(mongodb MongodbSim, apppushRpc, key, userid string, limit, max int) bool {
- value := GetLoginSess(userid)
- if !IsInLoginSess(key, value) {
- value = append(value, key)
- }
- ttlmap := []TtlMap{}
- if len(value) >= int(limit*max/100) {
- new_value := []string{}
- //如果已存的session大于限制 则清除三天后到期的session
- for _, vv := range value {
- ttl := redis.GetTTL("session", vv)
- if ttl <= 86400*1 && ttl != -1 {
- // if ttl <= 600 && ttl != -1 {
- if ok := redis.Del("session", vv); ok {
- LoginOutPush(mongodb, userid, vv, apppushRpc)
- log.Println(fmt.Sprintf("%s用户的sessionid 到期时间还有%v 小于三天 清除 %s", userid, ttl, vv))
- }
- continue
- }
- new_value = append(new_value, vv)
- ttlmap = append(ttlmap, TtlMap{vv, int(ttl)})
- }
- value = new_value
- }
- //清除并发最大限制的某个sessionid
- if len(value) > max {
- //排序 获取马上过期的session 清除
- sort.Slice(ttlmap, func(i, j int) bool {
- return ttlmap[i].value < ttlmap[j].value
- })
- if len(ttlmap) > 0 {
- //清除sessionid
- delId := ttlmap[0].key
- redis.Del("session", delId)
- value = removeArr(value, delId)
- LoginOutPush(mongodb, userid, delId, apppushRpc)
- log.Println(fmt.Sprintf("%s用户的sessionid 超过最大限制 清除 %s ,到期时间%v", userid, delId, ttlmap[0].value))
- for _, v := range ttlmap {
- log.Println(v.key, "===", v.value)
- }
- }
- }
- return redis.Put("other", LoginRedisKey(userid), value, -1)
- }
- // 清除数组中的s
- func removeArr(arr []string, s string) []string {
- result := []string{}
- for _, v := range arr {
- if v == s {
- continue
- }
- result = append(result, v)
- }
- return result
- }
- func LoginOutPush(mongodb MongodbSim, userid, sessid, apppushRpc string) {
- rediskey := fmt.Sprintf("app_%s", sessid)
- r := redis.Get("other", rediskey)
- if r == nil {
- return
- }
- arr, err := json.Marshal(r)
- if err != nil {
- log.Println("json Marshal err:", err)
- }
- apppush := AppLoginPush{}
- // 反序列化
- err2 := json.Unmarshal(arr, &apppush)
- if err2 != nil {
- log.Println("json Unmarshal err:", err)
- }
- if apppush.JgPushId == "" {
- return
- }
- mongodb.UpdateById("user", userid, map[string]interface{}{
- "$unset": map[string]interface{}{"s_jpushid": "", "s_opushid": ""},
- "$addToSet": map[string]interface{}{"a_jpushid": apppush.JgPushId},
- })
- //
- log.Println("多账号登陆:", userid, apppush.PhoneType, apppush.JgPushId, apppush.OtherPushId, "踢人下线")
- ok := qrpc.AppPush(apppushRpc, map[string]interface{}{
- "type": "signOut",
- "descript": "您的账号在其他设备登录,如有需要请重新登录。",
- "jgPushId": apppush.JgPushId,
- "otherPushId": apppush.OtherPushId,
- "phoneType": apppush.PhoneType,
- "userId": userid,
- })
- log.Println("ok:", ok)
- }
- // session数组清除某个value[针对多账号同时在线的方法、退出登录时调用]
- func DelUnlimitSessionId(sessid, userid string) []string {
- sessArr := GetLoginSess(userid)
- newArr := []string{}
- for _, v := range sessArr {
- if v == sessid {
- continue
- }
- newArr = append(newArr, v)
- }
- return newArr
- }
- // 获取当天结束时间 单位秒
- func GetExpire() int {
- t, _ := time.ParseInLocation(Date_Short_Layout, time.Now().AddDate(0, 0, 1).Format(Date_Short_Layout), time.Local)
- t2, _ := time.ParseInLocation(Date_Full_Layout, time.Now().Format(Date_Full_Layout), time.Local)
- return int(t.Unix() - t2.Unix())
- }
- func TimeProcessing(hour interface{}, duration int) time.Time {
- todayZero, _ := time.ParseInLocation(Date_Full_Layout, fmt.Sprint(hour), time.Local)
- mm, _ := time.ParseDuration(fmt.Sprint(duration) + "m")
- t := todayZero.Add(mm)
- return t
- }
- // 清除用户权益缓存、菜单缓存
- func ClearUserCache(middleground *Middleground, positionId int64) {
- middleground.UserCenter.WorkDesktopClearUserInfo(pb.WorkDesktopClearUserInfoReq{
- PositionId: fmt.Sprint(positionId),
- })
- middleground.PowerCheckCenter.DelCheckRedis("10000", positionId)
- }
- // 关键词分词处理
- func KeywordsProcessing(keywords, originalWord, sep string) string {
- keywords = MatchSpace.ReplaceAllString(keywords, " ")
- if keywords == "" || len(strings.Split(keywords, sep)) == 1 {
- return keywords
- }
- if originalWord == "" {
- originalWord = strings.ReplaceAll(keywords, sep, "")
- }
- var newWords = make([]string, 0, 0)
- if keywords != "" && len(strings.Split(keywords, sep)) > 1 {
- var words = strings.Split(keywords, sep)
- for k := 0; k < len(words); k++ {
- v := words[k]
- //连续性空格
- if len([]rune(v)) == 0 {
- continue
- }
- if len([]rune(v)) == 1 {
- //compare
- if k == 0 { //first
- newWord := v + words[k+1]
- if strings.Contains(originalWord, newWord) { //组合后 必须包含
- words[k+1] = newWord
- }
- } else if k == len(words)-1 { //last
- newWord := newWords[len(newWords)-1] + v
- if strings.Contains(originalWord, newWord) {
- newWords[len(newWords)-1] = newWord
- }
- } else {
- if len([]rune(newWords[len(newWords)-1])) < len([]rune(words[k+1])) {
- newWord := newWords[len(newWords)-1] + v
- if strings.Contains(originalWord, newWord) {
- newWords[len(newWords)-1] = newWord
- } else {
- newWord = v + words[k+1]
- if strings.Contains(originalWord, newWord) { //组合后 必须包含
- words[k+1] = newWord
- }
- }
- } else {
- newWord := v + words[k+1]
- if strings.Contains(originalWord, newWord) { //组合后 必须包含
- words[k+1] = newWord
- } else {
- newWord = newWords[len(newWords)-1] + v
- if strings.Contains(originalWord, newWord) {
- newWords[len(newWords)-1] = newWord
- }
- }
- }
- }
- } else {
- newWords = append(newWords, v)
- }
- }
- }
- return strings.Join(newWords, sep)
- }
- // 行业分类 其它分类处理
- var industryQT = "其它"
- func IndustryHandle(industry string) (it []string) {
- for _, v := range strings.Split(industry, ",") {
- if strings.Contains(v, "其他") {
- var iqt = industryQT
- if len(strings.Split(v, "_")) > 1 {
- iqt = fmt.Sprintf("%s_%s", strings.Split(v, "_")[0], industryQT)
- }
- it = append(it, iqt)
- }
- }
- return
- }
|