瀏覽代碼

wip:采购信息详情页

wangshan 9 月之前
父節點
當前提交
ec02c80357

+ 593 - 570
src/jfw/modules/publicapply/src/detail/dao/bidding.go

@@ -1,652 +1,675 @@
 package dao
 
 import (
-    "app.yhyue.com/moapp/jybase/common"
-    "app.yhyue.com/moapp/jybase/date"
-    "app.yhyue.com/moapp/jybase/encrypt"
-    elastic "app.yhyue.com/moapp/jybase/es"
-    mg "app.yhyue.com/moapp/jybase/mongodb"
-    "app.yhyue.com/moapp/jybase/redis"
-    "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
-    "app.yhyue.com/moapp/jypkg/public"
-    "database/sql"
-    "fmt"
-    "github.com/gogf/gf/v2/util/gconv"
-    "jy/src/jfw/modules/publicapply/src/config"
-    "jy/src/jfw/modules/publicapply/src/db"
-    dc "jy/src/jfw/modules/publicapply/src/detail/config"
-    "jy/src/jfw/modules/publicapply/src/detail/consts"
-    "jy/src/jfw/modules/publicapply/src/detail/entity"
-    "jy/src/jfw/modules/publicapply/src/detail/util"
-    "log"
-    "regexp"
-    "strconv"
-    "strings"
-    "sync"
-    "time"
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	elastic "app.yhyue.com/moapp/jybase/es"
+	mg "app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	"app.yhyue.com/moapp/jypkg/public"
+	"database/sql"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
+	"jy/src/jfw/modules/publicapply/src/config"
+	"jy/src/jfw/modules/publicapply/src/db"
+	dc "jy/src/jfw/modules/publicapply/src/detail/config"
+	"jy/src/jfw/modules/publicapply/src/detail/consts"
+	"jy/src/jfw/modules/publicapply/src/detail/entity"
+	"jy/src/jfw/modules/publicapply/src/detail/util"
+	"log"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
 )
 
 // userid  by openid
 func GetUserId(openid string) string {
-    data, ok := db.Mgo.FindOne(consts.UserTable, map[string]interface{}{"s_m_openid": openid})
-    if data != nil && len(*data) > 0 && ok {
-        userid := mg.BsonIdToSId((*data)["_id"])
-        return userid
-    }
-    return ""
+	data, ok := db.Mgo.FindOne(consts.UserTable, map[string]interface{}{"s_m_openid": openid})
+	if data != nil && len(*data) > 0 && ok {
+		userid := mg.BsonIdToSId((*data)["_id"])
+		return userid
+	}
+	return ""
 }
 
 // 分销--最新一条记录 2021-09-07 10:36:05
 func GetUserIdByDisWord(disWord, userId string) (belongUserId string) {
-    if disWord != "" {
-        redisDis := redis.GetStr(consts.RedisOther, "DIS_"+disWord[1:])
-        if redisDis != "" {
-            suffix := disWord[len(disWord)-3:]
-            //公告三级页处理
-            if suffix == consts.SuffixMsgT {
-                effectiveTimeStr := strings.Split(redisDis, "##")[3]
-                effectiveTime, _ := strconv.ParseInt(effectiveTimeStr, 10, 64)
-                //是否计算佣金
-                if time.Now().Unix() <= effectiveTime {
-                    belongUserId = strings.Split(redisDis, "##")[1]
-                    db.Mysql.ExecTx("口号使用", func(tx *sql.Tx) bool {
-                        //口号是否使用过
-                        wordInfo := db.Mysql.Find("dis_word", map[string]interface{}{"userId": userId, "password": disWord}, "id", "", 0, 0)
-                        if len(*wordInfo) == 0 {
-                            //新增口号使用
-                            startTime := time.Now().Format(date.Date_Full_Layout)
-                            stopTime := util.TimeProcessing(time.Now().Format(date.Date_Full_Layout), dc.Config.TermValidity).Format(date.Date_Full_Layout)
-                            insert := map[string]interface{}{
-                                "password":      disWord,
-                                "userId":        userId,
-                                "belong_userid": belongUserId,
-                                "start_time":    startTime,
-                                "stop_time":     stopTime,
-                            }
-                            insert1 := public.Mysql.InsertByTx(tx, "dis_word", insert) //口号使用表
-                            log.Println("插入口号使用表", insert1)
-                            return insert1 > 0
-                        }
-                        return true
-                    })
-                }
-            }
-        }
-    }
-    return
+	if disWord != "" {
+		redisDis := redis.GetStr(consts.RedisOther, "DIS_"+disWord[1:])
+		if redisDis != "" {
+			suffix := disWord[len(disWord)-3:]
+			//公告三级页处理
+			if suffix == consts.SuffixMsgT {
+				effectiveTimeStr := strings.Split(redisDis, "##")[3]
+				effectiveTime, _ := strconv.ParseInt(effectiveTimeStr, 10, 64)
+				//是否计算佣金
+				if time.Now().Unix() <= effectiveTime {
+					belongUserId = strings.Split(redisDis, "##")[1]
+					db.Mysql.ExecTx("口号使用", func(tx *sql.Tx) bool {
+						//口号是否使用过
+						wordInfo := db.Mysql.Find("dis_word", map[string]interface{}{"userId": userId, "password": disWord}, "id", "", 0, 0)
+						if len(*wordInfo) == 0 {
+							//新增口号使用
+							startTime := time.Now().Format(date.Date_Full_Layout)
+							stopTime := util.TimeProcessing(time.Now().Format(date.Date_Full_Layout), dc.Config.TermValidity).Format(date.Date_Full_Layout)
+							insert := map[string]interface{}{
+								"password":      disWord,
+								"userId":        userId,
+								"belong_userid": belongUserId,
+								"start_time":    startTime,
+								"stop_time":     stopTime,
+							}
+							insert1 := public.Mysql.InsertByTx(tx, "dis_word", insert) //口号使用表
+							log.Println("插入口号使用表", insert1)
+							return insert1 > 0
+						}
+						return true
+					})
+				}
+			}
+		}
+	}
+	return
 }
 
 // 检查用户是否关注
 func CheckUserIsSubscribe(openid string) bool {
-    user, ok := db.Mgo.FindOneByField("user", map[string]interface{}{
-        "i_appid":    2,
-        "s_m_openid": openid,
-        "s_unionid":  map[string]interface{}{"$ne": openid},
-    }, `{"i_ispush":1}`)
-    if ok && user != nil {
-        if (*user)["_id"] == nil || common.IntAllDef((*user)["i_ispush"], 1) == 0 {
-            return false
-        } else {
-            return true
-        }
-    }
-    return false
+	user, ok := db.Mgo.FindOneByField("user", map[string]interface{}{
+		"i_appid":    2,
+		"s_m_openid": openid,
+		"s_unionid":  map[string]interface{}{"$ne": openid},
+	}, `{"i_ispush":1}`)
+	if ok && user != nil {
+		if (*user)["_id"] == nil || common.IntAllDef((*user)["i_ispush"], 1) == 0 {
+			return false
+		} else {
+			return true
+		}
+	}
+	return false
 }
 
 // 超前信息
 func AdvancedInfo(newUserId int64, bdId string) (b bool) {
-    pushData := public.BaseMysql.FindOne("leadproject_push", map[string]interface{}{"user_id": newUserId, "info_id": bdId}, "id", "")
-    //访问次数加1
-    if pushData != nil {
-        b = public.BaseMysql.UpdateOrDeleteBySql("UPDATE leadproject_push SET  visit_count=visit_count+1 ,lastvisit_time=? WHERE id = ?", time.Now().Format("2006-01-02 15:04:05"), (*pushData)["id"]) > 0
-    }
-    return
+	pushData := public.BaseMysql.FindOne("leadproject_push", map[string]interface{}{"user_id": newUserId, "info_id": bdId}, "id", "")
+	//访问次数加1
+	if pushData != nil {
+		b = public.BaseMysql.UpdateOrDeleteBySql("UPDATE leadproject_push SET  visit_count=visit_count+1 ,lastvisit_time=? WHERE id = ?", time.Now().Format("2006-01-02 15:04:05"), (*pushData)["id"]) > 0
+	}
+	return
 }
 
 // 该节点是否留资
 func hasRetainedCapital(uid string, source []string) bool {
-    if count, err := db.Mgo.CountByErr("saleLeads", map[string]interface{}{"userid": uid, "source": map[string]interface{}{"$in": source}}); err != nil || count > 0 {
-        return true
-    }
-    return false
+	if count, err := db.Mgo.CountByErr("saleLeads", map[string]interface{}{"userid": uid, "source": map[string]interface{}{"$in": source}}); err != nil || count > 0 {
+		return true
+	}
+	return false
 }
 
 // 留资信息
 func CNode(userId string) bool {
-    if hasRetainedCapital(userId, []string{"jyarticle_see3_plus", "jyarticle_see3_plus_pc", "jyarticle_see3_plus_wx", "jyarticle_see3_plus_app", "pc_article_member_freeuse", "app_article_member_freeuse", "wx_article_member_freeuse", "h5_article_member_freeuse"}) {
-        return true
-    }
-    rM := map[string]interface{}{}
-    rdata, ok := db.Mgo.Find("saleLeads", map[string]interface{}{
-        "userid": userId,
-    }, `{"createtime":-1}`, nil, false, 0, 10)
-    if rdata != nil && len(*rdata) > 0 && ok {
-        for _, v := range *rdata {
-            for kk, vv := range v {
-                if vv == nil {
-                    continue
-                }
-                if rM[kk] != nil {
-                    continue
-                }
-                rM[kk] = vv
-            }
-        }
-        delete(rM, "_id")
-        delete(rM, "userid")
-        delete(rM, "createtime")
-        delete(rM, "client")
-    }
-    if userinfo := config.Compatible.Select(userId, `{"s_phone":1,"s_m_phone":1,"s_myemail":1,"s_company":1,"o_jy":1,"o_vipjy":1}`); userinfo != nil && len(*userinfo) > 0 {
-        s_phone := common.ObjToString((*userinfo)["s_phone"])
-        phone := common.If(s_phone == "", common.ObjToString((*userinfo)["s_m_phone"]), s_phone)
-        if rM["phone"] == nil || rM["phone"] == "" {
-            rM["phone"] = phone
-        }
-        if rM["company"] == nil || rM["company"] == "" {
-            rM["company"] = common.ObjToString((*userinfo)["s_company"])
-        }
-    }
-    if rM["name"] != nil && rM["name"] != "" && rM["phone"] != nil && rM["phone"] != "" && rM["company"] != nil && rM["company"] != "" && rM["position"] != nil && rM["position"] != "" && rM["companyType"] != "" {
+	if hasRetainedCapital(userId, []string{"jyarticle_see3_plus", "jyarticle_see3_plus_pc", "jyarticle_see3_plus_wx", "jyarticle_see3_plus_app", "pc_article_member_freeuse", "app_article_member_freeuse", "wx_article_member_freeuse", "h5_article_member_freeuse"}) {
+		return true
+	}
+	rM := map[string]interface{}{}
+	rdata, ok := db.Mgo.Find("saleLeads", map[string]interface{}{
+		"userid": userId,
+	}, `{"createtime":-1}`, nil, false, 0, 10)
+	if rdata != nil && len(*rdata) > 0 && ok {
+		for _, v := range *rdata {
+			for kk, vv := range v {
+				if vv == nil {
+					continue
+				}
+				if rM[kk] != nil {
+					continue
+				}
+				rM[kk] = vv
+			}
+		}
+		delete(rM, "_id")
+		delete(rM, "userid")
+		delete(rM, "createtime")
+		delete(rM, "client")
+	}
+	if userinfo := config.Compatible.Select(userId, `{"s_phone":1,"s_m_phone":1,"s_myemail":1,"s_company":1,"o_jy":1,"o_vipjy":1}`); userinfo != nil && len(*userinfo) > 0 {
+		s_phone := common.ObjToString((*userinfo)["s_phone"])
+		phone := common.If(s_phone == "", common.ObjToString((*userinfo)["s_m_phone"]), s_phone)
+		if rM["phone"] == nil || rM["phone"] == "" {
+			rM["phone"] = phone
+		}
+		if rM["company"] == nil || rM["company"] == "" {
+			rM["company"] = common.ObjToString((*userinfo)["s_company"])
+		}
+	}
+	if rM["name"] != nil && rM["name"] != "" && rM["phone"] != nil && rM["phone"] != "" && rM["company"] != nil && rM["company"] != "" && rM["position"] != nil && rM["position"] != "" && rM["companyType"] != "" {
 
-        if rM["position"] != "总裁" && rM["position"] != "总经理" && (rM["branch"] == nil || rM["branch"] == "") {
-            return false
-        }
-        return true
+		if rM["position"] != "总裁" && rM["position"] != "总经理" && (rM["branch"] == nil || rM["branch"] == "") {
+			return false
+		}
+		return true
 
-    }
-    return false
+	}
+	return false
 }
 
 var (
-    limitLogsLock  = sync.Mutex{}
-    limitLogsChan  = make(chan struct{}, 4)
-    limitLogsCount = 30
-    limitLogsData  []map[string]interface{}
+	limitLogsLock  = sync.Mutex{}
+	limitLogsChan  = make(chan struct{}, 4)
+	limitLogsCount = 30
+	limitLogsData  []map[string]interface{}
 )
 
 // 免费未留资用户查看公告超过免费次数限制记录
 func SeeDetailLimitLogs(sessUser util.SessUserInfo, sid string) {
-    limitLogsChan <- struct{}{}
-    defer func() {
-        <-limitLogsChan
-    }()
-    //保存日志
-    limitLogsLock.Lock()
-    limitLogsData = append(limitLogsData, map[string]interface{}{
-        "mgoUserId":    sessUser.MgoUserId,
-        "phone":        sessUser.Phone,
-        "positionId":   sessUser.PositionId,
-        "positionType": sessUser.PositionType,
-        "openId":       sessUser.OpenId,
-        "biddingId":    sid,
-        "createDate":   time.Now().Unix(),
-    })
-    if len(limitLogsData) > limitLogsCount {
-        tmp := limitLogsData
-        limitLogsData = make([]map[string]interface{}, 0)
-        sb := db.Mgo_Log.SaveBulk("detail_limit_logs", tmp...)
-        if !sb {
-            log.Println("免费用户 访问 详情页 超限制日志存储 异常")
-        }
-    }
-    limitLogsLock.Unlock()
+	limitLogsChan <- struct{}{}
+	defer func() {
+		<-limitLogsChan
+	}()
+	//保存日志
+	limitLogsLock.Lock()
+	limitLogsData = append(limitLogsData, map[string]interface{}{
+		"mgoUserId":    sessUser.MgoUserId,
+		"phone":        sessUser.Phone,
+		"positionId":   sessUser.PositionId,
+		"positionType": sessUser.PositionType,
+		"openId":       sessUser.OpenId,
+		"biddingId":    sid,
+		"createDate":   time.Now().Unix(),
+	})
+	if len(limitLogsData) > limitLogsCount {
+		tmp := limitLogsData
+		limitLogsData = make([]map[string]interface{}, 0)
+		sb := db.Mgo_Log.SaveBulk("detail_limit_logs", tmp...)
+		if !sb {
+			log.Println("免费用户 访问 详情页 超限制日志存储 异常")
+		}
+	}
+	limitLogsLock.Unlock()
 }
 
 // 查看公告详情次数限制
 func SeeDetailLimit(sessUser util.SessUserInfo, sid string) bool {
-    //|| 无限制
-    if dc.Config.CanReadNotice == 0 {
-        return true
-    }
-    userId := sessUser.UserId
-    //检验是否留资
-    if CNode(userId) {
-        return true
-    }
-    watchKey := fmt.Sprintf("article_count_%d_%s_%d_%s", time.Now().Year(), time.Now().Month(), time.Now().Day(), userId)
-    if seeRes := redis.Get(consts.RedisLimitation, watchKey); seeRes != nil && seeRes != "" {
-        if resVal, _ := seeRes.(string); resVal != "" {
-            sidss := strings.Split(resVal, "_")
-            if len(sidss) < dc.Config.CanReadNotice {
-                sidss = append(sidss, sid)
-                arrs := util.RemoveDuplicatesAndEmpty(sidss)
-                newVal := strings.Join(arrs, "_")
-                redis.Put(consts.RedisLimitation, watchKey, newVal, jy.GetExpire())
-                return true
-            } else {
-                for _, v := range sidss {
-                    if sid == v {
-                        return true
-                    }
-                }
-                //超过限制次数 记录
-                go SeeDetailLimitLogs(sessUser, sid)
-                return false
-            }
-        }
-    } else {
-        redis.Put(consts.RedisLimitation, watchKey, sid, jy.GetExpire())
-        return true
-    }
-    return false
+	//|| 无限制
+	if dc.Config.CanReadNotice == 0 {
+		return true
+	}
+	userId := sessUser.UserId
+	//检验是否留资
+	if CNode(userId) {
+		return true
+	}
+	watchKey := fmt.Sprintf("article_count_%d_%s_%d_%s", time.Now().Year(), time.Now().Month(), time.Now().Day(), userId)
+	if seeRes := redis.Get(consts.RedisLimitation, watchKey); seeRes != nil && seeRes != "" {
+		if resVal, _ := seeRes.(string); resVal != "" {
+			sidss := strings.Split(resVal, "_")
+			if len(sidss) < dc.Config.CanReadNotice {
+				sidss = append(sidss, sid)
+				arrs := util.RemoveDuplicatesAndEmpty(sidss)
+				newVal := strings.Join(arrs, "_")
+				redis.Put(consts.RedisLimitation, watchKey, newVal, jy.GetExpire())
+				return true
+			} else {
+				for _, v := range sidss {
+					if sid == v {
+						return true
+					}
+				}
+				//超过限制次数 记录
+				go SeeDetailLimitLogs(sessUser, sid)
+				return false
+			}
+		}
+	} else {
+		redis.Put(consts.RedisLimitation, watchKey, sid, jy.GetExpire())
+		return true
+	}
+	return false
 }
 
 // 详情页数据
 func GetBiddingData(id string) (subtype string, obj map[string]interface{}) {
-    cObj, ok := db.Mgo_Bidding.FindById(db.DbConf.Mongodb.Bidding.Collection, id, nil)
-    if ok && (cObj == nil || *cObj == nil || len(*cObj) == 0) {
-        cObj, ok = db.Mgo_Bidding.FindById(db.DbConf.Mongodb.Bidding.Collection_change, id, nil)
-    }
-    obj = *cObj
-    if ok && obj != nil && len(obj) > 0 {
-        subtype = common.ObjToString(obj["subtype"])
-        topType := common.ObjToString(obj["toptype"])
-        if topType == "" {
-            subtype = topType
-        }
-    }
-    return
+	cObj, ok := db.Mgo_Bidding.FindById(db.DbConf.Mongodb.Bidding.Collection, id, nil)
+	if ok && (cObj == nil || *cObj == nil || len(*cObj) == 0) {
+		cObj, ok = db.Mgo_Bidding.FindById(db.DbConf.Mongodb.Bidding.Collection_change, id, nil)
+	}
+	obj = *cObj
+	if ok && obj != nil && len(obj) > 0 {
+		subtype = common.ObjToString(obj["subtype"])
+		topType := common.ObjToString(obj["toptype"])
+		if topType == "" {
+			subtype = topType
+		}
+	}
+	return
 }
 
 // 没有权限招标信息处理
 func BiddingDataFormatNoPower(obj map[string]interface{}, id string) *entity.BidInfo {
-    var (
-        bi = &entity.BidInfo{
-            BaseInfo: &entity.BidBaseInfo{},
-            Abstract: &entity.Abstract{},
-            Detail:   &entity.DetailInfo{},
-            CanRead:  false,
-        }
-    )
-    //基本信息
-    bi.BaseInfo.Id = encrypt.EncodeArticleId2ByCheck(id)
-    industry := common.ObjToString(obj["s_subscopeclass"])
-    if industry != "" {
-        industry = strings.Replace(industry, "它", "他", -1)
-        industry = strings.Split(industry, ",")[0]
-    }
-    bi.BaseInfo.Industry = industry
-    title := common.ObjToString(obj["title"])
-    if len([]rune(title)) > dc.Config.TitleSize {
-        title = fmt.Sprintf("%s...", string([]rune(title)[:dc.Config.TitleSize]))
-    }
-    bi.BaseInfo.Title = title
-    bi.BaseInfo.SubType = common.ObjToString(obj["subtype"])
-    bi.BaseInfo.Area = common.ObjToString(obj["area"])
-    bi.BaseInfo.City = common.ObjToString(obj["city"])
-    bi.BaseInfo.BuyerClass = common.ObjToString(obj["buyerclass"])
-    return bi
+	var (
+		bi = &entity.BidInfo{
+			BaseInfo: &entity.BidBaseInfo{},
+			Abstract: &entity.Abstract{},
+			Detail:   &entity.DetailInfo{},
+			CanRead:  false,
+		}
+	)
+	//基本信息
+	bi.BaseInfo.Id = encrypt.EncodeArticleId2ByCheck(id)
+	industry := common.ObjToString(obj["s_subscopeclass"])
+	if industry != "" {
+		industry = strings.Replace(industry, "它", "他", -1)
+		industry = strings.Split(industry, ",")[0]
+	}
+	bi.BaseInfo.Industry = industry
+	title := common.ObjToString(obj["title"])
+	if len([]rune(title)) > dc.Config.TitleSize {
+		title = fmt.Sprintf("%s...", string([]rune(title)[:dc.Config.TitleSize]))
+	}
+	bi.BaseInfo.Title = title
+	bi.BaseInfo.SubType = common.ObjToString(obj["subtype"])
+	bi.BaseInfo.Area = common.ObjToString(obj["area"])
+	bi.BaseInfo.City = common.ObjToString(obj["city"])
+	bi.BaseInfo.BuyerClass = common.ObjToString(obj["buyerclass"])
+	return bi
 }
 
 // wx pc obj字段统一处理
 func BiddingDataFormat(obj map[string]interface{}, id string, b bool) *entity.BidInfo {
-    var (
-        bi = &entity.BidInfo{
-            BaseInfo: &entity.BidBaseInfo{},
-            Abstract: &entity.Abstract{},
-            Detail:   &entity.DetailInfo{},
-            CanRead:  true,
-            Topnet:   b,
-        }
-    )
-    //基本信息
-    bi.BaseInfo.Id = encrypt.EncodeArticleId2ByCheck(id)
-    industry := common.ObjToString(obj["s_subscopeclass"])
-    if industry != "" {
-        industry = strings.Replace(industry, "它", "他", -1)
-        industry = strings.Split(industry, ",")[0]
-    }
-    bi.BaseInfo.Industry = industry
-    title := common.ObjToString(obj["title"])
-    if len([]rune(title)) > dc.Config.TitleSize {
-        title = fmt.Sprintf("%s...", string([]rune(title)[:dc.Config.TitleSize]))
-    }
-    bi.BaseInfo.Title = title
-    bi.BaseInfo.Area = common.ObjToString(obj["area"])
-    bi.BaseInfo.Purchasing = common.ObjToString(obj["purchasing"])
-    bi.BaseInfo.ProjectName = common.ObjToString(obj["projectname"])
-    bi.BaseInfo.ProjectCode = common.ObjToString(obj["projectcode"])
-    bi.BaseInfo.City = common.ObjToString(obj["city"])
-    bi.BaseInfo.BuyerClass = common.ObjToString(obj["buyerclass"])
-    bi.BaseInfo.District = common.ObjToString(obj["district"])
-    bi.BaseInfo.Site = common.ObjToString(obj["site"])
-    bi.BaseInfo.SubType = common.ObjToString(obj["subtype"])
-    bi.BaseInfo.TopType = common.ObjToString(obj["toptype"])
-    if bi.BaseInfo.SubType == "" {
-        bi.BaseInfo.SubType = bi.BaseInfo.TopType
-    }
-    bi.BaseInfo.BidAmount = common.Int64All(obj["bidamount"])
-    bi.BaseInfo.Budget = common.Int64All(obj["budget"])
-    bi.BaseInfo.PublishTime = common.Int64All(obj["publishtime"])
-    bi.BaseInfo.BuyerSeoId = EsSeoId(false, common.InterfaceToStr(obj["buyer"]))
-    bi.BaseInfo.RecommendedService = common.IntAll(obj["recommended_service"])
-    //摘要
-    switch bi.BaseInfo.SubType {
-    case "拟建":
-        bi.Abstract.Proposed = &entity.Proposed{}
-        bi.Abstract.Proposed.ProjectName = bi.BaseInfo.ProjectName
-        bi.Abstract.Proposed.Area = bi.BaseInfo.Area
-        bi.Abstract.Proposed.Buyer = common.ObjToString(obj["owner"])
-        if bi.Abstract.Proposed.Buyer != "" {
-            bi.Abstract.Proposed.BuyerPortraitShow = true // len(GetEntInfo(strings.Split(bi.Abstract.Proposed.Buyer, ","))) > 0
-        }
-        bi.Abstract.Proposed.BuyerClass = bi.BaseInfo.BuyerClass
-        bi.Abstract.Proposed.TotalInvestment = common.InterfaceToStr(obj["total_investment"])
-        bi.Abstract.Proposed.ProjectPeriod = common.ObjToString(obj["projectperiod"])
-        bi.Abstract.Proposed.Address = common.ObjToString(obj["projectaddr"])
-        bi.Abstract.Proposed.ApproveDept = common.ObjToString(obj["approvedept"])
-        bi.Abstract.Proposed.ApproveContent = common.ObjToString(obj["approvecontent"])
-        bi.Abstract.Proposed.ApproveCode = common.ObjToString(obj["approvecode"])
-        bi.Abstract.Proposed.ApprovalNumber = common.ObjToString(obj["approvenumber"])
-        bi.Abstract.Proposed.ApproveTime = common.ObjToString(obj["approvetime"])
-        bi.Abstract.Proposed.ApproveStatus = common.ObjToString(obj["approvestatus"])
-        bi.Abstract.Proposed.Content = common.ObjToString(obj["project_scale"])
-    default:
-        bi.Abstract.Default = &entity.Default{}
-        bi.Abstract.Default.Buyer = common.ObjToString(obj["buyer"])
-        if bi.Abstract.Default.Buyer != "" {
-            bi.Abstract.Default.BuyerPortraitShow = true // len(GetEntInfo(strings.Split(bi.Abstract.Default.Buyer, ","))) > 0
-        }
-        //判断是否公开联系人信息
-        if common.Int64All(obj["buyerhint"]) != 2 {
-            bi.Abstract.Default.BuyerPerson = common.ObjToString(obj["buyerperson"])
-            bi.Abstract.Default.BuyerTel = common.ObjToString(obj["buyertel"])
-            //ContactInfo(common.ObjToString(obj["buyerperson"]), common.ObjToString(obj["buyertel"]))
-        }
-        bi.Abstract.Default.Agency = common.ObjToString(obj["agency"])
-        bi.Abstract.Default.AgencyPerson = common.ObjToString(obj["agencyperson"])
-        bi.Abstract.Default.AgencyTel = common.ObjToString(obj["agencytel"])
-        bi.Abstract.Default.SignEndTime = common.Int64All(obj["signendtime"])
-        bi.Abstract.Default.BidEndTime = common.Int64All(obj["bidendtime"])
-        bi.Abstract.Default.BidAmount = common.Float64All(obj["bidamount"])
-        entIdList, _ := obj["entidlist"].([]interface{})
-        entIds := common.ObjArrToStringArr(entIdList)
-        if obj["winnerorder"] != nil {
-            //中标候选人
-            winnerOrders := common.ObjArrToMapArr(obj["winnerorder"].([]interface{}))
-            if len(winnerOrders) > 0 {
-                winnerOrder := winnerOrders[0]
-                bi.Abstract.Default.WinnerInfos, bi.Abstract.Default.WinnerSeoMap = WinnerInfo(common.ObjToString(winnerOrder["entname"]), entIds, true)
-            }
-        } else if obj["s_winner"] != nil || obj["winner"] != nil {
-            //中标企业
-            winners := common.InterfaceToStr(obj["s_winner"])
-            if winners == "" {
-                winners = common.InterfaceToStr(obj["winner"])
-            }
-            bi.Abstract.Default.WinnerInfos, bi.Abstract.Default.WinnerSeoMap = WinnerInfo(winners, entIds, false)
-            if len(bi.Abstract.Default.WinnerInfos) > 0 {
-                bi.Abstract.Default.WinnerInfos[0].WinnerPerson = common.ObjToString(obj["winnerperson"])
-                bi.Abstract.Default.WinnerInfos[0].WinnerTel = common.ObjToString(obj["winnertel"])
-            }
-        }
-    }
-    //详情
-    bi.Detail.Detail = DetailFormat(strings.Trim(common.ObjToString(obj["detail"]), " "))
-    // p385调整为 除了从竞品爬虫到的新数据,不展示“查看原文链接”入口,其他公告都展示“查看原文链接”入口(包含客户管理系统-结构化数据,查看的标讯详情页)
-    //competehref字段来源:
-    infoFormat := common.IntAllDef(obj["infoformat"], 1)
-    obj["infoformat"] = infoFormat //信息类型,1代表标讯,2代表拟建,3代表产权
-    //href="#"为竞品
-    href := common.ObjToString(obj["href"])
-    //竞品及剑鱼信息发布的招标信息,不显示查看原文
-    if href != "" && href != "#" && common.ObjToString(obj["site"]) != consts.JyTxt {
-        bi.Detail.OriginalShow = true
-    }
-    //附件  且  附件可用
-    if isValidFile, _ := obj["isValidFile"].(bool); isValidFile && obj["projectinfo"] != nil {
-        projectInfo := common.ObjToMap(obj["projectinfo"])
-        if projectInfo != nil && (*projectInfo)["attachments"] != nil {
-            attachments := common.ObjToMap((*projectInfo)["attachments"])
-            for _, attachment := range *attachments {
-                at := common.ObjToMap(attachment)
-                if at != nil {
-                    fid := common.ObjToString((*at)["fid"])
-                    if fid != "" {
-                        bi.Detail.Attachments = append(bi.Detail.Attachments, entity.Attachment{
-                            FileName: common.ObjToString((*at)["filename"]),
-                            FileType: common.ObjToString((*at)["ftype"]),
-                            FileSize: common.ObjToString((*at)["size"]),
-                        })
-                    }
-                }
-            }
-        }
-    }
-    return bi
+	var (
+		bi = &entity.BidInfo{
+			BaseInfo: &entity.BidBaseInfo{},
+			Abstract: &entity.Abstract{},
+			Detail:   &entity.DetailInfo{},
+			CanRead:  true,
+			Topnet:   b,
+		}
+	)
+	//基本信息
+	bi.BaseInfo.Id = encrypt.EncodeArticleId2ByCheck(id)
+	industry := common.ObjToString(obj["s_subscopeclass"])
+	if industry != "" {
+		industry = strings.Replace(industry, "它", "他", -1)
+		industry = strings.Split(industry, ",")[0]
+	}
+	bi.BaseInfo.Industry = industry
+	title := common.ObjToString(obj["title"])
+	if len([]rune(title)) > dc.Config.TitleSize {
+		title = fmt.Sprintf("%s...", string([]rune(title)[:dc.Config.TitleSize]))
+	}
+	bi.BaseInfo.Title = title
+	bi.BaseInfo.Area = common.ObjToString(obj["area"])
+	bi.BaseInfo.Purchasing = common.ObjToString(obj["purchasing"])
+	bi.BaseInfo.ProjectName = common.ObjToString(obj["projectname"])
+	bi.BaseInfo.ProjectCode = common.ObjToString(obj["projectcode"])
+	bi.BaseInfo.City = common.ObjToString(obj["city"])
+	bi.BaseInfo.BuyerClass = common.ObjToString(obj["buyerclass"])
+	bi.BaseInfo.District = common.ObjToString(obj["district"])
+	bi.BaseInfo.Site = common.ObjToString(obj["site"])
+	bi.BaseInfo.SubType = common.ObjToString(obj["subtype"])
+	bi.BaseInfo.TopType = common.ObjToString(obj["toptype"])
+	if bi.BaseInfo.SubType == "" {
+		bi.BaseInfo.SubType = bi.BaseInfo.TopType
+	}
+	bi.BaseInfo.BidAmount = common.Int64All(obj["bidamount"])
+	bi.BaseInfo.Budget = common.Int64All(obj["budget"])
+	bi.BaseInfo.PublishTime = common.Int64All(obj["publishtime"])
+	bi.BaseInfo.BuyerSeoId = EsSeoId(false, common.InterfaceToStr(obj["buyer"]))
+	bi.BaseInfo.RecommendedService = common.IntAll(obj["recommended_service"])
+	bi.BaseInfo.InfoAttribute = common.InterfaceToStr(obj["infoattribute"])
+	bi.BaseInfo.PublicType = common.InterfaceToStr(obj["public_type"])
+	//摘要
+	switch bi.BaseInfo.SubType {
+	case "拟建":
+		bi.Abstract.Proposed = &entity.Proposed{}
+		bi.Abstract.Proposed.ProjectName = bi.BaseInfo.ProjectName
+		bi.Abstract.Proposed.Area = bi.BaseInfo.Area
+		bi.Abstract.Proposed.Buyer = common.ObjToString(obj["owner"])
+		if bi.Abstract.Proposed.Buyer != "" {
+			bi.Abstract.Proposed.BuyerPortraitShow = true // len(GetEntInfo(strings.Split(bi.Abstract.Proposed.Buyer, ","))) > 0
+		}
+		bi.Abstract.Proposed.BuyerClass = bi.BaseInfo.BuyerClass
+		bi.Abstract.Proposed.TotalInvestment = common.InterfaceToStr(obj["total_investment"])
+		bi.Abstract.Proposed.ProjectPeriod = common.ObjToString(obj["projectperiod"])
+		bi.Abstract.Proposed.Address = common.ObjToString(obj["projectaddr"])
+		bi.Abstract.Proposed.ApproveDept = common.ObjToString(obj["approvedept"])
+		bi.Abstract.Proposed.ApproveContent = common.ObjToString(obj["approvecontent"])
+		bi.Abstract.Proposed.ApproveCode = common.ObjToString(obj["approvecode"])
+		bi.Abstract.Proposed.ApprovalNumber = common.ObjToString(obj["approvenumber"])
+		bi.Abstract.Proposed.ApproveTime = common.ObjToString(obj["approvetime"])
+		bi.Abstract.Proposed.ApproveStatus = common.ObjToString(obj["approvestatus"])
+		bi.Abstract.Proposed.Content = common.ObjToString(obj["project_scale"])
+	default:
+		bi.Abstract.Default = &entity.Default{}
+		bi.Abstract.Default.Buyer = common.ObjToString(obj["buyer"])
+		if bi.Abstract.Default.Buyer != "" {
+			bi.Abstract.Default.BuyerPortraitShow = true // len(GetEntInfo(strings.Split(bi.Abstract.Default.Buyer, ","))) > 0
+		}
+		//判断是否公开联系人信息
+		if common.Int64All(obj["buyerhint"]) != 2 {
+			bi.Abstract.Default.BuyerPerson = common.ObjToString(obj["buyerperson"])
+			bi.Abstract.Default.BuyerTel = common.ObjToString(obj["buyertel"])
+			//ContactInfo(common.ObjToString(obj["buyerperson"]), common.ObjToString(obj["buyertel"]))
+		}
+		bi.Abstract.Default.Agency = common.ObjToString(obj["agency"])
+		bi.Abstract.Default.AgencyPerson = common.ObjToString(obj["agencyperson"])
+		bi.Abstract.Default.AgencyTel = common.ObjToString(obj["agencytel"])
+		signendTime := common.Int64All(obj["signendtime"])
+		if signendTime > 0 {
+			bi.Abstract.Default.SignEndTime = common.Int64All(obj["signendtime"]) //报名截止时间
+		}
+		bi.Abstract.Default.BidEndTime = common.Int64All(obj["bidendtime"])
+		bi.Abstract.Default.BidAmount = common.Float64All(obj["bidamount"])
+		entIdList, _ := obj["entidlist"].([]interface{})
+		entIds := common.ObjArrToStringArr(entIdList)
+		if obj["winnerorder"] != nil {
+			//中标候选人
+			winnerOrders := common.ObjArrToMapArr(obj["winnerorder"].([]interface{}))
+			if len(winnerOrders) > 0 {
+				winnerOrder := winnerOrders[0]
+				bi.Abstract.Default.WinnerInfos, bi.Abstract.Default.WinnerSeoMap = WinnerInfo(common.ObjToString(winnerOrder["entname"]), entIds, true)
+			}
+		} else if obj["s_winner"] != nil || obj["winner"] != nil {
+			//中标企业
+			winners := common.InterfaceToStr(obj["s_winner"])
+			if winners == "" {
+				winners = common.InterfaceToStr(obj["winner"])
+			}
+			bi.Abstract.Default.WinnerInfos, bi.Abstract.Default.WinnerSeoMap = WinnerInfo(winners, entIds, false)
+			if len(bi.Abstract.Default.WinnerInfos) > 0 {
+				bi.Abstract.Default.WinnerInfos[0].WinnerPerson = common.ObjToString(obj["winnerperson"])
+				bi.Abstract.Default.WinnerInfos[0].WinnerTel = common.ObjToString(obj["winnertel"])
+			}
+		}
+		bi.Abstract.Default.DeliverArea = common.InterfaceToStr(obj["deliver_area"])
+		bi.Abstract.Default.DeliverCity = common.InterfaceToStr(obj["deliver_city"])
+		bi.Abstract.Default.DeliverDistrict = common.InterfaceToStr(obj["deliver_district"])
+		if obj["purchasinglist"] != nil {
+			purchasingList := common.ObjArrToMapArr(obj["purchasinglist"].([]interface{}))
+			b, err := json.Marshal(purchasingList)
+			if err == nil && len(b) > 0 {
+				var pls []entity.PurchasingList
+				err = json.Unmarshal(b, &pls)
+				if err == nil && len(pls) > 0 {
+					bi.Abstract.Default.PurchasingList = append(bi.Abstract.Default.PurchasingList, pls...)
+				}
+			}
+			if err != nil {
+				log.Println("purchasinglist json  err:", err.Error())
+			}
+		}
+	}
+	//详情
+	bi.Detail.Detail = DetailFormat(strings.Trim(common.ObjToString(obj["detail"]), " "))
+	// p385调整为 除了从竞品爬虫到的新数据,不展示“查看原文链接”入口,其他公告都展示“查看原文链接”入口(包含客户管理系统-结构化数据,查看的标讯详情页)
+	//competehref字段来源:
+	infoFormat := common.IntAllDef(obj["infoformat"], 1)
+	obj["infoformat"] = infoFormat //信息类型,1代表标讯,2代表拟建,3代表产权
+	//href="#"为竞品
+	href := common.ObjToString(obj["href"])
+	//竞品及剑鱼信息发布的招标信息,不显示查看原文
+	if href != "" && href != "#" && common.ObjToString(obj["site"]) != consts.JyTxt {
+		bi.Detail.OriginalShow = true
+	}
+	//附件  且  附件可用
+	if isValidFile, _ := obj["isValidFile"].(bool); isValidFile && obj["projectinfo"] != nil {
+		projectInfo := common.ObjToMap(obj["projectinfo"])
+		if projectInfo != nil && (*projectInfo)["attachments"] != nil {
+			attachments := common.ObjToMap((*projectInfo)["attachments"])
+			for _, attachment := range *attachments {
+				at := common.ObjToMap(attachment)
+				if at != nil {
+					fid := common.ObjToString((*at)["fid"])
+					if fid != "" {
+						bi.Detail.Attachments = append(bi.Detail.Attachments, entity.Attachment{
+							FileName: common.ObjToString((*at)["filename"]),
+							FileType: common.ObjToString((*at)["ftype"]),
+							FileSize: common.ObjToString((*at)["size"]),
+						})
+					}
+				}
+			}
+		}
+	}
+	return bi
 }
 
 // 详情
 func DetailFormat(detail string) (fd string) {
-    if detail != "" {
-        //detail字段 缺少标签 处理
-        for _, v := range dc.Config.DetailElement {
-            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
-                }
-            }
-        }
-        fd = detail
-    }
-    return
+	if detail != "" {
+		//detail字段 缺少标签 处理
+		for _, v := range dc.Config.DetailElement {
+			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
+				}
+			}
+		}
+		fd = detail
+	}
+	return
 }
 
 // 联系人/联系方式
 func ContactInfo(name, link string) (str string) {
-    if name != "" && link != "" {
-        str = fmt.Sprintf("%s/%s", name, link)
-    } else if name == "" && link != "" {
-        str = link
-    } else if name != "" && link == "" {
-        str = name
-    }
-    return
+	if name != "" && link != "" {
+		str = fmt.Sprintf("%s/%s", name, link)
+	} else if name == "" && link != "" {
+		str = link
+	} else if name != "" && link == "" {
+		str = name
+	}
+	return
 }
 
 // 企业信息
 func WinnerInfo(winners string, winnerIds []string, candidate bool) (wis []entity.WinnerInfo, wsm map[string]interface{}) {
-    if winners == "" {
-        return
-    }
-    wsm = map[string]interface{}{}
-    winnerArr := strings.Split(winners, ",")
-    if len(winnerIds) != len(winnerArr) {
-        for _, v := range strings.Split(winners, ",") {
-            if v == "-" || v == "" {
-                continue
-            }
-            //临时更改为企业名称查询企业id
-            rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"should":[{"term":{"company_name":"%s"}},{"term":{"hname":"%s"}}],"minimum_should_match":1}},"_source":["name","_id","nseo_id","capital","company_phone"],"size":1}`, v, v))
-            if rData != nil && len(*rData) == 1 {
-                if entId := common.ObjToString((*rData)[0]["_id"]); entId != "" {
-                    wis = append(wis, entity.WinnerInfo{
-                        Winner:      v,
-                        WinnerId:    encrypt.EncodeArticleId2ByCheck(entId),
-                        IsCandidate: candidate,
-                    })
-                    wsm[v] = (*rData)[0]["nseo_id"]
-                }
-            }
-        }
-    } else {
-        for k, v := range winnerIds {
-            winnerId := common.ObjToString(v)
-            if winnerId == "-" || winnerId == "" {
-                continue
-            }
-            wis = append(wis, entity.WinnerInfo{
-                Winner:      winnerArr[k],
-                WinnerId:    encrypt.EncodeArticleId2ByCheck(winnerId),
-                IsCandidate: candidate,
-            })
-            wsm[winnerArr[k]] = EsSeoId(true, winnerId)
-        }
-    }
-    return
+	if winners == "" {
+		return
+	}
+	wsm = map[string]interface{}{}
+	winnerArr := strings.Split(winners, ",")
+	if len(winnerIds) != len(winnerArr) {
+		for _, v := range strings.Split(winners, ",") {
+			if v == "-" || v == "" {
+				continue
+			}
+			//临时更改为企业名称查询企业id
+			rData := elastic.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"should":[{"term":{"company_name":"%s"}},{"term":{"hname":"%s"}}],"minimum_should_match":1}},"_source":["name","_id","nseo_id","capital","company_phone"],"size":1}`, v, v))
+			if rData != nil && len(*rData) == 1 {
+				if entId := common.ObjToString((*rData)[0]["_id"]); entId != "" {
+					wis = append(wis, entity.WinnerInfo{
+						Winner:      v,
+						WinnerId:    encrypt.EncodeArticleId2ByCheck(entId),
+						IsCandidate: candidate,
+					})
+					wsm[v] = (*rData)[0]["nseo_id"]
+				}
+			}
+		}
+	} else {
+		for k, v := range winnerIds {
+			winnerId := common.ObjToString(v)
+			if winnerId == "-" || winnerId == "" {
+				continue
+			}
+			wis = append(wis, entity.WinnerInfo{
+				Winner:      winnerArr[k],
+				WinnerId:    encrypt.EncodeArticleId2ByCheck(winnerId),
+				IsCandidate: candidate,
+			})
+			wsm[winnerArr[k]] = EsSeoId(true, winnerId)
+		}
+	}
+	return
 }
 
 // 采购单位 中标企业 seo 信息
 func EsSeoId(isWinner bool, idName string) string {
-    if idName == "" {
-        return idName
-    }
-    var seoId string
-    redisKey := fmt.Sprintf("getSeoId_%v_%s", isWinner, idName)
-    seoId = redis.GetStr(consts.RedisNewOther, redisKey)
-    if seoId != "" {
-        return seoId
-    }
+	if idName == "" {
+		return idName
+	}
+	var seoId string
+	redisKey := fmt.Sprintf("getSeoId_%v_%s", isWinner, idName)
+	seoId = redis.GetStr(consts.RedisNewOther, redisKey)
+	if seoId != "" {
+		return seoId
+	}
 
-    if isWinner {
-        winnerSeo := elastic.GetById("qyxy", "qyxy", idName)
-        if winnerSeo != nil && len(*winnerSeo) > 0 {
-            seoId = common.InterfaceToStr((*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 = common.InterfaceToStr((*winnerSeo)[0]["seo_id"])
-        }
-    }
-    if seoId != "" {
-        redis.Put("newother", redisKey, seoId, -1)
-    }
-    return seoId
+	if isWinner {
+		winnerSeo := elastic.GetById("qyxy", "qyxy", idName)
+		if winnerSeo != nil && len(*winnerSeo) > 0 {
+			seoId = common.InterfaceToStr((*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 = common.InterfaceToStr((*winnerSeo)[0]["seo_id"])
+		}
+	}
+	if seoId != "" {
+		redis.Put("newother", redisKey, seoId, -1)
+	}
+	return seoId
 }
 
 // 手机号
 func NumberCodeFormat(bi *entity.BidInfo) {
-    //采购电话中标单位电话置空
-    if bi.Abstract.Default.BuyerPerson != "" {
-        bi.Abstract.Default.BuyerPerson = "freeView"
-        bi.Abstract.Default.BuyerTel = ""
-    }
-    if len(bi.Abstract.Default.WinnerInfos) > 0 {
-        bi.Abstract.Default.WinnerInfos[0].WinnerPerson = "freeView"
-        bi.Abstract.Default.WinnerInfos[0].WinnerTel = ""
-    }
-    //正文电话 手机号 邮箱处理
-    if bi.Detail.Detail != "" {
-        //手机号
-        detail := regexp.MustCompile("1[345789]{1}\\d{9}").ReplaceAllString(bi.Detail.Detail, `<span class="freeView">点击查看</span>`)
-        //项目代码
-        code := bi.BaseInfo.ProjectCode
-        if code != "" {
-            detail = strings.ReplaceAll(detail, code, "*********")
-        }
-        //座机
-        landlineRegexp := regexp.MustCompile("((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?")
-        detail = landlineRegexp.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
-        landlineRegexp400 := regexp.MustCompile("((400)-)(\\d{3,4}-)(\\d{3,})")
-        detail = landlineRegexp400.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
-        //邮箱
-        mailboxRegexp := 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})(\\]?)")
-        detail = mailboxRegexp.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
-        bi.Detail.Detail = strings.ReplaceAll(strings.ReplaceAll(detail, `<span class="freeView">点击查看</span><span class="freeView">点击查看</span>`, `<span class="freeView">点击查看</span>`), "*********", code)
-    }
+	//采购电话中标单位电话置空
+	if bi.Abstract.Default.BuyerPerson != "" {
+		bi.Abstract.Default.BuyerPerson = "freeView"
+		bi.Abstract.Default.BuyerTel = ""
+	}
+	if len(bi.Abstract.Default.WinnerInfos) > 0 {
+		bi.Abstract.Default.WinnerInfos[0].WinnerPerson = "freeView"
+		bi.Abstract.Default.WinnerInfos[0].WinnerTel = ""
+	}
+	//正文电话 手机号 邮箱处理
+	if bi.Detail.Detail != "" {
+		//手机号
+		detail := regexp.MustCompile("1[345789]{1}\\d{9}").ReplaceAllString(bi.Detail.Detail, `<span class="freeView">点击查看</span>`)
+		//项目代码
+		code := bi.BaseInfo.ProjectCode
+		if code != "" {
+			detail = strings.ReplaceAll(detail, code, "*********")
+		}
+		//座机
+		landlineRegexp := regexp.MustCompile("((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?")
+		detail = landlineRegexp.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
+		landlineRegexp400 := regexp.MustCompile("((400)-)(\\d{3,4}-)(\\d{3,})")
+		detail = landlineRegexp400.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
+		//邮箱
+		mailboxRegexp := 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})(\\]?)")
+		detail = mailboxRegexp.ReplaceAllString(detail, `<span class="freeView">点击查看</span>`)
+		bi.Detail.Detail = strings.ReplaceAll(strings.ReplaceAll(detail, `<span class="freeView">点击查看</span><span class="freeView">点击查看</span>`, `<span class="freeView">点击查看</span>`), "*********", code)
+	}
 }
 
 // 关键词
 func KeyWordHandle(obj map[string]interface{}) string {
-    keywordArr := []string{}
-    owner := common.InterfaceToStr(obj["owner"])
-    buyer := common.InterfaceToStr(obj["buyer"])
-    if buyer == "" {
-        buyer = owner
-    }
-    if buyer != "" && buyer != dc.Config.DetailMosaicTxt {
-        keywordArr = append(keywordArr, buyer)
-    }
-    if common.InterfaceToStr(obj["s_winner"]) != "" && common.InterfaceToStr(obj["s_winner"]) != dc.Config.DetailMosaicTxt {
-        keywordArr = append(keywordArr, common.InterfaceToStr(obj["s_winner"]))
-    }
-    if obj["purchasinglist"] != nil && obj["purchasinglist"] != "" {
-        i := 0
-        for _, v := range gconv.SliceMap(obj["purchasinglist"]) {
-            if i == 5 {
-                break
-            }
-            if common.InterfaceToStr(v["itemname"]) != "" && common.InterfaceToStr(obj["s_winner"]) != dc.Config.DetailMosaicTxt {
-                keywordArr = append(keywordArr, common.InterfaceToStr(v["itemname"]))
-                i++
-            }
-        }
-    }
-    if common.InterfaceToStr(obj["subtype"]) != "" && common.InterfaceToStr(obj["subtype"]) != "其它" {
-        keywordArr = append(keywordArr, consts.TypeCodeMap[common.InterfaceToStr(obj["subtype"])])
-    }
-    if common.InterfaceToStr(obj["area"]) != "" {
-        keywordArr = append(keywordArr, common.InterfaceToStr(obj["area"])+"招标")
-    }
-    if common.InterfaceToStr(obj["city"]) != "" {
-        keywordArr = append(keywordArr, common.InterfaceToStr(obj["city"])+"招标")
-    }
-    keywordArr = append(keywordArr, "剑鱼标讯")
-    keyword := strings.Join(keywordArr, ",")
-    return keyword
+	keywordArr := []string{}
+	owner := common.InterfaceToStr(obj["owner"])
+	buyer := common.InterfaceToStr(obj["buyer"])
+	if buyer == "" {
+		buyer = owner
+	}
+	if buyer != "" && buyer != dc.Config.DetailMosaicTxt {
+		keywordArr = append(keywordArr, buyer)
+	}
+	if common.InterfaceToStr(obj["s_winner"]) != "" && common.InterfaceToStr(obj["s_winner"]) != dc.Config.DetailMosaicTxt {
+		keywordArr = append(keywordArr, common.InterfaceToStr(obj["s_winner"]))
+	}
+	if obj["purchasinglist"] != nil && obj["purchasinglist"] != "" {
+		i := 0
+		for _, v := range gconv.SliceMap(obj["purchasinglist"]) {
+			if i == 5 {
+				break
+			}
+			if common.InterfaceToStr(v["itemname"]) != "" && common.InterfaceToStr(obj["s_winner"]) != dc.Config.DetailMosaicTxt {
+				keywordArr = append(keywordArr, common.InterfaceToStr(v["itemname"]))
+				i++
+			}
+		}
+	}
+	if common.InterfaceToStr(obj["subtype"]) != "" && common.InterfaceToStr(obj["subtype"]) != "其它" {
+		keywordArr = append(keywordArr, consts.TypeCodeMap[common.InterfaceToStr(obj["subtype"])])
+	}
+	if common.InterfaceToStr(obj["area"]) != "" {
+		keywordArr = append(keywordArr, common.InterfaceToStr(obj["area"])+"招标")
+	}
+	if common.InterfaceToStr(obj["city"]) != "" {
+		keywordArr = append(keywordArr, common.InterfaceToStr(obj["city"])+"招标")
+	}
+	keywordArr = append(keywordArr, "剑鱼标讯")
+	keyword := strings.Join(keywordArr, ",")
+	return keyword
 }
 
 // 描述
 func DescriptionHandle(stype string, obj map[string]interface{}) string {
-    description := ""
-    publishtime := common.Int64All(obj["l_publishtime"])
-    if publishtime == 0 {
-        publishtime = common.Int64All(obj["publishtime"])
-    }
-    pushTime := time.Unix(publishtime, 0)
-    title := common.InterfaceToStr(obj["title"])
-    owner := common.InterfaceToStr(obj["owner"])
-    buyer := common.InterfaceToStr(obj["buyer"])
-    if buyer == "" {
-        buyer = owner
-    }
-    s_winner := common.InterfaceToStr(obj["s_winner"])
-    area := common.InterfaceToStr(obj["area"])
-    city := common.InterfaceToStr(obj["city"])
-    if stype == "bdprivate" {
-        //bdprivate
-        //{项目标题},采购单位:{采购单位名称},成交供应商:{中标企业名称},公告日期:{公告日期}。
-        descriptionArr := []string{}
-        if title != "" {
-            descriptionArr = append(descriptionArr, title)
-        }
-        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, title)
-        }
-        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
+	description := ""
+	publishtime := common.Int64All(obj["l_publishtime"])
+	if publishtime == 0 {
+		publishtime = common.Int64All(obj["publishtime"])
+	}
+	pushTime := time.Unix(publishtime, 0)
+	title := common.InterfaceToStr(obj["title"])
+	owner := common.InterfaceToStr(obj["owner"])
+	buyer := common.InterfaceToStr(obj["buyer"])
+	if buyer == "" {
+		buyer = owner
+	}
+	s_winner := common.InterfaceToStr(obj["s_winner"])
+	area := common.InterfaceToStr(obj["area"])
+	city := common.InterfaceToStr(obj["city"])
+	if stype == "bdprivate" {
+		//bdprivate
+		//{项目标题},采购单位:{采购单位名称},成交供应商:{中标企业名称},公告日期:{公告日期}。
+		descriptionArr := []string{}
+		if title != "" {
+			descriptionArr = append(descriptionArr, title)
+		}
+		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, title)
+		}
+		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
 }

