|
@@ -0,0 +1,520 @@
|
|
|
|
+package service
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ util "app.yhyue.com/moapp/jybase/common"
|
|
|
|
+ "app.yhyue.com/moapp/jybase/date"
|
|
|
|
+ "app.yhyue.com/moapp/jybase/encrypt"
|
|
|
|
+ elastic "app.yhyue.com/moapp/jybase/esv7"
|
|
|
|
+ "app.yhyue.com/moapp/jybase/ipmatch"
|
|
|
|
+ "app.yhyue.com/moapp/jybase/mongodb"
|
|
|
|
+ "app.yhyue.com/moapp/jypkg/common/src/qfw/util/bidsearch"
|
|
|
|
+ "app.yhyue.com/moapp/jypkg/public"
|
|
|
|
+ "context"
|
|
|
|
+ "fmt"
|
|
|
|
+ "github.com/gogf/gf/v2/frame/g"
|
|
|
|
+ "github.com/gogf/gf/v2/util/gconv"
|
|
|
|
+ "go.mongodb.org/mongo-driver/bson"
|
|
|
|
+ "html/template"
|
|
|
|
+ "jyseo/utility"
|
|
|
|
+ "regexp"
|
|
|
|
+ "strings"
|
|
|
|
+ "sync"
|
|
|
|
+ "time"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+const (
|
|
|
|
+ DecodeErr = iota + 1
|
|
|
|
+ CacheTime = 60 * 60 * 8
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+var (
|
|
|
|
+ bidSearchField = `"_id","title","publishtime","toptype","subtype","type","area","dataweight","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"`
|
|
|
|
+ IpList *ipmatch.WhiteIp
|
|
|
|
+ IpInitLock sync.RWMutex //锁
|
|
|
|
+ detailNeedMosaic map[string]interface{}
|
|
|
|
+ TypeCodeMap = map[string]string{
|
|
|
|
+ "拟建": "拟建项目",
|
|
|
|
+ "采购意向": "采购意向",
|
|
|
|
+ "预告": "招标预告",
|
|
|
|
+ "预审": "资格预审",
|
|
|
|
+ "预审结果": "资格预审结果",
|
|
|
|
+ "论证意见": "论证意见",
|
|
|
|
+ "需求公示": "需求公示",
|
|
|
|
+ "招标": "公开招标",
|
|
|
|
+ "邀标": "邀请招标",
|
|
|
|
+ "询价": "询价采购",
|
|
|
|
+ "竞谈": "竞争性谈判",
|
|
|
|
+ "单一": "单一来源采购",
|
|
|
|
+ "竞价": "竞价公告",
|
|
|
|
+ "变更": "变更公告",
|
|
|
|
+ "中标": "中标公示",
|
|
|
|
+ "成交": "成交公告",
|
|
|
|
+ "废标": "废标公告",
|
|
|
|
+ "流标": "流标公告",
|
|
|
|
+ "合同": "合同公告信息",
|
|
|
|
+ "验收": "验收公告信息",
|
|
|
|
+ "违规": "违规信息",
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+func init() {
|
|
|
|
+ IpInitLock.Lock()
|
|
|
|
+ defer IpInitLock.Unlock()
|
|
|
|
+ data, err := g.DB("tidb").Query(context.Background(), "select ip,ip_type,is_white from base_service.black_white where is_white = 1")
|
|
|
|
+ if err == nil && !data.IsEmpty() {
|
|
|
|
+ //log.Info("加载白名单")
|
|
|
|
+ var ips []ipmatch.IpParameter
|
|
|
|
+ for _, v := range data.List() {
|
|
|
|
+ var ipData ipmatch.IpParameter
|
|
|
|
+ ipData.Ip = util.InterfaceToStr(v["ip"])
|
|
|
|
+ ipData.IpType = util.IntAll(v["ip_type"])
|
|
|
|
+ ipData.IsWhite = util.IntAll(v["is_white"])
|
|
|
|
+ ips = append(ips, ipData)
|
|
|
|
+ }
|
|
|
|
+ IpList = ipmatch.NewRb(ips)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ IpList = ipmatch.NewRb(nil)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// pc三级页跳转
|
|
|
|
+// 20170821增加查询字段s_subscopeclass
|
|
|
|
+func GetBidInfo(bidId, content string, isWhiteIp bool) (resData map[string]interface{}) {
|
|
|
|
+ bidCacheKey := fmt.Sprintf("jypcdetail_nologin_%s_%s_%v", "content", bidId, isWhiteIp)
|
|
|
|
+ cacheData, _ := g.Redis("limitation").Get(context.Background(), bidCacheKey)
|
|
|
|
+ if !cacheData.IsNil() && len(cacheData.Map()) > 0 {
|
|
|
|
+ return cacheData.Map()
|
|
|
|
+ }
|
|
|
|
+ defer util.Catch()
|
|
|
|
+ if len(bidId) > 5 {
|
|
|
|
+ if ok, bidData := FindBiding(bidId, content, 0); ok {
|
|
|
|
+ var purchasing = bidData["purchasing"]
|
|
|
|
+ if purchasing != nil && purchasing != "" {
|
|
|
|
+ bidData["purchasing"] = util.ObjToString(purchasing)
|
|
|
|
+ }
|
|
|
|
+ titleStr := util.ObjToString(bidData["title"])
|
|
|
|
+ if len([]rune(titleStr)) > 100 {
|
|
|
|
+ titleStr = string([]rune(titleStr)[:100]) + "..."
|
|
|
|
+ }
|
|
|
|
+ //titleTmp := util.If(len([]rune(titleStr)) > 100, string([]rune(titleStr)[:100])+"...", string(titleStr)).(string)
|
|
|
|
+ bidData["title"] = public.ClearHtml.ReplaceAllString(titleStr, "")
|
|
|
|
+ finalType := gconv.String(bidData["subtype"])
|
|
|
|
+ if finalType == "" {
|
|
|
|
+ finalType = util.ObjToString(bidData["toptype"])
|
|
|
|
+ }
|
|
|
|
+ if finalType == "" {
|
|
|
|
+ finalType = util.ObjToString(bidData["type"])
|
|
|
|
+ switch finalType {
|
|
|
|
+ case "bid":
|
|
|
|
+ finalType = "中标"
|
|
|
|
+ case "tender":
|
|
|
|
+ finalType = "招标"
|
|
|
|
+ default:
|
|
|
|
+ finalType = ""
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ bidData["stypeadd"] = GetBidTypeCode(finalType)
|
|
|
|
+ href := strings.Replace(gconv.String(bidData["href"]), "\n", "", -1)
|
|
|
|
+ if href != "" && !strings.HasPrefix(href, "http") {
|
|
|
|
+ href = "http://" + href
|
|
|
|
+ }
|
|
|
|
+ bidData["url"] = href
|
|
|
|
+ bidData["buyerSeoId"] = EsSeoId(false, util.InterfaceToStr(bidData["buyer"]))
|
|
|
|
+
|
|
|
|
+ bidData["agency"] = ""
|
|
|
|
+ if bidData["publishtime"] != nil {
|
|
|
|
+ bidData["publishtimeShorDate"] = time.Unix(util.Int64All(bidData["publishtime"]), 0).Format(date.Date_Short_Layout)
|
|
|
|
+ }
|
|
|
|
+ if !isWhiteIp { //非白名单用户
|
|
|
|
+ bidData = Filter(bidData)
|
|
|
|
+ }
|
|
|
|
+ bidData["description"] = DescriptionHandle("nologin", bidData)
|
|
|
|
+ bidData["keywords"] = KeyWordHandle(bidData)
|
|
|
|
+ g.Redis("limitation").SetEX(context.Background(), bidCacheKey, bidData, 60*2)
|
|
|
|
+ resData = bidData
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return resData
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// wx pc obj字段统一处理
|
|
|
|
+func FindBiding(sid, content string, lent int) (t bool, obj map[string]interface{}) {
|
|
|
|
+ brobj, ok := utility.MG.DB("bidding").Find("bidding_rec", bson.M{"s_id": sid}, `{"l_recoverydate":-1}`, nil, false, 0, 1)
|
|
|
|
+ if ok && (*brobj) != nil && len(*brobj) == 1 && (*brobj)[0] != nil {
|
|
|
|
+ obj = (*brobj)[0]
|
|
|
|
+ } else {
|
|
|
|
+ aobj, ok := utility.MG.DB("bidding").FindById(g.Cfg().MustGet(context.Background(), "mongodb.bidding.collection").String(), sid, nil)
|
|
|
|
+ if ok && (aobj == nil || *aobj == nil || len(*aobj) == 0) {
|
|
|
|
+ aobj, ok = utility.MG.DB("bidding").FindById(g.Cfg().MustGet(context.Background(), "mongodb.bidding.collection_back").String(), sid, nil)
|
|
|
|
+ }
|
|
|
|
+ obj = *aobj
|
|
|
|
+ }
|
|
|
|
+ if ok && obj != nil && len(obj) > lent {
|
|
|
|
+ t = true
|
|
|
|
+ if content != "indexcontent" && (gconv.String(obj["subtype"]) == "拟建" || gconv.String(obj["subtype"]) == "采购意向") {
|
|
|
|
+ if lent == 0 {
|
|
|
|
+ //delete(obj, "detail")
|
|
|
|
+ //delete(obj, "projectinfo")
|
|
|
|
+ goto env
|
|
|
|
+ }
|
|
|
|
+ for k, _ := range obj {
|
|
|
|
+ if k != "title" && k != "area" && k != "detail" && k != "projecttype" && k != "approvecity" && k != "procurementlist" && k != "projectinfo" && k != "subtype" && k != "toptype" && k != "publishtime" && k != "budget" && k != "bidamount" && k != "site" && k != "spidercode" && k != "recommended_service" &&
|
|
|
|
+ k != "owner" && k != "total_investment" && k != "projectaddr" && k != "projectperiod" && k != "approvedept" && k != "approvecontent" && k != "approvecode" && k != "approvenumber" && k != "approvetime" && k != "approvestatus" && k != "project_scale" && k != "projectname" {
|
|
|
|
+ delete(obj, k)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ env:
|
|
|
|
+ obj["_id"] = encrypt.EncodeArticleId2ByCheck(sid)
|
|
|
|
+ infoformat := util.IntAllDef(obj["infoformat"], 1)
|
|
|
|
+ obj["infoformat"] = infoformat
|
|
|
|
+ // p385调整为 除了从竞品爬虫到的新数据,不展示“查看原文链接”入口,其他公告都展示“查看原文链接”入口(包含客户管理系统-结构化数据,查看的标讯详情页)
|
|
|
|
+ // 精准字段(竞争对手的地址) 或 拟建项目
|
|
|
|
+ //competehref字段来源:
|
|
|
|
+ //1、竞品采集 href="#" competehref=原网址
|
|
|
|
+ //2、2021-11-01后新增的爬虫 href=原网址 competehref="#"
|
|
|
|
+ if gconv.String(obj["href"]) == "#" || infoformat == 2 || gconv.String(obj["site"]) == "剑鱼信息发布平台" {
|
|
|
|
+ delete(obj, "href")
|
|
|
|
+ delete(obj, "competehref")
|
|
|
|
+ }
|
|
|
|
+ if strings.Trim(gconv.String(obj["detail"]), " ") == "" {
|
|
|
|
+ obj["detail"] = ""
|
|
|
|
+ } else if g.Cfg().MustGet(cxt, "detailElement").Strings() != nil {
|
|
|
|
+ //detail字段 缺少标签 处理
|
|
|
|
+ var arrTags = g.Cfg().MustGet(cxt, "detailElement").Strings()
|
|
|
|
+ var _detail = gconv.String(obj["detail"])
|
|
|
|
+ for _, v := range arrTags {
|
|
|
|
+ var intOpen = strings.Count(_detail, "<"+v)
|
|
|
|
+ var intClose = strings.Count(_detail, "</"+v+">")
|
|
|
|
+ if intOpen >= intClose {
|
|
|
|
+ for di := 0; di < (intOpen - intClose); di++ {
|
|
|
|
+ _detail += "</" + v + ">"
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ for di := 0; di < (intClose - intOpen); di++ {
|
|
|
|
+ _detail = "<" + v + ">" + _detail
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //seo清除正文h1标签
|
|
|
|
+ obj["detail"] = removeHTMLTagUsingRegex(_detail, "h1")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func GetBidTypeCode(stp string) string {
|
|
|
|
+ stypeArr := g.Cfg("global").MustGet(cxt, "stype").Maps()
|
|
|
|
+ var tpadd = ""
|
|
|
|
+ if stp != "" {
|
|
|
|
+ for _, v := range stypeArr {
|
|
|
|
+ if stp == gconv.String(v["name"]) {
|
|
|
|
+ tpadd = gconv.String(v["code"])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return tpadd
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 未登录用户进行数据过滤 name 配置文件
|
|
|
|
+func Filter(obj map[string]interface{}) map[string]interface{} {
|
|
|
|
+ detail := fmt.Sprint(obj["detail"])
|
|
|
|
+ mosaicText := fmt.Sprintf(`<span style="color:#2ABED1;">%s</span>`, g.Cfg("global").MustGet(context.Background(), "detailMosaic").String())
|
|
|
|
+ detailText := fmt.Sprintf(`<span class="noLoginMosaic" style="color: #2ABED1;">%s</span>`, g.Cfg("global").MustGet(context.Background(), "detailMosaic").String())
|
|
|
|
+ if detailNeedMosaic == nil {
|
|
|
|
+ detailNeedMosaic = g.Cfg("global").MustGet(context.Background(), "detailNeedMosaic").Map()
|
|
|
|
+ }
|
|
|
|
+ for dk, dv := range detailNeedMosaic {
|
|
|
|
+ if !dv.(bool) {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if obj["package"] != nil {
|
|
|
|
+ pk := util.ObjToMap(obj["package"])
|
|
|
|
+ for _, pv := range *pk {
|
|
|
|
+ if pv != nil {
|
|
|
|
+ if page := util.ObjToMap(pv); page != nil {
|
|
|
|
+ if (*page)[dk] != nil {
|
|
|
|
+ (*page)[dk] = mosaicText
|
|
|
|
+ }
|
|
|
|
+ delete(*page, "text")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //if util.ObjToString(obj[dk]) != "" {
|
|
|
|
+ // detail = strings.ReplaceAll(detail, util.ObjToString(obj[dk]), detailText)
|
|
|
|
+ //}
|
|
|
|
+ if util.InterfaceToStr(obj[dk]) != "" {
|
|
|
|
+ value, b := obj[dk].(float64)
|
|
|
|
+ if b {
|
|
|
|
+ replaceStr := fmt.Sprintf("%v", int64(value))
|
|
|
|
+ detail = strings.ReplaceAll(detail, replaceStr, detailText)
|
|
|
|
+ } else {
|
|
|
|
+ detail = strings.ReplaceAll(detail, util.InterfaceToStr(obj[dk]), detailText)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //中标企业信息
|
|
|
|
+ if dk == "winnerMap" {
|
|
|
|
+ winnerNewMap := map[string]interface{}{}
|
|
|
|
+ if obj[dk] != nil {
|
|
|
|
+ winnerMap := util.ObjToMap(obj[dk])
|
|
|
|
+ for _, wv := range *winnerMap {
|
|
|
|
+ winnerNewMap[mosaicText] = wv
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ obj[dk] = winnerNewMap
|
|
|
|
+ } else {
|
|
|
|
+ obj[dk] = mosaicText
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ obj["detail"] = detail
|
|
|
|
+ return obj
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func removeHTMLTagUsingRegex(htmlText, tag string) string {
|
|
|
|
+ if strings.Index(htmlText, tag) == -1 {
|
|
|
|
+ return htmlText
|
|
|
|
+ }
|
|
|
|
+ re := regexp.MustCompile(fmt.Sprintf(`<%s.*?>(.*?)</%s>`, tag, tag))
|
|
|
|
+ cleanedText := re.ReplaceAllString(htmlText, "${1}")
|
|
|
|
+ return cleanedText
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func DescriptionHandle(stype string, obj map[string]interface{}) string {
|
|
|
|
+ description := ""
|
|
|
|
+ publishtime := util.Int64All(obj["l_publishtime"])
|
|
|
|
+ if publishtime == 0 {
|
|
|
|
+ publishtime = util.Int64All(obj["publishtime"])
|
|
|
|
+ }
|
|
|
|
+ pushTime := time.Unix(publishtime, 0)
|
|
|
|
+ title := util.InterfaceToStr(obj["title"])
|
|
|
|
+ owner := util.InterfaceToStr(obj["owner"])
|
|
|
|
+ buyer := util.InterfaceToStr(obj["buyer"])
|
|
|
|
+ if buyer == "" {
|
|
|
|
+ buyer = owner
|
|
|
|
+ }
|
|
|
|
+ s_winner := util.InterfaceToStr(obj["s_winner"])
|
|
|
|
+ area := util.InterfaceToStr(obj["area"])
|
|
|
|
+ city := util.InterfaceToStr(obj["city"])
|
|
|
|
+ if stype == "bdprivate" {
|
|
|
|
+ //bdprivate
|
|
|
|
+ //{项目标题},采购单位:{采购单位名称},成交供应商:{中标企业名称},公告日期:{公告日期}。
|
|
|
|
+ descriptionArr := []string{}
|
|
|
|
+ if title != "" {
|
|
|
|
+ descriptionArr = append(descriptionArr, utility.StrLimitRune(title, g.Cfg().MustGet(context.TODO(), "seo.description.titleLimit", 48).Int()))
|
|
|
|
+ }
|
|
|
|
+ if buyer != "" {
|
|
|
|
+ descriptionArr = append(descriptionArr, fmt.Sprintf("采购单位:%s", buyer))
|
|
|
|
+ }
|
|
|
|
+ if s_winner != "" {
|
|
|
|
+ descriptionArr = append(descriptionArr, fmt.Sprintf("成交供应商:%s", s_winner))
|
|
|
|
+ }
|
|
|
|
+ if publishtime != 0 {
|
|
|
|
+ descriptionArr = append(descriptionArr, fmt.Sprintf("公告日期:%s", pushTime.Format("2006年01月02日")))
|
|
|
|
+ }
|
|
|
|
+ descriptionArr = append(descriptionArr, "查看该项目信息详情请访问剑鱼标讯官网。")
|
|
|
|
+ description = strings.Join(descriptionArr, ",")
|
|
|
|
+ } else {
|
|
|
|
+ //descriptionStr = "%s,项目所属地区是%s%s,项目采购单位是%s,项目发布时间是%s"
|
|
|
|
+ descriptionArr := []string{}
|
|
|
|
+ if title != "" {
|
|
|
|
+ descriptionArr = append(descriptionArr, utility.StrLimitRune(title, g.Cfg().MustGet(context.TODO(), "seo.description.titleLimit", 48).Int()))
|
|
|
|
+ }
|
|
|
|
+ if area != "" || city != "" {
|
|
|
|
+ descriptionArr = append(descriptionArr, fmt.Sprintf("项目所属地区是%s%s", area, city))
|
|
|
|
+ }
|
|
|
|
+ if buyer != "" {
|
|
|
|
+ descriptionArr = append(descriptionArr, fmt.Sprintf("项目采购单位是%s", buyer))
|
|
|
|
+ }
|
|
|
|
+ if publishtime != 0 {
|
|
|
|
+ descriptionArr = append(descriptionArr, fmt.Sprintf("项目发布时间是%s", pushTime.Format("2006年01月02日")))
|
|
|
|
+ }
|
|
|
|
+ descriptionArr = append(descriptionArr, "查看该项目信息详情请访问剑鱼标讯官网。")
|
|
|
|
+ description = strings.Join(descriptionArr, ",")
|
|
|
|
+ }
|
|
|
|
+ return description
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func EsSeoId(isWinner bool, idName string) string {
|
|
|
|
+ if idName == "" {
|
|
|
|
+ return idName
|
|
|
|
+ }
|
|
|
|
+ var seoId string
|
|
|
|
+ redisKey := fmt.Sprintf("getSeoId_%v_%s", isWinner, idName)
|
|
|
|
+ gv, _ := g.Redis("newother").Get(context.Background(), redisKey)
|
|
|
|
+ if gv.IsEmpty() && gv.String() != "" {
|
|
|
|
+ return gv.String()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if isWinner {
|
|
|
|
+ winnerSeo := elastic.GetById("qyxy", "qyxy", idName)
|
|
|
|
+ if winnerSeo != nil && len(*winnerSeo) > 0 {
|
|
|
|
+ seoId = gconv.String((*winnerSeo)[0]["nseo_id"])
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ q := fmt.Sprintf(`{"query": {"bool": {"must": [{"match": {"buyer_name": "%s"}}]}},"from": 0,"size": 1,"_source":["seo_id"]}`, idName)
|
|
|
|
+ winnerSeo := elastic.Get("buyer", "buyer", q)
|
|
|
|
+ if winnerSeo != nil && len(*winnerSeo) > 0 {
|
|
|
|
+ seoId = gconv.String((*winnerSeo)[0]["seo_id"])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if seoId != "" {
|
|
|
|
+ g.Redis("newother").SetEX(context.Background(), redisKey, seoId, -1)
|
|
|
|
+ }
|
|
|
|
+ return seoId
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func KeyWordHandle(obj map[string]interface{}) string {
|
|
|
|
+ keywordArr := []string{}
|
|
|
|
+ owner := util.InterfaceToStr(obj["owner"])
|
|
|
|
+ buyer := util.InterfaceToStr(obj["buyer"])
|
|
|
|
+ if buyer == "" {
|
|
|
|
+ buyer = owner
|
|
|
|
+ }
|
|
|
|
+ if buyer != "" && buyer != g.Cfg("global").MustGet(context.TODO(), "detailMosaicTxt", "略").String() {
|
|
|
|
+ keywordArr = append(keywordArr, buyer)
|
|
|
|
+ }
|
|
|
|
+ if util.InterfaceToStr(obj["s_winner"]) != "" && util.InterfaceToStr(obj["s_winner"]) != g.Cfg("global").MustGet(context.TODO(), "detailMosaicTxt", "略").String() {
|
|
|
|
+ keywordArr = append(keywordArr, util.InterfaceToStr(obj["s_winner"]))
|
|
|
|
+ }
|
|
|
|
+ if obj["purchasinglist"] != nil && obj["purchasinglist"] != "" {
|
|
|
|
+ i := 0
|
|
|
|
+ for _, v := range gconv.SliceMap(obj["purchasinglist"]) {
|
|
|
|
+ if i == 5 {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ if util.InterfaceToStr(v["itemname"]) != "" && util.InterfaceToStr(obj["s_winner"]) != g.Cfg("global").MustGet(context.TODO(), "detailMosaicTxt", "略").String() {
|
|
|
|
+ keywordArr = append(keywordArr, util.InterfaceToStr(v["itemname"]))
|
|
|
|
+ i++
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if util.InterfaceToStr(obj["subtype"]) != "" && util.InterfaceToStr(obj["subtype"]) != "其它" {
|
|
|
|
+ keywordArr = append(keywordArr, TypeCodeMap[util.InterfaceToStr(obj["subtype"])])
|
|
|
|
+ }
|
|
|
|
+ if util.InterfaceToStr(obj["area"]) != "" {
|
|
|
|
+ keywordArr = append(keywordArr, util.InterfaceToStr(obj["area"])+"招标")
|
|
|
|
+ }
|
|
|
|
+ if util.InterfaceToStr(obj["city"]) != "" {
|
|
|
|
+ keywordArr = append(keywordArr, util.InterfaceToStr(obj["city"])+"招标")
|
|
|
|
+ }
|
|
|
|
+ keywordArr = append(keywordArr, "剑鱼标讯")
|
|
|
|
+ keyword := strings.Join(keywordArr, ",")
|
|
|
|
+ return keyword
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 招投标攻略
|
|
|
|
+func GetBiddingStrategy(pageSize int) (res []map[string]interface{}) {
|
|
|
|
+ chKey := fmt.Sprintf("bidDetail_BiddingStrategy")
|
|
|
|
+ gv, _ := g.Redis().Get(context.Background(), chKey)
|
|
|
|
+ if !gv.IsNil() && len(gv.Maps()) > 0 {
|
|
|
|
+ res = gv.Maps()
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ queryMap := map[string]interface{}{
|
|
|
|
+ "i_status": 1,
|
|
|
|
+ }
|
|
|
|
+ total := utility.MG.DB().Count("content", queryMap)
|
|
|
|
+ if total == 0 {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+ data, _ := utility.MG.DB().Find("content", queryMap, `{"releasetime":-1}`, `{"s_title":1,"releasetime":1,"s_pic":1,"s_pic1":1,"l_createdate":1,"_id":1,"s_author":1,"i_viewnum":1}`, false, 0, pageSize)
|
|
|
|
+ res = []map[string]interface{}{}
|
|
|
|
+ if data != nil && len(*data) > 0 {
|
|
|
|
+ for _, m := range *data {
|
|
|
|
+ s_title, _ := m["s_title"].(string)
|
|
|
|
+ m["s_title"] = template.HTML(s_title)
|
|
|
|
+ tmpdate1, _ := m["releasetime"]
|
|
|
|
+ m["releasetime"] = util.TimeDiff(time.Unix(util.Int64All(tmpdate1), 0))
|
|
|
|
+ reltime := time.Unix(util.Int64All(tmpdate1), 0)
|
|
|
|
+ m["time"] = reltime.Format("2006-01-02") //首页展示
|
|
|
|
+ m["_id"] = se.EncodeString(mongodb.BsonIdToSId(m["_id"]))
|
|
|
|
+ m["url"] = fmt.Sprintf("/jyblog/%s.html", gconv.String(m["_id"]))
|
|
|
|
+ res = append(res, m)
|
|
|
|
+ }
|
|
|
|
+ g.Redis().SetEX(context.Background(), chKey, res, CacheTime)
|
|
|
|
+ }
|
|
|
|
+ return res
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 获取最新招标信息
|
|
|
|
+func GetNewBidInfo(bidId, industry, area, city string) (list []map[string]interface{}) {
|
|
|
|
+ var (
|
|
|
|
+ redisKey = fmt.Sprintf("pcindex_newArticle_%s", bidId)
|
|
|
|
+ redisKeySL = fmt.Sprintf("pcindex_newArticle_second_level_%s", bidId) //二级缓存
|
|
|
|
+ redisLock = &sync.Mutex{}
|
|
|
|
+ ri int
|
|
|
|
+ rn = 3
|
|
|
|
+ )
|
|
|
|
+ var newBidInfos = func() (list []map[string]interface{}) {
|
|
|
|
+ // p397 未登录详情页最新招投标信息去掉拟建
|
|
|
|
+ var (
|
|
|
|
+ now = time.Now()
|
|
|
|
+ startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-7, now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix()) //最近7天
|
|
|
|
+ endTime = fmt.Sprint(now.Unix())
|
|
|
|
+ publishTime = fmt.Sprintf("%s_%s", startTime, endTime)
|
|
|
|
+ )
|
|
|
|
+ _, _, lists := bidsearch.GetPcBidSearchData("", area, city, publishTime, "招标预告,招标公告,招标结果,招标信用信息", industry, "", "", "", "", "", "", "", 1, false, nil, bidSearchField, "", false, false, "", 50, "")
|
|
|
|
+ if lists != nil && len(*lists) > 0 {
|
|
|
|
+ if len(*lists) > 10 {
|
|
|
|
+ *lists = (*lists)[:10]
|
|
|
|
+ }
|
|
|
|
+ for _, v := range *lists {
|
|
|
|
+ v["_id"] = encrypt.CommonEncodeArticle("content", v["_id"].(string))
|
|
|
|
+ delete(v, "toptype")
|
|
|
|
+ delete(v, "s_subscopeclass")
|
|
|
|
+ tmpdate := v["publishtime"]
|
|
|
|
+ v["publishtime"] = gconv.Int64(tmpdate.(float64))
|
|
|
|
+ v["date"] = time.Unix(gconv.Int64(tmpdate.(float64)), 0).Format(date.Date_Short_Layout)
|
|
|
|
+ if v["budget"] != nil {
|
|
|
|
+ v["budget"] = utility.ConversionMoeny(v["budget"])
|
|
|
|
+ } else if v["bidamount"] != nil {
|
|
|
|
+ v["budget"] = utility.ConversionMoeny(v["bidamount"])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ list = *lists
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ var bidInfosByCache = func(rk string) (list []map[string]interface{}) {
|
|
|
|
+ gv, _ := g.Redis().Get(context.Background(), rk)
|
|
|
|
+ if !gv.IsNil() && len(gv.Maps()) > 0 {
|
|
|
|
+ list = gv.Maps()
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ var bidInfosToCache = func(list []map[string]interface{}) {
|
|
|
|
+ if err := g.Redis().SetEX(context.Background(), redisKey, list, CacheTime); err != nil {
|
|
|
|
+ g.Log().Errorf(context.Background(), "最新招投标数据 存储redis err:%v", err)
|
|
|
|
+ }
|
|
|
|
+ if err := g.Redis().SetEX(context.Background(), redisKeySL, list, -1); err != nil {
|
|
|
|
+ g.Log().Errorf(context.Background(), "最新招投标二级数据 存储redis err:%v", err)
|
|
|
|
+ }
|
|
|
|
+ //redis.Put("seoCache", redisKey, list, cacheTime)
|
|
|
|
+ //ok := redis.Put("seoCache", redisKeySL, list, -1)
|
|
|
|
+ //log.Println(redisKeySL, "--00--", ok)
|
|
|
|
+ }
|
|
|
|
+ list = bidInfosByCache(redisKey)
|
|
|
|
+ if len(list) == 0 {
|
|
|
|
+ list = bidInfosByCache(redisKeySL)
|
|
|
|
+ if len(list) == 0 {
|
|
|
|
+ list = newBidInfos()
|
|
|
|
+ bidInfosToCache(list)
|
|
|
|
+ } else {
|
|
|
|
+ go func() {
|
|
|
|
+ for {
|
|
|
|
+ if redisLock.TryLock() {
|
|
|
|
+ bidInfosToCache(newBidInfos())
|
|
|
|
+ redisLock.Unlock()
|
|
|
|
+ }
|
|
|
|
+ ri++
|
|
|
|
+ if len(list) > 0 || ri >= rn {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ time.Sleep(100 * time.Millisecond)
|
|
|
|
+ }
|
|
|
|
+ }()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return list
|
|
|
|
+}
|