package p import ( "encoding/json" "fmt" "net/http" "reflect" "sort" "strconv" "strings" "sync" "time" . "app.yhyue.com/moapp/jybase/common" util "app.yhyue.com/moapp/jybase/common" . "app.yhyue.com/moapp/jybase/date" "app.yhyue.com/moapp/jybase/es" "app.yhyue.com/moapp/jybase/logger" . "app.yhyue.com/moapp/jybase/mongodb" . "app.yhyue.com/moapp/jybase/mysql" "app.yhyue.com/moapp/jybase/redis" rcDb "bp.jydev.jianyu360.cn/BaseService/resourceCenter/public/db" rcService "bp.jydev.jianyu360.cn/BaseService/resourceCenter/public/service" . "bp.jydev.jianyu360.cn/BaseService/userCenter/identity" ) //金额转化 金额:0-万元以下单位为元 ,万元以上至亿元以下单位为万元 ,亿元以上单位为亿元。保留 小数点后 2 位,不进行四舍五入。 func ConversionMoney(i_money interface{}) string { m := "" if reflect.TypeOf(i_money).Name() == "float64" { m = strconv.FormatFloat(Float64All(i_money), 'f', -1, 64) } else { m = ObjToString(i_money) } if m == "" { return m } m_arr := strings.Split(m, ".") m_1 := m_arr[0] len_m1 := len([]rune(m_1)) if len_m1 >= 9 { m = m_1[0:len_m1-8] + "." + m_1[len_m1-8:len_m1-6] + "亿元" } else if len_m1 >= 5 { m = m_1[0:len_m1-4] + "." + m_1[len_m1-4:len_m1-2] + "万元" } else { if len(m_arr) == 1 { return m + ".00元" } m_2 := m_arr[1] if len([]rune(m_2)) > 1 { m_2 = m_2[0:2] } else { m_2 = m_2[0:1] + "0" } m = m_1 + "." + m_2 + "元" } return m } //微信模板消息 remark func WxTplRemark(titles []string, lastTime int64, hasLen int) string { tip := "" second := time.Now().Unix() - lastTime if second > 0 { if second < 61 { tip = fmt.Sprintf("%d秒前发布的:\n", second) } else { second = second / 60 if second < 121 { if second < 1 { second = 1 } tip = fmt.Sprintf("%d分钟前发布的:\n", second) } } } lastTip := "" if len(titles) > 1 { lastTip = fmt.Sprintf("...(共%d条)", len(titles)) } reLen := 199 - hasLen - len([]rune(tip)) lastTipLen := len([]rune(lastTip)) wxTplMsgTitle := "" bshow := false for n := 1; n < len(titles)+1; n++ { curTitle := titles[n-1] tmptitle := wxTplMsgTitle + fmt.Sprintf("%d %s\n", n, curTitle) ch := reLen - len([]rune(tmptitle)) if ch < lastTipLen { //加上后大于后辍,则没有完全显示 if ch == 0 && n == len(titles) { wxTplMsgTitle = tmptitle bshow = true } else { ch_1 := reLen - len([]rune(wxTplMsgTitle)) - lastTipLen if ch_1 > 8 { curLen := len([]rune(curTitle)) if ch_1 > curLen { ch_1 = curLen } wxTplMsgTitle += fmt.Sprintf("%d %s\n", n, string([]rune(curTitle)[:ch_1-3])) } } } else { wxTplMsgTitle = tmptitle if n == len(titles) { bshow = true } } } if bshow { lastTip = "" } return tip + wxTplMsgTitle + lastTip } //获取信息行业 func GetSubScopeClass(subscopeclass interface{}) string { industry := "" if subscopeclass != nil { k2sub := strings.Split(ObjToString(subscopeclass), ",") if len(k2sub) > 0 { industry = k2sub[0] if industry != "" { ss := strings.Split(industry, "_") if len(ss) > 1 { industry = ss[0] } } } } return industry } //控制一分钟最大推送数,均匀调度 func LimitMaxOneMinutePush(pushPoll *chan bool, maxOneMinute int) { max := int(maxOneMinute / 60) *pushPoll = make(chan bool, max) go func() { for { time.Sleep(time.Second) for i := 0; i < max; i++ { select { case *pushPoll <- true: default: continue } } } }() } // func UpdateUserIsPush(Mgo *MongodbSim, userId string, err error) { if err == nil { return } if strings.Contains(err.Error(), "[43004]") { Mgo.UpdateById("user", userId, map[string]interface{}{ "$set": map[string]interface{}{ "i_ispush": 0, }, }) } } //查找我的子账号 func MySonAccounts(Mgo *MongodbSim, coll, userId string, field map[string]interface{}) *[]map[string]interface{} { users, _ := Mgo.Find(coll, map[string]interface{}{ "i_member_sub_status": 1, "s_member_mainid": userId, "i_member_status": map[string]interface{}{"$gt": 0}, }, nil, field, false, -1, -1) if users == nil { users = &[]map[string]interface{}{} } return users } //是否购买此服务 func HasService(msl *Mysql, userId string, params ...int) *MemberService { args := []interface{}{} ws := []string{} for _, v := range params { args = append(args, v) ws = append(ws, "?") } args = append(args, args...) args = append(args, userId, NowFormat(Date_Full_Layout)) list := msl.SelectBySql(`SELECT a.l_starttime,b.id from jianyu.bigmember_service_user a INNER JOIN jianyu.bigmember_service b on (((b.id in (`+strings.Join(ws, ",")+`) and a.s_serviceid=b.id) or (b.i_pid in (`+strings.Join(ws, ",")+`) and a.s_serviceid=b.i_pid)) and b.i_status=0 and a.s_userid=? and a.i_status=0 and a.l_endtime>?)`, args...) ms := &MemberService{ Services: map[int]*memberService{}, } if list != nil { for _, v := range *list { ms.IsBuy = true id := util.IntAll(v["id"]) ms.Services[id] = &memberService{ Id: id, StartTime: util.ObjToString(v["l_starttime"]), } } } return ms } // func GetInfoTitle(info map[string]interface{}) string { title, _ := info["title"].(string) jsondata, _ := info["jsondata"].(map[string]interface{}) if jsondata != nil { goods, _ := jsondata["goods"].(string) title += goods } title = strings.ToUpper(title) return title } //加载数据到内存中 func LoadBidding(mgo *MongodbSim, dbName, coll, incField string, startTime, maxSize int64, redisCache bool, query, fields map[string]interface{}) (*[]map[string]interface{}, int64) { defer util.Catch() endTime := time.Now().Unix() if query == nil || len(query) == 0 { query = map[string]interface{}{ incField: map[string]interface{}{ "$gte": startTime, "$lt": endTime, }, } } logger.Info("开始加载", coll, "数据", query) queryField := map[string]interface{}{ "title": 1, "detail": 1, "purchasing": 1, "projectname": 1, "projectcode": 1, "buyer": 1, "buyerperson": 1, "buyertel": 1, "s_winner": 1, "agency": 1, "bidopentime": 1, "projectscope": 1, "publishtime": 1, "toptype": 1, "subtype": 1, "area": 1, "s_subscopeclass": 1, "city": 1, "district": 1, "buyerclass": 1, "jsondata": 1, "budget": 1, "bidamount": 1, "isValidFile": 1, "site": 1, "agencyperson": 1, "agencytel": 1, "winnerperson": 1, "winnertel": 1, "signendtime": 1, "bidendtime": 1, "entidlist": 1, "autoid": 1, } if fields != nil { for k, v := range fields { if util.IntAll(v) == 0 { delete(queryField, k) } else { queryField[k] = v } } } var res []map[string]interface{} sess := mgo.GetMgoConn() defer mgo.DestoryMongoConn(sess) it := sess.DB(dbName).C(coll).Find(query).Select(queryField).Iter() var index int64 for temp := make(map[string]interface{}); it.Next(&temp); { _id := BsonIdToSId(temp["_id"]) if publishtime := util.Int64All(temp["publishtime"]); startTime-publishtime > 7*86400 { logger.Info(_id, "发布时间大于7天,不参与匹配", startTime, publishtime) continue } temp["_id"] = _id title, _ := temp["title"].(string) title = strings.ReplaceAll(title, "\n", "") temp["title"] = title if util.ObjToString(temp["area"]) == "A" { temp["area"] = "全国" } temp["attachment_count"] = GetAttachmentCount(temp) res = append(res, temp) if redisCache { //信息缓存3天 info := map[string]interface{}{} for _, v := range SaveBiddingField { if v == "_id" || temp[v] == nil { continue } info[v] = temp[v] } if temp["detail"] != nil { info["detail"] = temp["detail"] } redis.Put(Pushcache_1, "info_"+_id, info, OneDaySecond) } temp = make(map[string]interface{}) index++ if index%500 == 0 { logger.Info("加载", coll, "数据:", index) } if maxSize > 0 && index == maxSize { break } } if util.IntAll(queryField["filetext"]) > 0 { BiddingRepair(res, "filetext") } logger.Info(coll, "数据已经加载结束。。。", index) return &res, endTime } // func BiddingRepair(res []map[string]interface{}, fields string) { array := []map[string]interface{}{} for _, v := range res { array = append(array, v) if len(array) == 50 { OnceBiddingRepair(array, fields) array = []map[string]interface{}{} } } if len(array) > 0 { OnceBiddingRepair(array, fields) array = []map[string]interface{}{} } } // func OnceBiddingRepair(array []map[string]interface{}, fields string) { if es.VarEs == nil { return } ids := []string{} for _, v := range array { ids = append(ids, fmt.Sprintf(`"%s"`, util.ObjToString(v["_id"]))) } m := map[string]map[string]interface{}{} list := es.VarEs.Get(Es_Bidding, Es_Bidding, fmt.Sprintf(Es_Query_By_Ids, strings.Join(ids, ","), fields, len(ids))) if list == nil { return } for _, v := range *list { m[util.ObjToString(v["_id"])] = v } for _, v := range array { obj := m[util.ObjToString(v["_id"])] if obj == nil { continue } for kk, vv := range obj { v[kk] = vv } } } // func ToSortList(list interface{}) *SortList { sl := make(SortList, 0) if list == nil { return &sl } b, err := json.Marshal(list) if err != nil { return &sl } err = json.Unmarshal(b, &sl) if err != nil { return &sl } sort.Sort(sl) return &sl } //第一个参数是老数据,第二个参数是新进数据 func MergeSortList(o, n interface{}, maxPushSize int) *SortList { of, oo := o.(*SortList) if !oo { of = ToSortList(o) } nf, no := n.(*SortList) if !no { nf = ToSortList(n) } idMap := map[string]bool{} for _, v := range *nf { idMap[util.ObjToString(v.Info["_id"])] = true } for _, v := range *of { if idMap[util.ObjToString(v.Info["_id"])] { continue } *nf = append(*nf, v) } sort.Sort(nf) if maxPushSize > 0 && len(*nf) > maxPushSize { *nf = (*nf)[:maxPushSize] } return nf } //获取招标信息附件数量 func GetAttachmentCount(temp map[string]interface{}) int { isValidFile, _ := temp["isValidFile"].(bool) if isValidFile { return 1 } return 0 } //获取招标信息附件数量 func GetAttachmentCountById(mgo *MongodbSim, dbName, coll, _id string) int { sess := mgo.GetMgoConn() defer mgo.DestoryMongoConn(sess) temp := map[string]interface{}{} sess.DB(dbName).C(coll).Find(map[string]interface{}{ "_id": StringTOBsonId(_id), }).Select(map[string]interface{}{ "isValidFile": 1, }).One(&temp) if temp != nil { return GetAttachmentCount(temp) } return -1 } // func NewBiddingInfo(info map[string]interface{}, keys []string) *BiddingInfo { bi := &BiddingInfo{} bi.Title, _ = info["title"].(string) bi.ClearTitle = TitleClearRe.ReplaceAllString(strings.Replace(bi.Title, "\n", "", -1), "$1") bi.Area, _ = info["area"].(string) if bi.Area == "A" { bi.Area = "全国" } bi.AreaTitle = fmt.Sprintf("[%s]%s", bi.Area, bi.ClearTitle) bi.Publishtime = util.Int64All(info["publishtime"]) bi.PublishtimeYMD = FormatDateByInt64(&bi.Publishtime, Date_Short_Layout) bi.PublishtimeDiff = util.TimeDiff(time.Unix(bi.Publishtime, 0)) bi.Buyerclass, _ = info["buyerclass"].(string) bi.Subscopeclass = GetSubScopeClass(info["s_subscopeclass"]) bi.Bidamount = info["bidamount"] bi.Budget = info["budget"] if bi.Bidamount != nil { bi.Acount = ConversionMoney(bi.Bidamount) } else if bi.Budget != nil { bi.Acount = ConversionMoney(bi.Budget) } bi.Id, _ = info["_id"].(string) bi.AutoId = Int64All(info["autoid"]) bi.Subtype, _ = info["subtype"].(string) bi.Toptype, _ = info["toptype"].(string) bi.Infotype = bi.Subtype if bi.Infotype == "" { bi.Infotype = bi.Toptype } bi.HighlightTitle = bi.ClearTitle for _, kw := range keys { kws := strings.Split(kw, "+") n := 0 otitle := bi.HighlightTitle for _, kwn := range kws { ot := strings.Replace(otitle, kwn, ""+kwn+"", 1) if ot != bi.HighlightTitle { n++ otitle = ot } else { break } } if n == len(kws) { bi.HighlightTitle = otitle break } } return bi } // func SortListSplit(list *SortList, f func(v interface{})) { l := len(*list) if l == 0 { return } i := Mgo_ListSize for { if l > i { arr := (*list)[i-Mgo_ListSize : i] f(&arr) } else if l > i-Mgo_ListSize { arr := (*list)[i-Mgo_ListSize:] f(&arr) break } i += Mgo_ListSize } } // func CSortListSplit(list *CSortList, f func(v interface{})) { l := len(*list) if l == 0 { return } i := Mgo_ListSize for { if l > i { arr := (*list)[i-Mgo_ListSize : i] f(&arr) } else if l > i-Mgo_ListSize { arr := (*list)[i-Mgo_ListSize:] f(&arr) break } i += Mgo_ListSize } } //获取企业授权超级订阅/大会员的用户 func LoadEntProductUsers(msl *Mysql, testUserIds []int) (map[string]*UserInfo, map[int]*UserInfo, map[int]*UserInfo, []*UserInfo) { logger.Info("开始加载企业授权用户。。。") phoneMap := map[string]*UserInfo{} userMap := map[int]*UserInfo{} entMap := map[int]*UserInfo{} all := []*UserInfo{} query := `SELECT DISTINCT a.ent_id,IF(instr(a.product_type,'` + Ent_EmpowerMember + `')>0,'` + Ent_EmpowerMember + `','` + Ent_EmpowerVip + `') as product_type,c.phone,b.ent_user_id,d.name as ent_name,d.power_source,d.isNew from jianyu.entniche_wait_empower a inner join jianyu.entniche_power b on (a.end_time>? and b.status=1 and (a.product_type like '%` + Ent_EmpowerVip + `%' or a.product_type like '%` + Ent_EmpowerMember + `%') and a.id=b.wait_empower_id) inner join jianyu.entniche_user c on (` if len(testUserIds) > 0 { array := []string{} for _, v := range testUserIds { array = append(array, fmt.Sprint(v)) } query += `c.id in (` + strings.Join(array, ",") + `) and ` } query += `b.ent_user_id=c.id) inner join jianyu.entniche_info d on (d.id=a.ent_id)` msl.SelectByBath(200, func(l *[]map[string]interface{}) bool { for _, v := range *l { phone, _ := v["phone"].(string) if phone == "" { continue } u := &UserInfo{ Entniche: &Entniche{ EntId: util.IntAll(v["ent_id"]), EntName: util.ObjToString(v["ent_name"]), UserId: util.IntAll(v["ent_user_id"]), ProductType: util.ObjToString(v["product_type"]), PowerSource: util.IntAll(v["power_source"]), IsNew: util.IntAll(v["isNew"]), }, Phone: phone, } if strings.Contains(u.Entniche.ProductType, Ent_EmpowerMember) { u.MemberStatus = 1 } else if strings.Contains(u.Entniche.ProductType, Ent_EmpowerVip) { u.VipStatus = 1 } else { continue } phoneMap[phone] = u userMap[u.Entniche.UserId] = u all = append(all, u) entMap[u.Entniche.EntId] = u logger.Info("加载企业授权用户", u.Entniche.EntName, u.Entniche.EntId, u.Entniche.UserId, u.Entniche.ProductType, u.Phone) } return true }, query, NowFormat(Date_Full_Layout)) logger.Info("企业授权用户加载结束。。。", len(phoneMap), len(userMap), len(entMap), len(all)) return phoneMap, userMap, entMap, all } //加载商机管理用户 func LoadEntnicheUsers(msl *Mysql) map[string]bool { logger.Info("开始加载新版商机管理用户。。。") r := map[string]bool{} msl.SelectByBath(200, func(l *[]map[string]interface{}) bool { for _, v := range *l { phone := util.ObjToString(v["phone"]) if phone != "" { r[phone] = true logger.Info("加载商机管理用户", phone) } } return true }, `SELECT b.phone from jianyu.entniche_info a INNER JOIN jianyu.entniche_user b on (a.status=1 and a.power_source is null and b.power=1 and a.id=b.ent_id)`) logger.Info("商机管理用户加载结束。。。", len(r)) return r } // func GetWxTplMsg(subSet *SubSet) (string, string) { keyword := strings.Join(subSet.Keys, " ") if len([]rune(keyword)) > 100 { keyword = string([]rune(keyword)[:100]) + "..." } area := strings.Join(subSet.Areas, " ") if len([]rune(area)) > 100 { area = string([]rune(area)[:100]) + "..." } if area == "" { area = "全国" } return keyword, area } // func GetPhone(u map[string]interface{}) string { phone := util.ObjToString(u["s_phone"]) if phone == "" { phone = util.ObjToString(u["s_m_phone"]) } return phone } // func GetAllByEntUserId(mgo *MongodbSim, msl *Mysql, entUserId int) *map[string]interface{} { entUsers := msl.SelectBySql(`select phone from jianyu.entniche_user where id=?`, entUserId) if entUsers == nil || len(*entUsers) == 0 { logger.Info("entniche_user表中没有找到该企业用户", entUserId) return nil } phone, _ := (*entUsers)[0]["phone"].(string) if phone == "" { return nil } return getEntPushSet(mgo, msl, entUserId, phone) } // func GetAllByEntPositionId(mgo *MongodbSim, msl *Mysql, positionId int) *map[string]interface{} { position := msl.SelectBySql(`select a.ent_id,b.phone from base_service.base_position a inner join base_service.base_user b on (a.id=? and a.user_id=b.id)`, positionId) if position == nil || len(*position) == 0 { logger.Info("无效的职位id", position) return nil } entId := util.Int64All((*position)[0]["ent_id"]) if entId == 0 { logger.Info("该职位id没有找到对应的企业id", position) return nil } phone, _ := (*position)[0]["phone"].(string) if phone == "" { logger.Info("该职位id没有找到对应的手机号", position) return nil } entUsers := msl.SelectBySql(`select id from jianyu.entniche_user where phone=? and ent_id=?`, phone, entId) if entUsers == nil || len(*entUsers) == 0 { logger.Info("entniche_user表中没有找到该企业用户", phone, entId) return nil } return getEntPushSet(mgo, msl, util.IntAll((*entUsers)[0]["id"]), phone) } // func getEntPushSet(mgo *MongodbSim, msl *Mysql, entUserId int, phone string) *map[string]interface{} { users, ok := mgo.Find(Mgo_User, map[string]interface{}{ "$or": []map[string]interface{}{ map[string]interface{}{ "s_phone": phone, }, map[string]interface{}{ "s_m_phone": phone, }, }, }, `{"s_phone":-1}`, map[string]interface{}{ "_id": 1, "s_m_openid": 1, "a_m_openid": 1, "s_phone": 1, "s_m_phone": 1, "i_ispush": 1, "s_jpushid": 1, "s_opushid": 1, "s_appponetype": 1, "base_user_id": 1, }, false, -1, -1) if !ok || users == nil || len(*users) == 0 { logger.Info("user表中没有找到该企业用户", entUserId, phone) return nil } user := map[string]interface{}{} for _, v := range *users { if user["_id"] == nil { user["_id"] = v["_id"] user["base_user_id"] = v["base_user_id"] } if user["s_phone"] == nil && util.ObjToString(v["s_phone"]) != "" { user["s_phone"] = v["s_phone"] } if user["s_m_phone"] == nil && util.ObjToString(v["s_m_phone"]) != "" { user["s_m_phone"] = v["s_m_phone"] } if user["a_m_openid"] == nil && util.ObjToString(v["a_m_openid"]) != "" { user["a_m_openid"] = v["a_m_openid"] } s_m_openid := util.ObjToString(v["s_m_openid"]) i_ispush := util.IntAll(v["i_ispush"]) s_jpushid := util.ObjToString(v["s_jpushid"]) s_opushid := util.ObjToString(v["s_opushid"]) s_appponetype := util.ObjToString(v["s_appponetype"]) if user["s_m_openid"] == nil && user["i_ispush"] == nil && s_m_openid != "" && i_ispush == 1 { user["s_m_openid"] = s_m_openid user["i_ispush"] = i_ispush } if user["s_jpushid"] == nil && user["s_opushid"] == nil && user["s_appponetype"] == nil && s_appponetype != "" && (s_jpushid != "" || s_opushid != "") { user["s_jpushid"] = s_jpushid user["s_opushid"] = s_opushid user["s_appponetype"] = s_appponetype } } entniche_user, ok := mgo.FindOneByField(Mgo_Ent_User, map[string]interface{}{ "i_userid": entUserId, }, `{"_id":0,"i_member_status":1,"i_vip_status":1,"o_pushset":1}`) if ok && entniche_user != nil && len(*entniche_user) > 0 { for k, v := range *entniche_user { user[k] = v } } entniche_rule, ok := mgo.Find("entniche_rule", map[string]interface{}{ "i_userid": entUserId, }, nil, `{"_id":0,"o_entniche":1,"i_type":1}`, false, -1, -1) if ok && entniche_rule != nil { for _, v := range *entniche_rule { i_type := util.IntAll(v["i_type"]) if i_type == 0 { user["o_entniche"] = v["o_entniche"] } else if i_type == 1 { user["o_vipjy"] = v["o_entniche"] user["o_member_jy"] = v["o_entniche"] } else if i_type == 2 { user["o_jy"] = v["o_entniche"] } } } return &user } // func GetEntUserPushset(mgo *MongodbSim, entUserId int) map[string]interface{} { temp, ok := mgo.FindOneByField(Mgo_Ent_User, map[string]interface{}{ "i_userid": entUserId, }, `{"o_pushset":1}`) if ok && temp != nil && len(*temp) > 0 { o_pushset, _ := (*temp)["o_pushset"].(map[string]interface{}) return o_pushset } return nil } // func GetEntUserSubset(mgo *MongodbSim, entUserId, tp int) map[string]interface{} { temp, ok := mgo.FindOneByField("entniche_rule", map[string]interface{}{ "i_userid": entUserId, "i_type": tp, }, `{"o_entniche":1}`) if ok && temp != nil && len(*temp) > 0 { o_msgset, _ := (*temp)["o_entniche"].(map[string]interface{}) return o_msgset } return nil } //格式化小时 func HourFormat(hour int) string { if hour < 10 { return fmt.Sprintf("0%d:00", hour) } else { return fmt.Sprintf("%d:00", hour) } } //数组中的小时是否结束 func TimesIsOver(times []string, hour int) (bool, time.Time, time.Time) { now := time.Now() if len(times) == 0 { return false, now, now } sort.Strings(times) lastHour := util.IntAll(strings.Split(times[len(times)-1], ":")[0]) //跨天 if lastHour == 23 && hour == 0 { start := time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, time.Local) end := time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 0, time.Local) return true, start, end } else { start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local) return hour-1 == lastHour, start, now } } //监听超时 func MonitorTimeOut(pool chan bool, timeout time.Duration, warn string, f func()) bool { select { case <-time.After(timeout): go func() { f() if warn != "" { if _, err := http.Get(warn); err != nil { logger.Error("发送告警邮件错误", err) } } }() return false case pool <- true: } return true } //根据职位id获取用户信息 func GetUserInfoByPosition(msl *Mysql, mgo *MongodbSim, id int64) *UserInfo { list := msl.SelectBySql(`select user_id from base_service.base_position where id=?`, id) if list == nil || len(*list) == 0 { return nil } data, ok := mgo.FindOneByField("user", map[string]interface{}{ "base_user_id": util.Int64All((*list)[0]["user_id"]), }, `{"_id":1}`) if !ok || data == nil || len(*data) == 0 { return nil } return &UserInfo{ Id: BsonIdToSId((*data)["_id"]), } } //资源中台权益 var rcpLock = &sync.Mutex{} func ResourceCenterPowers(msl *Mysql, positionId int64) map[string]bool { rcpLock.Lock() if rcDb.Mysql_BaseService == nil { rcDb.Mysql_BaseService = &Mysql{ Address: msl.Address, UserName: msl.UserName, PassWord: msl.PassWord, DBName: "base_service", MaxOpenConns: msl.MaxOpenConns, MaxIdleConns: msl.MaxIdleConns, } rcDb.Mysql_BaseService.Init() } rcpLock.Unlock() powers := map[string]bool{} if identity := IdentityByPositionId(msl, positionId); identity != nil { list, _ := rcService.HasPowers("10000", identity.AccountId, identity.EntAccountId, identity.EntId, identity.EntUserId) for _, v := range list { powers[v] = true } } return powers } // func MergeDiffIndustry(wuye, other *[]map[string]interface{}) *[]map[string]interface{} { m := map[string]map[string]interface{}{} for _, v := range *wuye { _id := BsonIdToSId(v["_id"]) tag_topinformation, _ := v["tag_topinformation"].([]interface{}) for _, vv := range tag_topinformation { if vv != "情报_物业" { continue } m[_id] = v } } for _, v := range *other { _id := BsonIdToSId(v["_id"]) tag_topinformation, _ := v["tag_topinformation"].([]interface{}) if len(tag_topinformation) == 1 && tag_topinformation[0] == "情报_物业" { continue } m[_id] = v } datas := []map[string]interface{}{} for _, v := range m { datas = append(datas, v) } return &datas } // func GetWxTplSurplus(mgo *MongodbSim, wxNodeNum, dayNum, count, retain int64) int64 { ymds := []string{} now := time.Now() for i := 0; i < int(dayNum); i++ { now = now.AddDate(0, 0, -1) ymds = append(ymds, FormatDate(&now, Date_Short_Layout)) } list, ok := mgo.Find("wxtmplsend_tj", map[string]interface{}{"ymd": map[string]interface{}{"$in": ymds}}, `{"ymd":-1}`, `{"count":1,"node_type":1,"ymd":1}`, false, -1, -1) if !ok || list == nil || len(*list) == 0 { logger.Error("wxtmplsend_tj没有找到记录", ymds) return 0 } all := map[string]map[string]int64{} ymdCount := map[string]int64{} for _, v := range *list { ymd, _ := v["ymd"].(string) if all[ymd] == nil { all[ymd] = map[string]int64{} } all[ymd][ObjToString(v["node_type"])]++ ymdCount[ymd] += Int64All(v["count"]) } var index, maxNum int64 L: for _, v := range ymds { if all[v] == nil || int64(len(all[v])) != wxNodeNum { continue } for _, vv := range all[v] { if vv != 1 { continue L } } index++ if maxNum < ymdCount[v] { maxNum = ymdCount[v] } } if index < dayNum/2 { logger.Error("计算以往最大推送量异常", index, dayNum/2) return 0 } surplus := count - maxNum - retain if surplus < 0 { return 0 } logger.Info("微信模板消息最大量", count, ",过去", dayNum, "天内一天最大推送量", maxNum, ",保留", retain, ",剩余可用", surplus) return surplus }