+ 20 - 0
src/jfw/modules/publicapply/src/detail/entity/entity.go

@@ -37,6 +37,22 @@ type BidBaseInfo struct {
 	Keywords           string `json:"keywords"`           //关键词-seo  待处理
 	Description        string `json:"description"`        //描述-seo  待处理
 	RecommendedService int    `json:"recommendedService"` //业主发布 排名考前,默认0
+	InfoAttribute      string `json:"infoAttribute"`      //zc_cgxx --- 采购信息
+	PublicType         string `json:"publicType"`         //发布方式:个人发布 or 平台发布
+}
+type PurchasingList struct {
+	Number      float64     `json:"number"`      //数量
+	Table       interface{} `json:"table"`       //
+	ItemName    string      `json:"itemname"`    //产品名称
+	Model       string      `json:"model"`       //型号
+	UnitPrice   float64     `json:"unitprice"`   //单价(预算单价)
+	Root        string      `json:"root"`        //
+	TotalPrice  float64     `json:"totalprice"`  //小计(预算)
+	Score       float64     `json:"score"`       //
+	BrandName   string      `json:"brandname"`   //品牌
+	UnitName    string      `json:"unitname"`    //单位
+	Code        string      `json:"code"`        //
+	Reliability float64     `json:"reliability"` //
 }
 
 // 摘要
