1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045 |
- package main
- import (
- "fmt"
- "log"
- qutil "qfw/util"
- "qfw/util/mongodb"
- "strings"
- "sync"
- "time"
- )
- type Info struct {
- id string //id
- title string //标题
- area string //省份
- city string //城市
- subtype string //信息类型
- buyer string //采购单位
- agency string //代理机构
- winner string //中标单位
- budget float64 //预算金额
- bidamount float64 //中标金额
- projectname string //项目名称
- projectcode string //项目编号
- contractnumber string //合同编号
- publishtime int64 //发布时间
- comeintime int64 //入库时间
- bidopentime int64 //开标时间
- agencyaddr string //开标地点
- site string //站点
- href string //正文的url
- repeatid string //重复id
- titleSpecialWord bool //标题特殊词
- specialWord bool //再次判断的特殊词
- mergemap map[string]interface{} //合并记录
- is_site bool //是否站点城市
- }
- var datelimit = float64(432000) //五天
- var sitelock sync.Mutex //锁
- //一般数据判重
- type datamap struct {
- lock sync.Mutex //锁
- days int //保留几天数据
- data map[string][]*Info
- keymap []string
- keys map[string]bool
- }
- //历史更新数据
- type historymap struct {
- lock sync.Mutex //锁
- days int //保留几天数据
- data map[string][]*Info
- keymap []string
- keys map[string]bool
- }
- func NewDatamap(days int, lastid string) *datamap {
- datelimit = qutil.Float64All(days * 86400)
- dm := &datamap{sync.Mutex{}, days, map[string][]*Info{}, []string{}, map[string]bool{}}
- if lastid == "" {
- return dm
- }
- //初始化加载数据
- sess := mgo.GetMgoConn()
- defer mgo.DestoryMongoConn(sess)
- query := map[string]interface{}{"_id": map[string]interface{}{
- "$lte": StringTOBsonId(lastid),
- }}
- log.Println("query", query)
- it := sess.DB(mgo.DbName).C(extract).Find(query).Sort("-_id").Iter()
- now1 := int64(0)
- n, continuSum := 0, 0
- for tmp := make(map[string]interface{}); it.Next(&tmp); n++ {
- if qutil.IntAll(tmp["repeat"]) == 1 || qutil.IntAll(tmp["repeat"]) == -1 {
- continuSum++
- } else {
- pt := tmp["comeintime"]
- if Is_Sort {
- pt = tmp["publishtime"]
- }
- pt_time := qutil.Int64All(pt)
- if pt_time <= 0 {
- continue
- }
- if now1 == 0 {
- now1 = pt_time
- }
- if qutil.Float64All(now1-pt_time) < datelimit {
- info := NewInfo(tmp)
- dkey := qutil.FormatDateWithObj(&pt, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, info.subtype, info.area)
- data := dm.data[k]
- if data == nil {
- data = []*Info{}
- }
- data = append(data, info)
- dm.data[k] = data
- dm.keys[dkey] = true
- } else {
- break
- }
- }
- if n%5000 == 0 {
- log.Println("current n:", n, continuSum)
- }
- tmp = make(map[string]interface{})
- }
- log.Println("load data:", n)
- return dm
- }
- //构建新历史数据池
- func NewHistorymap(startid string, lastid string, startTime int64, lastTime int64) *historymap {
- datelimit = qutil.Float64All(5 * 86400)
- hm := &historymap{sync.Mutex{}, 5, map[string][]*Info{}, []string{}, map[string]bool{}}
- if lastid == "" || startid == "" {
- return hm
- }
- //取startid之前5天
- sess_start := mgo.GetMgoConn()
- defer mgo.DestoryMongoConn(sess_start) //lte gte
- it_start := sess_start.DB(mgo.DbName).C(extract).Find(mongodb.ObjToMQ(`{"_id":{"$lte":"`+startid+`"}}`,
- true)).Sort("-_id").Iter()
- m, n := 0, 0
- for tmp_start := make(map[string]interface{}); it_start.Next(&tmp_start); {
- pt_s := tmp_start["comeintime"]
- if Is_Sort {
- pt_s = tmp_start["publishtime"]
- }
- pt_time := qutil.Int64All(pt_s)
- if pt_time <= 0 {
- continue
- }
- if qutil.Float64All(startTime-pt_time) <= datelimit {
- n++
- info := NewInfo(tmp_start)
- dkey := qutil.FormatDateWithObj(&pt_s, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, info.subtype, info.area)
- data := hm.data[k]
- if data == nil {
- data = []*Info{}
- }
- data = append(data, info)
- hm.data[k] = data
- hm.keys[dkey] = true
- } else {
- break
- }
- tmp_start = make(map[string]interface{})
- }
- log.Println("load history 前:", n)
- //取lastid之后5天
- sess_last := mgo.GetMgoConn()
- defer mgo.DestoryMongoConn(sess_last) //lte gte
- it_last := sess_last.DB(mgo.DbName).C(extract).Find(mongodb.ObjToMQ(`{"_id":{"$gte":"`+lastid+`"}}`,
- true)).Sort("_id").Iter()
- for tmp_last := make(map[string]interface{}); it_last.Next(&tmp_last); {
- pt_l := tmp_last["comeintime"]
- if Is_Sort {
- pt_l = tmp_last["publishtime"]
- }
- pt_time := qutil.Int64All(pt_l)
- if pt_time <= 0 {
- continue
- }
- if qutil.Float64All(pt_time-lastTime) <= datelimit {
- m++
- info := NewInfo(tmp_last)
- dkey := qutil.FormatDateWithObj(&pt_l, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, info.subtype, info.area)
- data := hm.data[k]
- if data == nil {
- data = []*Info{}
- }
- data = append(data, info)
- hm.data[k] = data
- hm.keys[dkey] = true
- } else {
- break
- }
- tmp_last = make(map[string]interface{})
- }
- log.Println("load history 后:", m)
- return hm
- }
- func NewInfo(tmp map[string]interface{}) *Info {
- subtype := qutil.ObjToString(tmp["subtype"])
- area := qutil.ObjToString(tmp["area"])
- if area == "A" {
- area = "全国"
- }
- info := &Info{}
- info.id = BsonTOStringId(tmp["_id"])
- info.title = qutil.ObjToString(tmp["title"])
- info.area = area
- info.subtype = subtype
- info.buyer = qutil.ObjToString(tmp["buyer"])
- info.projectname = qutil.ObjToString(tmp["projectname"])
- info.contractnumber = qutil.ObjToString(tmp["contractnumber"])
- info.projectcode = qutil.ObjToString(tmp["projectcode"])
- info.city = qutil.ObjToString(tmp["city"])
- info.agency = qutil.ObjToString(tmp["agency"])
- info.winner = qutil.ObjToString(tmp["winner"])
- info.budget = qutil.Float64All(tmp["budget"])
- info.bidamount = qutil.Float64All(tmp["bidamount"])
- info.publishtime = qutil.Int64All(tmp["publishtime"])
- info.comeintime = qutil.Int64All(tmp["comeintime"])
- info.bidopentime = qutil.Int64All(tmp["bidopentime"])
- info.agencyaddr = qutil.ObjToString(tmp["agencyaddr"])
- info.site = qutil.ObjToString(tmp["site"])
- info.href = qutil.ObjToString(tmp["href"])
- info.repeatid = qutil.ObjToString(tmp["repeatid"])
- info.specialWord = FilterRegTitle.MatchString(info.title)
- info.titleSpecialWord = FilterRegTitle_1.MatchString(info.title) || FilterRegTitle_2.MatchString(info.title)
- info.mergemap = *qutil.ObjToMap(tmp["merge_map"])
- if info.mergemap == nil {
- info.mergemap = make(map[string]interface{}, 0)
- }
- info.is_site = false
- return info
- }
- //判重方法
- func (d *datamap) check(info *Info) (b bool, source *Info, reasons string) {
- reason := ""
- keys := []string{}
- d.lock.Lock()
- for k, _ := range d.keys { //不同时间段
- keys = append(keys, fmt.Sprintf("%s_%s_%s", k, info.subtype, info.area))
- if info.area != "全国" { //这个后续可以不要
- keys = append(keys, fmt.Sprintf("%s_%s_%s", k, info.subtype, "全国"))
- }
- }
- d.lock.Unlock()
- L:
- for _, k := range keys {
- d.lock.Lock()
- data := d.data[k]
- d.lock.Unlock()
- if len(data) > 0 { //对比v 找到同类型,同省或全国的数据作对比
- for _, v := range data {
- reason = ""
- if v.id == info.id { //正常重复
- return false, v, ""
- }
- if info.subtype == v.subtype {
- if info.site != "" {
- sitelock.Lock()
- dict := SiteMap[info.site]
- sitelock.Unlock()
- if dict != nil {
- if info.area == "全国" && dict["area"] != "" {
- info.is_site = true
- info.area = qutil.ObjToString(dict["area"])
- info.city = qutil.ObjToString(dict["city"])
- } else {
- if info.city == "" && dict["city"] != "" {
- info.is_site = true
- info.area = qutil.ObjToString(dict["area"])
- info.city = qutil.ObjToString(dict["city"])
- }
- }
- }
- }
- //前置条件1 - 站点相关
- if info.site != "" && info.site == v.site {
- if info.href != "" && info.href == v.href {
- reason = "href相同"
- b = true
- source = v
- reasons = reason
- break L
- }
- if info.href != "" && info.href != v.href {
- reason = "href不同-"
- }
- }
- //前置条件2 - 标题相关,有且一个关键词
- if ((info.titleSpecialWord && !v.titleSpecialWord) || (info.specialWord && !v.specialWord)) &&
- info.title != v.title && v.title != "" && info.title != "" {
- continue
- }
- //前置条件3 - 标题相关,均含有关键词
- if ((info.titleSpecialWord && v.titleSpecialWord) || (info.specialWord && v.specialWord)) &&
- len([]rune(v.title)) > 10 && len([]rune(info.title)) > 10 && v.title != "" && info.title != "" {
- if !(strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title)) {
- continue //无包含关系
- }
- if strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title) {
- reason = reason + "标题关键词且包含关系"
- //继续二级金额判断
- if !againRepeat(v, info) {
- b = true
- source = v
- reasons = reason
- break
- }
- }
- }
- //代理机构相同-非空相等
- if v.agency != "" && info.agency != "" && v.agency == info.agency {
- reason = reason + "同机构-"
- repeat := false
- if repeat, reason = quickHeavyMethodTwo(v, info, reason); repeat {
- b = true
- source = v
- reasons = reason
- break
- }
- } else {
- reason = reason + "非同机构-"
- if info.city != "" && info.city == v.city {
- reason = reason + "同城-"
- repeat := false
- if repeat, reason = quickHeavyMethodTwo(v, info, reason); repeat {
- b = true
- source = v
- reasons = reason
- break
- }
- } else {
- reason = reason + "不同城-"
- repeat := false
- if repeat, reason = quickHeavyMethodOne(v, info, reason); repeat {
- b = true
- source = v
- reasons = reason
- break
- }
- }
- }
- }
- }
- }
- }
- //往预存数据 d 添加
- if !b {
- ct := info.comeintime
- if Is_Sort {
- ct = info.publishtime
- }
- dkey := qutil.FormatDateByInt64(&ct, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, info.subtype, info.area)
- d.lock.Lock()
- data := d.data[k]
- if data == nil {
- data = []*Info{info}
- d.data[k] = data
- if !d.keys[dkey] {
- d.keys[dkey] = true
- d.update(ct)
- }
- } else {
- data = append(data, info)
- d.data[k] = data
- }
- d.lock.Unlock()
- }
- return
- }
- func (h *historymap) checkHistory(info *Info) (b bool, source *Info, reasons string) {
- reason := ""
- keys := []string{}
- h.lock.Lock()
- for k, _ := range h.keys { //不同时间段
- keys = append(keys, fmt.Sprintf("%s_%s_%s", k, info.subtype, info.area))
- if info.area != "全国" { //这个后续可以不要
- keys = append(keys, fmt.Sprintf("%s_%s_%s", k, info.subtype, "全国"))
- }
- }
- h.lock.Unlock()
- L:
- for _, k := range keys {
- h.lock.Lock()
- data := h.data[k]
- h.lock.Unlock()
- if len(data) > 0 { //对比v 找到同类型,同省或全国的数据作对比
- for _, v := range data {
- reason = ""
- if v.id == info.id { //正常重复
- return false, v, ""
- }
- if info.subtype == v.subtype {
- if info.site != "" {
- sitelock.Lock()
- dict := SiteMap[info.site]
- sitelock.Unlock()
- if dict != nil {
- if info.area == "全国" && dict["area"] != "" {
- info.area = qutil.ObjToString(dict["area"])
- info.city = qutil.ObjToString(dict["city"])
- } else {
- if info.city == "" && dict["city"] != "" {
- info.area = qutil.ObjToString(dict["area"])
- info.city = qutil.ObjToString(dict["city"])
- }
- }
- }
- }
- //前置条件1 - 站点相关
- if info.site != "" && info.site == v.site {
- if info.href != "" && info.href == v.href {
- reason = "href相同"
- b = true
- source = v
- reasons = reason
- break L
- }
- if info.href != "" && info.href != v.href {
- reason = "href不同-"
- }
- }
- //前置条件2 - 标题相关,有且一个关键词
- if ((info.titleSpecialWord && !v.titleSpecialWord) || (info.specialWord && !v.specialWord)) &&
- info.title != v.title && v.title != "" && info.title != "" {
- continue
- }
- //前置条件3 - 标题相关,均含有关键词
- if ((info.titleSpecialWord && v.titleSpecialWord) || (info.specialWord && v.specialWord)) &&
- len([]rune(v.title)) > 10 && len([]rune(info.title)) > 10 && v.title != "" && info.title != "" {
- if !(strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title)) {
- continue //无包含关系
- }
- if strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title) {
- reason = reason + "标题关键词且包含关系"
- //继续二级金额判断
- if !againRepeat(v, info) {
- b = true
- source = v
- reasons = reason
- break
- }
- }
- }
- //代理机构相同-非空相等
- if v.agency != "" && info.agency != "" && v.agency == info.agency {
- reason = reason + "同机构-"
- repeat := false
- if repeat, reason = quickHeavyMethodTwo(v, info, reason); repeat {
- b = true
- source = v
- reasons = reason
- break
- }
- } else {
- reason = reason + "非同机构-"
- if info.city != "" && info.city == v.city {
- reason = reason + "同城-"
- repeat := false
- if repeat, reason = quickHeavyMethodTwo(v, info, reason); repeat {
- b = true
- source = v
- reasons = reason
- break
- }
- } else {
- reason = reason + "不同城-"
- repeat := false
- if repeat, reason = quickHeavyMethodOne(v, info, reason); repeat {
- b = true
- source = v
- reasons = reason
- break
- }
- }
- }
- }
- }
- }
- }
- //
- if b {
- if info.repeatid == source.id {
- b = false //重复-无变化-不处理
- }
- } else {
- if source != nil {
- if source.repeatid != "" { //未判重-有变化--记录
- b = true
- reason = "未判重记录"
- reasons = reason
- }
- }
- }
- //往预存数据 d 添加
- if !b {
- ct := info.comeintime
- if Is_Sort {
- ct = info.publishtime
- }
- dkey := qutil.FormatDateByInt64(&ct, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, info.subtype, info.area)
- data := h.data[k]
- if data == nil {
- data = []*Info{info}
- h.data[k] = data
- if !h.keys[dkey] {
- h.keys[dkey] = true
- //h.update(ct)
- }
- } else {
- data = append(data, info)
- h.data[k] = data
- }
- }
- return
- }
- //替换原始数据池
- func (d *datamap) replaceSourceData(replaceData *Info, replaceId string) {
- ct := replaceData.comeintime
- if Is_Sort {
- ct = replaceData.publishtime
- }
- dkey := qutil.FormatDateByInt64(&ct, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, replaceData.subtype, replaceData.area)
- d.lock.Lock()
- data := d.data[k]
- if data == nil {
- data = []*Info{replaceData}
- d.data[k] = data
- if !d.keys[dkey] {
- d.keys[dkey] = true
- }
- } else {
- //遍历替换
- for k, v := range data {
- if v.id == replaceId {
- data[k] = replaceData
- break
- }
- }
- d.data[k] = data
- }
- d.lock.Unlock()
- }
- func (h *historymap) replaceSourceData(replaceData *Info, replaceId string) {
- ct := replaceData.comeintime
- if Is_Sort {
- ct = replaceData.publishtime
- }
- dkey := qutil.FormatDateByInt64(&ct, qutil.Date_yyyyMMdd)
- k := fmt.Sprintf("%s_%s_%s", dkey, replaceData.subtype, replaceData.area)
- h.lock.Lock()
- data := h.data[k]
- if data == nil {
- data = []*Info{replaceData}
- h.data[k] = data
- if !h.keys[dkey] {
- h.keys[dkey] = true
- }
- } else {
- //遍历替换
- for k, v := range data {
- if v.id == replaceId {
- data[k] = replaceData
- break
- }
- }
- h.data[k] = data
- }
- h.lock.Unlock()
- }
- func (d *datamap) update(t int64) {
- //每天0点清除历史数据
- d.keymap = d.GetLatelyFiveDay(t)
- m := map[string]bool{}
- for _, v := range d.keymap {
- m[v] = true
- }
- all, all1 := 0, 0
- for k, v := range d.data {
- all += len(v)
- if !m[k[:8]] {
- delete(d.data, k)
- }
- }
- for k, _ := range d.keys {
- if !m[k] {
- delete(d.keys, k)
- }
- }
- for _, v := range d.data {
- all1 += len(v)
- }
- //log.Println("更新前后数据:", all, all1)
- }
- func (d *datamap) GetLatelyFiveDay(t int64) []string {
- array := make([]string, d.days)
- now := time.Unix(t, 0)
- for i := 0; i < d.days; i++ {
- array[i] = now.Format(qutil.Date_yyyyMMdd)
- now = now.AddDate(0, 0, -1)
- }
- return array
- }
- /*
- **************************
- ******* 以下为判重 ********
- **************************
- */
- //判重方法1
- func quickHeavyMethodOne(v *Info, info *Info, reason string) (bool, string) {
- isMeet := false
- if info.subtype == "招标" || info.subtype == "邀标" || info.subtype == "询价" ||
- info.subtype == "竞谈" || info.subtype == "单一" || info.subtype == "竞价" ||
- info.subtype == "变更" || info.subtype == "其他" {
- //招标结果
- if isMeet, reason = tenderRepeat_A(v, info, reason); isMeet {
- if tenderRepeat_C(v, info) {
- return false, reason
- } else {
- reason = reason + "---招标类"
- return true, reason
- }
- } else {
- return false, reason
- }
- } else if info.subtype == "中标" || info.subtype == "成交" || info.subtype == "废标" || info.subtype == "流标" {
- //中标结果
- if isMeet, reason = winningRepeat_A(v, info, reason); isMeet {
- if winningRepeat_C(v, info) {
- return false, reason
- } else {
- reason = reason + "---中标类"
- return true, reason
- }
- } else {
- return false, reason
- }
- } else if info.subtype == "合同" || info.subtype == "验收" || info.subtype == "违规" {
- //合同
- if isMeet, reason = contractRepeat_A(v, info, reason); isMeet {
- if contractRepeat_C(v, info) {
- return false, reason
- } else {
- reason = reason + "---合同类"
- return true, reason
- }
- } else {
- return false, reason
- }
- } else {
- //招标结果
- if isMeet, reason = tenderRepeat_A(v, info, reason); isMeet {
- if tenderRepeat_C(v, info) {
- return false, reason
- } else {
- reason = reason + "---类别空-招标类"
- return true, reason
- }
- } else {
- return false, reason
- }
- }
- return false, reason
- }
- //判重方法2
- func quickHeavyMethodTwo(v *Info, info *Info, reason string) (bool, string) {
- isMeet := false
- if v.agency == info.agency && v.agency != "" && info.agency != "" {
- if info.subtype == "招标" || info.subtype == "邀标" || info.subtype == "询价" ||
- info.subtype == "竞谈" || info.subtype == "单一" || info.subtype == "竞价" ||
- info.subtype == "变更" || info.subtype == "其他" {
- //招标结果
- if isMeet, reason = tenderRepeat_B(v, info, reason); isMeet {
- if tenderRepeat_C(v, info) { //有不同
- return false, reason
- } else {
- reason = reason + "---招标类"
- return true, reason
- }
- } else {
- return false, reason
- }
- } else if info.subtype == "中标" || info.subtype == "成交" || info.subtype == "废标" || info.subtype == "流标" {
- //中标结果
- if isMeet, reason = winningRepeat_B(v, info, reason); isMeet {
- if winningRepeat_C(v, info) { //有不同
- return false, reason
- } else {
- reason = reason + "---中标类"
- return true, reason
- }
- } else {
- return false, reason
- }
- } else if info.subtype == "合同" || info.subtype == "验收" || info.subtype == "违规" {
- //合同
- if isMeet, reason = contractRepeat_B(v, info, reason); isMeet {
- if contractRepeat_C(v, info) { //有不同
- return false, reason
- } else {
- reason = reason + "---合同类"
- return true, reason
- }
- } else {
- return false, reason
- }
- } else {
- //招标结果
- if isMeet, reason = tenderRepeat_B(v, info, reason); isMeet {
- if tenderRepeat_C(v, info) { //有不同
- return false, reason
- } else {
- reason = reason + "---类别空-招标类"
- return true, reason
- }
- } else {
- return false, reason
- }
- }
- }
- //不同
- if v.agency != info.agency && v.agency != "" && info.agency != "" {
- return false, reason
- }
- //机构最少一个为空
- if v.agency == "" || info.agency == "" {
- var repeat = false
- if repeat, reason = quickHeavyMethodOne(v, info, reason); repeat {
- reason = reason + "---机构最少一个空"
- return true, reason
- } else {
- return false, reason
- }
- }
- return false, reason
- }
- //招标_A
- func tenderRepeat_A(v *Info, info *Info, reason string) (bool, string) {
- var ss string
- p1, p2, p3, p4, p9, p10, p11 := false, false, false, false, false, false, false
- if v.projectname != "" && v.projectname == info.projectname {
- ss = ss + "p1(名称)-"
- p1 = true
- }
- if v.buyer != "" && v.buyer == info.buyer {
- ss = ss + "p2(单位)-"
- p2 = true
- }
- if (v.projectcode != "" && v.projectcode == info.projectcode && len(v.projectcode) >= 5) ||
- (v.contractnumber != "" && v.contractnumber == info.contractnumber && len(v.contractnumber) >= 5) {
- ss = ss + "p3(编号组)-"
- p3 = true
- }
- if v.budget != 0 && v.budget == info.budget {
- ss = ss + "p4(预算)-"
- p4 = true
- }
- if v.bidopentime != 0 && v.bidopentime == info.bidopentime {
- ss = ss + "p9(开标时间)-"
- p9 = true
- }
- if v.agencyaddr != "" && v.agencyaddr == info.agencyaddr {
- ss = ss + "p10(开标地点)-"
- p10 = true
- }
- if len([]rune(v.title)) > 10 && len([]rune(info.title)) > 10 &&
- (strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title)) {
- ss = ss + "p11(标题)-"
- p11 = true
- }
- if (p1 && p2 && p3) || (p1 && p2 && p4) || (p1 && p2 && p9) ||
- (p1 && p2 && p10) || (p1 && p2 && p11) || (p1 && p3 && p9) || (p1 && p3 && p10) ||
- (p1 && p4 && p9) || (p1 && p4 && p10) || (p2 && p3 && p4) ||
- (p2 && p3 && p9) || (p2 && p3 && p10) || (p2 && p3 && p11) ||
- (p2 && p4 && p9) || (p2 && p4 && p10) || (p2 && p4 && p11) ||
- (p3 && p4 && p9) || (p3 && p4 && p10) || (p3 && p4 && p11) ||
- (p4 && p9 && p10) || (p4 && p9 && p11) || (p9 && p10 && p11) {
- reason = reason + "满足招标A,3要素组合-" + ss + ","
- return true, reason
- }
- return false, reason
- }
- //招标_B
- func tenderRepeat_B(v *Info, info *Info, reason string) (bool, string) {
- m, n := 0, 0
- if v.projectname != "" && v.projectname == info.projectname {
- m++
- n++
- }
- if v.buyer != "" && v.buyer == info.buyer {
- m++
- }
- if (v.projectcode != "" && v.projectcode == info.projectcode && len(v.projectcode) >= 5) ||
- (v.contractnumber != "" && v.contractnumber == info.contractnumber && len(v.contractnumber) >= 5) {
- m++
- }
- if v.budget != 0 && v.budget == info.budget {
- m++
- }
- if v.bidopentime != 0 && v.bidopentime == info.bidopentime {
- m++
- }
- if v.agencyaddr != "" && v.agencyaddr == info.agencyaddr {
- m++
- }
- if len([]rune(v.title)) > 10 && len([]rune(info.title)) > 10 &&
- (strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title)) {
- m++
- n++
- }
- if m >= 2 {
- if n == 2 && m == 2 {
- return false, reason
- } else {
- reason = reason + "满足招标B,七选二,"
- return true, reason
- }
- }
- return false, reason
- }
- //招标_C
- func tenderRepeat_C(v *Info, info *Info) bool {
- if v.budget != 0 && info.budget != 0 && v.budget != info.budget {
- return true
- }
- //原始地址...
- if v.buyer != "" && info.buyer != "" && v.buyer != info.buyer {
- return true
- }
- if v.bidopentime != 0 && info.bidopentime != 0 && v.bidopentime != info.bidopentime {
- return true
- }
- if v.agencyaddr != "" && info.agencyaddr != "" && v.agencyaddr != info.agencyaddr {
- return true
- }
- return false
- }
- //中标_A
- func winningRepeat_A(v *Info, info *Info, reason string) (bool, string) {
- var ss string
- p1, p2, p3, p5, p6, p11 := false, false, false, false, false, false
- if v.projectname != "" && v.projectname == info.projectname {
- ss = ss + "p1(项目名称)-"
- p1 = true
- }
- if v.buyer != "" && v.buyer == info.buyer {
- ss = ss + "p2(单位)-"
- p2 = true
- }
- if (v.projectcode != "" && v.projectcode == info.projectcode && len(v.projectcode) >= 5) ||
- (v.contractnumber != "" && v.contractnumber == info.contractnumber && len(v.contractnumber) >= 5) {
- ss = ss + "p3(编号组)-"
- p3 = true
- }
- if v.bidamount != 0 && v.bidamount == info.bidamount {
- ss = ss + "p5(中标金)-"
- p5 = true
- }
- if v.winner != "" && v.winner == info.winner {
- ss = ss + "p6(中标人)-"
- p6 = true
- }
- if len([]rune(v.title)) > 10 && len([]rune(info.title)) > 10 &&
- (strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title)) {
- ss = ss + "p11(标题)-"
- p11 = true
- }
- if (p1 && p2 && p3) || (p1 && p2 && p5) || (p1 && p2 && p6) ||
- (p1 && p3 && p5) || (p1 && p3 && p6) || (p1 && p5 && p6) ||
- (p2 && p3 && p5) || (p2 && p3 && p6) || (p2 && p3 && p11) ||
- (p2 && p5 && p6) || (p2 && p5 && p11) || (p2 && p6 && p11) ||
- (p3 && p5 && p6) || (p3 && p5 && p11) || (p3 && p6 && p11) ||
- (p5 && p6 && p11) {
- reason = reason + "满足中标A,3要素组合-" + ss + ","
- return true, reason
- }
- return false, reason
- }
- //中标_B
- func winningRepeat_B(v *Info, info *Info, reason string) (bool, string) {
- m, n := 0, 0
- if v.projectname != "" && v.projectname == info.projectname {
- m++
- n++
- }
- if v.buyer != "" && v.buyer == info.buyer {
- m++
- }
- if (v.projectcode != "" && v.projectcode == info.projectcode && len(v.projectcode) >= 5) ||
- (v.contractnumber != "" && v.contractnumber == info.contractnumber && len(v.contractnumber) >= 5) {
- m++
- }
- if v.bidamount != 0 && v.bidamount == info.bidamount {
- m++
- }
- if v.winner != "" && v.winner == info.winner {
- m++
- }
- if len([]rune(v.title)) > 10 && len([]rune(info.title)) > 10 &&
- (strings.Contains(v.title, info.title) || strings.Contains(info.title, v.title)) {
- m++
- n++
- }
- if m >= 2 {
- if n == 2 && m == 2 {
- return false, reason
- } else {
- reason = reason + "满足中标B.六选二,"
- return true, reason
- }
- }
- return false, reason
- }
- //中标_C
- func winningRepeat_C(v *Info, info *Info) bool {
- if v.bidamount != 0 && info.bidamount != 0 && v.bidamount != info.bidamount {
- return true
- }
- if v.winner != "" && info.winner != "" && v.winner != info.winner {
- return true
- }
- //原始地址...
- if v.buyer != "" && info.buyer != "" && v.buyer != info.buyer {
- return true
- }
- return false
- }
- //合同_A
- func contractRepeat_A(v *Info, info *Info, reason string) (bool, string) {
- isMeet_1 := false
- if isMeet_1, reason = tenderRepeat_A(v, info, reason); isMeet_1 {
- return true, reason
- }
- isMeet_2 := false
- if isMeet_2, reason = winningRepeat_A(v, info, reason); isMeet_2 {
- return true, reason
- }
- return false, reason
- }
- //合同_B
- func contractRepeat_B(v *Info, info *Info, reason string) (bool, string) {
- isMeet_1 := false
- if isMeet_1, reason = tenderRepeat_B(v, info, reason); isMeet_1 {
- return true, reason
- }
- isMeet_2 := false
- if isMeet_2, reason = winningRepeat_B(v, info, reason); isMeet_2 {
- return true, reason
- }
- return false, reason
- }
- //合同_C
- func contractRepeat_C(v *Info, info *Info) bool {
- if tenderRepeat_C(v, info) {
- return true
- }
- if winningRepeat_C(v, info) {
- return true
- }
- return false
- }
- func againRepeat(v *Info, info *Info) bool {
- //相同采购单位下
- if info.buyer != "" && v.buyer == info.buyer {
- if info.subtype == "招标" || info.subtype == "邀标" || info.subtype == "询价" ||
- info.subtype == "竞谈" || info.subtype == "单一" || info.subtype == "竞价" ||
- info.subtype == "其他" || info.subtype == "变更" {
- //预算金额满足条件
- if v.budget != info.budget && v.budget != 0 && info.budget != 0 {
- return true
- }
- } else if info.subtype == "中标" || info.subtype == "成交" || info.subtype == "废标" ||
- info.subtype == "流标" || info.subtype == "合同" || info.subtype == "验收" ||
- info.subtype == "违规" {
- //中标金额单位满足条件
- if (v.bidamount != info.bidamount && v.bidamount != 0 && info.bidamount != 0) ||
- (v.winner != info.winner && v.winner != "" && info.winner != "") {
- return true
- }
- } else {
- }
- }
- return false
- }
|