@@ -68,6 +84,10 @@ type Default struct {
 	WinnerInfos       []WinnerInfo           `json:"winnerInfos"`       //中标企业信息
 	WinnerSeoMap      map[string]interface{} `json:"winnerSeoMap"`      //中标企业seo 对应的id 我也不知道是啥
 	BidAmount         float64                `json:"bidAmount"`         //中标金额
+	PurchasingList    []PurchasingList       `json:"purchasingList"`    //采购清单
+	DeliverArea       string                 `json:"deliverArea"`       //交付省份
+	DeliverCity       string                 `json:"deliverCity"`       //交付城市
+	DeliverDistrict   string                 `json:"deliverDistrict"`   //交付地区
 }
 
 // 拟建

+ 2 - 2
src/jfw/modules/publicapply/src/go.sum

@@ -20,8 +20,8 @@ app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66/go.mod h1:XHNATN6t
 app.yhyue.com/moapp/jyfs v0.0.0-20231024061508-480c270480d4/go.mod h1:61hzZ3dZHXL28BNl8BOgZsvM2S5UVY5YFzOkEUPrSu4=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545 h1:+Lak4m1zgsigQloOsvp8AJ+0XeX/+PGp9QP550xlbBQ=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545/go.mod h1:uFrsdUBFbETiJlEmr4PtJWPsZlUpPj2bHQRhryu6ggk=
-app.yhyue.com/moapp/jypkg v1.22.7 h1:7azZJOhvoJasnKHEab4QF8cwIc5DOthOpmDh85Tif7I=
-app.yhyue.com/moapp/jypkg v1.22.7/go.mod h1:FylaC4MJ4G36WndktgeZfc8jTq3uvBGWIwbk02xfdQI=
+app.yhyue.com/moapp/jypkg v1.22.9 h1:tIcjYsDOBUM7vB5t4/qlGJY4XUI43Edfi3mmkmobH0Q=
+app.yhyue.com/moapp/jypkg v1.22.9/go.mod h1:FylaC4MJ4G36WndktgeZfc8jTq3uvBGWIwbk02xfdQI=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161 h1:WGi4OEIoqw6NpNFGioUEBZnjK9aBa+xJqf/5WY+QyhM=
 app.yhyue.com/moapp/message v0.0.0-20231204024949-8c7145bfc161/go.mod h1:0Oj8SB4pVjdCLD28sy2zyM3hS0WHGpNuVcakLW43GmI=
 bp.jydev.jianyu360.cn/BP/jynsq v0.0.0-20220222052708-ebc43af90698/go.mod h1:ojo/AUH9Yr1wzarEjOaNMkj1Cet/9r8IgLyba64Z52E=