1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174 |
- package pretreated
- import (
- "fmt"
- "jy/clear"
- u "jy/util"
- qutil "qfw/util"
- "strings"
- "unicode/utf8"
- )
- // 对table进行整体解析处理
- func (tn *Table) AnalyTables(contactFormat *u.ContactFormat, isSite bool, codeSite string) []*Table {
- ts := tn.tableSubDemolitionTable() //分包,拆表
- for n, table := range ts {
- //处理每个table
- if len(table.TRs) > 0 {
- //删除尾部空白行
- table.deleteTrimTr()
- //table.Print()
- //校对表格
- table.Adjust(isSite, codeSite)
- //查找表格的标签,table.Tag字段
- table.FindTag()
- //分割表格
- table.bSplit(n, ts, isSite, codeSite)
- table.TdContactFormat(contactFormat, isSite, codeSite) //contactFormat,处理采购单位,代理机构
- //开始查找kv,核心模块,table.SortKV
- table.FindKV(isSite, codeSite)
- //table中抽取品牌,table.BrandData
- if u.IsBrandGoods {
- table.analyBrand()
- }
- //table中抽取单价和个数
- if u.IsPriceNumber {
- //qutil.Debug("======================抽取price和number===========")
- table.extractPriceNumber()
- }
- res, _, _, _, _ := CheckCommon(table.Tag, "abandontable")
- if !res { //调试
- //过滤、标准化、合并kv,table.StandKV,table.StandKVWeight
- table.KVFilter(isSite, codeSite)
- }
- //对有表头表格的处理
- if table.Tag != "" && utf8.RuneCountInString(table.Tag) < 100 {
- co, m, b := CheckMultiPackage(table.Tag) //分包处理
- if b {
- table.BPackage = b
- if len(table.BlockPackage.Map) == 0 {
- for _, av := range m {
- kv := u.NewJobKv()
- kv.KvTags = table.StandKV
- bd := u.PackageNumberConvert(av[0])
- //切割文本分包
- blockPackage := &u.BlockPackage{
- Origin: av[0],
- Name: av[0],
- Text: co,
- TableKV: kv,
- Index: bd,
- }
- if bd != "" {
- table.BlockPackage.AddKey(bd, blockPackage)
- } else {
- table.BlockPackage.AddKey(av[0], blockPackage)
- }
- }
- }
- table.StandKV["项目名称"] = append(table.StandKV["项目名称"], &u.Tag{Key: "项目名称", Value: table.Tag, Weight: -300})
- }
- }
- //判断是否是多包,并处理分包的//遍历td分块
- table.CheckMultiPackageByTable(isSite, codeSite) //分包处理
- //MergeKvTags(table.TableResult.KvTags, table.StandKV)
- }
- }
- return ts
- }
- // 查找每一个单元格的表头,调用FindNear
- func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
- if td.Val == "" || strings.TrimSpace(td.Val) == "" {
- return
- }
- near := table.FindNear(td, direct)
- if near != nil && near.BH && (near.KeyDirect == vdirect || near.KeyDirect == 0) && (near.KVDirect == direct || near.KVDirect == 0) && near.KVDirect < 3 {
- near.KVDirect = direct
- near.KeyDirect = vdirect
- td.KVDirect = direct
- key := repSpace.ReplaceAllString(near.Val, "")
- //临时去掉换行-进行判断
- tmp_tdVal := strings.ReplaceAll(td.Val, "\n", "")
- if key == "名称" && near.StartCol == 0 && near.Rowspan > 0 {
- new_key := ""
- tr := table.TRs[:td.TR.RowPos]
- if len(tr) > len(tr)-1 && len(tr) > 0 {
- tds := tr[len(tr)-1].TDs
- if len(tds) > td.EndCol && tds != nil {
- td1 := tds[td.EndCol]
- if zbhxrSecondReg.MatchString(td1.Val) {
- new_key = td1.Val
- }
- }
- }
- if new_key == "" {
- for _, vn := range table.TRs[near.Rowspan-1].TDs {
- if strings.Contains(vn.Val, "代理") {
- key = "代理机构"
- break
- } else if strings.Contains(vn.Val, "招标") {
- key = "采购单位"
- break
- } else if strings.Contains(vn.Val, "中标") && utf8.RuneCountInString(tmp_tdVal) >= 4 {
- key = "中标单位"
- break
- }
- }
- } else {
- key = new_key
- }
- } else if zbhxrReg.MatchString(key) && findCandidate2.MatchString(tmp_tdVal) {
- new_key := "中标单位"
- tr_top := table.TRs[:td.TR.RowPos]
- if len(tr_top) > len(tr_top)-1 && len(tr_top) > 0 { //上临查询
- tds := tr_top[len(tr_top)-1].TDs
- if len(tds) > td.ColPos && tds != nil && len(tds) == len(td.TR.TDs) {
- td1 := tds[td.ColPos]
- if zbhxrSortNameReg.MatchString(td1.Val) {
- new_key = td1.Val
- } else {
- if zbhxrSortReg_1.MatchString(td1.Val) {
- new_key = "中标候选人" + td1.Val
- }
- }
- }
- }
- if new_key == "中标单位" { //最左临查询
- tr_left := table.TRs[:td.TR.RowPos+1]
- tds_left := tr_left[len(tr_left)-1].TDs
- if td.ColPos > 0 {
- td1 := tds_left[0]
- if zbhxrSortReg_2.MatchString(td1.Val) { //针对排名情况
- new_key = "中标候选人第" + td1.Val + "名"
- } else {
- if zbhxrSortReg_1.MatchString(td1.Val) {
- new_key = "中标候选人" + td1.Val
- }
- }
- }
- }
- if new_key != "中标单位" {
- td.Val = tmp_tdVal
- }
- key = new_key
- } else if zbhxrReg.MatchString(key) && findCandidate3.MatchString(tmp_tdVal) {
- key = "中标单位名称"
- } else if key == "投标人名称" || key == "单位名称" { //左临上临-拼接
- tmpnewnear := table.FindNear(near, 1)
- if tmpnewnear == nil {
- tmpnewnear = table.FindNear(near, 2)
- }
- if tmpnewnear != nil {
- if (table.Tag == "成交候选人" || table.Tag == "中标候选人") &&
- zbhxrSortReg_1.MatchString(tmpnewnear.Val) {
- key = "中选候选人" + tmpnewnear.Val
- } else if table.Tag == "中标情况" {
- if tmpnewnear.MustBH || tmpnewnear.BH {
- if tmpnewnear.Val == "标段名称" && findCandidate2.MatchString(td.Val) {
- key = "中标单位名称"
- }
- }
- } else {
- if tmpnewnear.MustBH || tmpnewnear.BH {
- if tmpnewnear.Val == "中标候选人情况" && zbhxrSortReg_3.MatchString(td.Val) {
- key = "中标候选人第" + zbhxrSortReg_3.FindString(td.Val) + "名"
- } else if tmpnewnear.Val == "名次" || tmpnewnear.Val == "排名" || tmpnewnear.Val == "序号" || tmpnewnear.Val == "中标候选人排名" {
- if vv, ok := table.SortKV.Map[tmpnewnear.Val].(string); ok {
- if vv == "1" && findCandidate2.MatchString(td.Val) && key == "单位名称" {
- key = "中标单位名称"
- }
- }
- } else {
- key = tmpnewnear.Val + near.Val
- }
- }
- }
- } else {
- if table.Tag == "成交单位" && key == "单位名称" {
- key = "中标单位名称"
- } else if key == "单位名称" {
- tmpdirect := 2
- if direct == 2 {
- tmpdirect = 1
- }
- tmpnewnear = table.FindNear(td, tmpdirect)
- if tmpnewnear != nil {
- if tmpnewnear.Val == "中标人" {
- key = "中标单位名称"
- }
- }
- }
- }
- } else if key == "采购人(乙方)" || key == "采购人(乙方)" {
- if findCandidate2.MatchString(td.Val) {
- key = "中标单位"
- }
- } else if key == "企业名称" {
- if findCandidate2.MatchString(td.Val) && strings.Contains(qutil.ObjToString(table.Tag), "履约信息") {
- key = "中标单位"
- }
- } else if key == "发布部门" || key == "主体名称" {
- if findCandidate2.MatchString(td.Val) && strings.Contains(qutil.ObjToString(table.Tag), "履约信息") {
- key = "采购单位"
- }
- } else if key == "金额" {
- //父级表格
- pre_near := table.FindNear(near, direct)
- if pre_near != nil {
- if pre_near.Val == "第一中标候选人" {
- key = pre_near.Val + key
- }
- }
- } else if key == "第一候选人" && qutil.Float64All(tmp_tdVal) > 0.0 {
- if tmp_near := table.FindNear(td, 2); tmp_near != nil {
- if winMoneyReg.MatchString(tmp_near.Val) {
- key = tmp_near.Val
- }
- }
- } else if key == "联系人" || key == "联系电话" {
- if table.Toptype_Old == "采购意向" {
- key = "采购" + key
- }
- }
- if near.Val == "" {
- key = fmtkey("k", near.TR.RowPos, near.ColPos)
- }
- val := table.SortKV.Map[key]
- //qutil.Debug("====================", "key:", key, "val:", val)
- bthiskey := false
- if val != nil {
- curpos := table.SortKV.Index[key]
- thistr := table.kTD[curpos]
- if thistr != near {
- if strings.TrimSpace(near.Val) == "名称" && near.TR != nil && len(near.TR.TDs) > 0 && near.ColPos-1 >= 0 {
- rv := near.TR.TDs[near.ColPos-1].Val
- if near.ColPos > 0 && (strings.Contains(rv, "招标") || strings.Contains(rv, "代理") || strings.Contains(rv, "采购") || strings.Contains(rv, "中标")) {
- near = near.TR.TDs[near.ColPos-1]
- }
- } else {
- bthiskey = true
- }
- } else {
- bthiskey = true
- }
- }
- bfind := false
- barr := false
- varrpos := -1
- if bthiskey {
- //处理是数组值,且有合并行或合并列的情况 kvscope,对数组值的处理
- pos := table.SortKV.Index[key]
- mval := table.kvscope[pos]
- bvalfind := false
- if direct == 1 { //kv是横向
- L1:
- for k3, v3 := range mval {
- for _, v4 := range v3 {
- if v4.EndRow+1 == td.StartRow && v4.EndCol == td.EndCol {
- varrpos = k3
- bvalfind = true
- break L1
- }
- }
- }
- } else { //kv是纵向
- L2:
- for k3, v3 := range mval {
- for _, v4 := range v3 {
- if v4.EndCol+1 == td.StartCol && v4.EndRow == td.EndRow {
- varrpos = k3
- bvalfind = true
- break L2
- }
- }
- }
- }
- if vals, ok := val.([]string); ok {
- if near.Val == "" {
- bn := false
- for _, vs := range vals {
- if vs != "" && NullTdReg.MatchString(vs) {
- bn = true
- } else {
- bn = false
- break
- }
- }
- if bn {
- near.Val = NullTxtBid
- key = NullTxtBid
- bfind = true
- }
- }
- if bvalfind && varrpos > -1 && len(vals) > varrpos {
- tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
- if tmapval == "" {
- vals = append(vals, td.Val) // 累加
- } else {
- vals = append(vals, tmapval) // 累加
- }
- val = vals
- //vals[varrpos] = td.Val // += "__" + td.Val
- } else {
- //添加时候去除空值和nil
- newVals := []string{}
- for _, isval := range vals {
- if isval == "" {
- continue
- }
- newVals = append(newVals, isval)
- }
- //vals = append(vals, td.Val)
- if td.Val != "" {
- newVals = append(newVals, td.Val)
- }
- val = newVals
- varrpos = len(vals) - 1
- }
- } else if vals, ok := val.(string); ok && vals != "" && td.Val != "" {
- tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(vals, "")) //已存在的kv
- tmapvaltd := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
- if bvalfind {
- if key == "中标单位" { //不能覆盖---
- } else {
- if tmapvaltd == "" {
- val = td.Val //vals + "__" + td.Val
- } else {
- val = tmapvaltd
- }
- }
- } else {
- if key == "中标单位" { //新增不能数组
- } else {
- if zbhxrSortNameReg.MatchString(key) {
- //特殊~不构建数组
- } else {
- tval := []string{}
- if tmapval == "" {
- tval = append(tval, vals)
- } else {
- tval = append(tval, tmapval)
- }
- if tmapvaltd == "" {
- tval = append(tval, td.Val)
- } else {
- tval = append(tval, tmapvaltd)
- }
- val = tval
- varrpos = 1
- }
- }
- }
- }
- barr = true
- } else {
- if td.Val != "" {
- tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
- if tmapval == "" {
- val = td.Val
- } else {
- val = tmapval
- }
- } else if len(near.SortKV.Map) == 1 && near.SortKV.Map[near.Val] != "" {
- val = near.SortKV.Map[near.Val]
- }
- }
- td.HeadTd = near
- if bfind {
- tkey := fmtkey("k", near.TR.RowPos, near.ColPos)
- table.SortKV.ReplaceKey(key, val, tkey)
- } else {
- if key == "单位名称" && len(near.TR.TDs) > 1 {
- if near.TR.TDs[0].Val != "序号" {
- key = near.TR.TDs[0].Val
- }
- }
- table.SortKV.AddKey(key, val)
- pos := table.SortKV.Index[key]
- if barr {
- mval := table.kvscope[pos]
- if mval != nil {
- tds := mval[varrpos]
- if tds != nil {
- tds = append(tds, td)
- } else {
- tds = []*TD{td}
- }
- if varrpos > -1 {
- mval[varrpos] = tds
- table.kvscope[pos] = mval
- }
- }
- } else {
- table.kvscope[pos] = map[int][]*TD{
- 0: []*TD{td},
- }
- table.kTD[pos] = near
- }
- }
- b = true
- }
- return
- }
- // 查找单元格的表头时,横向或纵向
- func (table *Table) FindNear(td *TD, direct int) *TD {
- if direct == 1 && td.StartCol > 0 { //左临
- tr := table.TRs[:td.TR.RowPos+1]
- for i := len(tr) - 1; i > -1; i-- {
- tds := tr[i].TDs
- for _, td1 := range tds {
- if td1.StartRow <= td.StartRow && td1.EndRow >= td.EndRow && td1.EndCol+1 == td.StartCol {
- //找到左临节点
- if td1.BH || (zbhxrSortReg_1.MatchString(td1.Val) && (table.Tag == "成交候选人" || table.Tag == "中标候选人")) {
- return td1
- } else {
- if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct {
- return td1.HeadTd
- }
- }
- }
- }
- }
- } else if direct == 2 && td.StartRow > 0 { //上临
- tr := table.TRs[:td.TR.RowPos]
- for i := len(tr) - 1; i > -1; i-- {
- tds := tr[i].TDs
- for it, td1 := range tds {
- if td1.StartCol <= td.StartCol && td1.EndCol >= td.EndCol && td1.EndRow+1 == td.StartRow {
- if td1.BH {
- //new_td := tds[td.ColPos] //列错落
- //if td.ColPos!=it && new_td.BH {
- // return new_td
- //}
- return td1
- } else if len(tr[i].TDs) == len(td.TR.TDs) && td1.HeadTd != nil && td1.HeadTd.KVDirect == direct {
- return td1.HeadTd
- } else if it > 0 && td1.Val == "" && td1.TR.TopTR == nil && len(td.TR.TDs)-(td.StartCol-1) > 0 && strings.Contains(td.TR.TDs[td.StartCol-1].Val, "中标候选人") {
- return tds[it-1]
- } else if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct && td.Colspan == td1.Colspan && td.Rowspan == td.Rowspan {
- return td1.HeadTd
- } else {
- }
- } else if len(td.TR.TDs) == len(tds) && i == len(tr)-1 && len(tds) > td.ColPos &&
- it == td.ColPos && td1.EndRow+1 == td.StartRow {
- new_td := tds[td.ColPos]
- if new_td.BH {
- return new_td
- }
- }
- }
- }
- }
- return nil
- }
- // 根据行号列号获取td对象
- func (tn *Table) GetTdByRCNo(row, col int) *TD {
- for _, tr := range tn.TRs {
- for _, td := range tr.TDs {
- if td.StartCol <= col && td.EndCol >= col && td.StartRow <= row && td.EndRow >= row {
- return td
- }
- }
- }
- return nil
- }
- // 判断表格是否是分包
- func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool, index []string) {
- pac := 0 //包的数量
- val := 0 //分值
- index = []string{} //存储分包,使用tbale.SortKV的key和value使用正则等处理对值进行判断
- index_pos := []int{} //下标
- //是数组且能找到标段之类的提示
- //arr_count := 0 //计数table.SortKV的value是数组的数量,后面没用
- key_index := -1
- hasPkgTd := map[string]bool{}
- //初始化CheckMultiPackageByTable方法需要的数据
- key_index, index, index_pos, val, pac, hasPkgTd = initCheckMultiPackageByTable(tn, key_index, index, index_pos, val, pac, hasPkgTd)
- //key是分包的情况
- //记录key对应的值
- commonKeyVals := map[string][]string{}
- //记录key出现的次数
- keyExistsCount := map[string]int{}
- if pac > 1 {
- val = 10
- } else {
- //查找标签
- if TableMultiPackageReg_4.MatchString(tn.Tag) {
- val += 4
- } else if TableMultiPackageReg_2.MatchString(tn.Tag) {
- val += 4
- }
- //根据table.SortKV的key判断是否分包,如果没有再根据value判断
- val, index, index_pos = foundPacBySortKV(tn, val, index, index_pos, &keyExistsCount, &commonKeyVals, key_index, hasPkgTd)
- }
- // u.Debug(index)
- //过滤重复及标准化!
- standIndex := []string{}
- standIndex_pos := []int{}
- oldIndex := []string{} //存放包的原始值
- brepeat := map[string]bool{}
- for k, v := range index {
- v = u.PackageNumberConvert(v)
- if !brepeat[v] {
- brepeat[v] = true
- standIndex = append(standIndex, v)
- standIndex_pos = append(standIndex_pos, index_pos[k])
- oldIndex = append(oldIndex, index[k])
- }
- }
- index = standIndex
- //有一个以上的包,并且相同的key出现一次以上,认为这个key是属于包里面的
- if len(commonKeyVals) > 0 {
- for k, v := range commonKeyVals {
- if len(index) > 1 && keyExistsCount[k] < 2 {
- continue
- }
- tn.SortKV.AddKey(k, v)
- }
- }
- //
- isGoonNext := false
- if val > 4 && len(brepeat) > 0 {
- b = true
- //多包解析
- if b {
- tn.BPackage = true
- //pnum := len(index)
- //根据数组index分包长度添加table.BlockPackage子包数组
- for nk, v := range index {
- if tn.BlockPackage.Map[v] == nil {
- kv := u.NewJobKv()
- for tnk, tnv := range tn.StandKV {
- if nk >= len(tnv) {
- continue
- } else if len(index) == len(tnv) {
- if tnk == "预算" && isUnRealBudgetBp(tnv) {
- continue
- }
- if tnk == "预算" && codeSite == "ha_zmdszfcgw_cgxx" && len(tnv) > 1 {
- isEqErr, budget_v := false, ""
- for bk, bv := range tnv {
- if bk == 0 {
- budget_v = bv.Value
- } else {
- if budget_v != bv.Value {
- isEqErr = true
- break
- }
- }
- }
- if isEqErr {
- kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
- }
- } else {
- kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
- }
- }
- }
- //kv.KvTags = tn.StandKV
- bp := &u.BlockPackage{}
- bp.Index = v //序号 (转换后编号,只有数字或字母)
- bp.Origin = oldIndex[nk] //包的原始值
- bp.TableKV = kv //table kv (分出的对应的KV值)
- bp.Name = v
- if bp.TableKV != nil && bp.TableKV.KvTags != nil && len(bp.TableKV.KvTags) > 0 {
- for kc, cv := range bp.TableKV.KvTags {
- if kc == "预算" && bp.Budget <= 0 {
- moneys := clear.ObjToMoney([]interface{}{cv[0].Value, ""})
- if len(moneys) > 0 {
- if vf, ok := moneys[0].(float64); ok {
- bp.Budget = vf
- bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
- } else if vi, ok := moneys[0].(int); ok {
- bp.Budget = float64(vi)
- bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
- }
- }
- } else if kc == "中标金额" && bp.Bidamount <= 0 {
- moneys := clear.ObjToMoney([]interface{}{cv[0].Value, ""})
- if len(moneys) > 0 {
- if vf, ok := moneys[0].(float64); ok {
- bp.Bidamount = vf
- bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
- } else if vi, ok := moneys[0].(int); ok {
- bp.Bidamount = float64(vi)
- bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
- }
- }
- } else if kc == "中标单位" && bp.Winner == "" {
- bp.Winner = cv[0].Value
- }
- //拼接内容
- if !excludeKey.MatchString(kc) {
- bp.Text += fmt.Sprintf("%v:%v\n", kc, cv[0].Value)
- }
- }
- } else { //新增 - 特殊情况 - 查找sortKV - 预算 - 中标金额 - 中标单位
- for k, v := range tn.SortKV.Map {
- //kt := u.GetTags(k, isSite, codeSite)
- if budgetSortKVReg.MatchString(k) {
- if vs, ok := v.([]string); ok {
- if len(index) == len(vs) {
- moneys := clear.ObjToMoney([]interface{}{vs[nk], ""})
- if len(moneys) > 0 {
- if vf, ok := moneys[0].(float64); ok {
- if !strings.Contains(vs[nk], "万") &&
- strings.Contains(k, "万") {
- vf = 10000.0 * vf
- }
- bp.Budget = vf
- bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
- } else if vi, ok := moneys[0].(int); ok {
- if !strings.Contains(vs[nk], "万") &&
- strings.Contains(k, "万") {
- vi = 10000 * vi
- }
- bp.Budget = float64(vi)
- bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
- }
- }
- }
- }
- }
- if bidamountSortKVReg.MatchString(k) {
- if vs, ok := v.([]string); ok {
- if len(index) == len(vs) {
- moneys := clear.ObjToMoney([]interface{}{vs[nk], ""})
- if len(moneys) > 0 {
- if vf, ok := moneys[0].(float64); ok {
- if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") {
- vf = 10000.0 * vf
- }
- bp.Bidamount = vf
- bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
- } else if vi, ok := moneys[0].(int); ok {
- if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") {
- vi = 10000.0 * vi
- }
- bp.Bidamount = float64(vi)
- bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
- }
- }
- }
- }
- }
- if winnerSortKVReg.MatchString(k) {
- if vs, ok := v.([]string); ok {
- if len(index) == len(vs) {
- bp.Winner = vs[nk]
- }
- }
- }
- }
- }
- tn.BlockPackage.AddKey(v, bp) //table子包数组
- }
- }
- isGoonNext = tn.manyPackageProcessByIndex(index, standIndex_pos, isSite, codeSite) //多包处理,处理不同情况下的分包
- }
- } else {
- isGoonNext = true
- }
- if isGoonNext { //没有处理成数组的情况下,继续调用正文查找分包的方法
- tn.isGoonNext(isSite, codeSite)
- }
- //查找分包中的中标人排序-分包找候选人
- if tn.BlockPackage != nil && tn.BlockPackage.Keys != nil && len(tn.BlockPackage.Keys) > 0 {
- for _, v := range tn.BlockPackage.Keys {
- vv, ok := tn.BlockPackage.Map[v].(*u.BlockPackage)
- if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) {
- vv.WinnerOrder = winnerOrderEntity.Find(vv.Text, true, 2, isSite, codeSite)
- }
- //if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) && (tn.WinnerOrder == nil || len(tn.WinnerOrder) == 0) {
- // vv.WinnerOrder = tn.WinnerOrder
- //}
- }
- }
- return
- }
- // 多包处理,处理不同情况下的分包
- func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int, isSite bool, codeSite string) (isGoonNext bool) {
- if len(index) == 1 { //是一个的情况
- if len(tn.SortKV.Keys) < 10 && tn.ColNum < 10 && tn.RowNum < 4 { //table带排序的KV值小于10并且小于10列和小于4行
- beq := true
- for _, v2 := range tn.SortKV.Keys {
- if _, ok := tn.SortKV.Map[v2].(string); !ok {
- beq = false
- break
- }
- }
- if beq { //统一处理为数组
- td := tn.GetTdByRCNo(tn.RowNum-1, 0)
- if !td.BH && FindVal2_1.MatchString(td.Val) {
- for _, v2 := range tn.SortKV.Keys {
- tn.SortKV.AddKey(v2, []string{tn.SortKV.Map[v2].(string)})
- }
- } else {
- //没有处理成数组的情况下,继续调用正文查找分包的方法
- isGoonNext = true
- }
- }
- }
- }
- for _, k1 := range tn.SortKV.Keys {
- v1 := tn.SortKV.Map[k1]
- var v1_arr []string
- if vtmpv1, ok := v1.(string); ok {
- v1_arr = PreCon4.FindAllString(qutil.ObjToString(vtmpv1), -1)
- if len(v1_arr) > 0 {
- if dw := Precon4dw.FindString(vtmpv1); dw != "" {
- for i, v := range v1_arr {
- v1_arr[i] = v + dw
- }
- }
- }
- } else if vtmpv1s, ok := v1.([]string); ok {
- v1_arr = vtmpv1s
- }
- if len(v1_arr) > 0 && len(v1_arr) <= len(index) { //table.SortKV.Map.value数组小于等于分包index
- for k, v := range v1_arr {
- tn.assemblePackage(k1, v, index[k], isSite, codeSite) //组装解析到的分包
- }
- }
- }
- return isGoonNext
- }
- // 没有处理成数组的情况下,继续调用正文查找分包的方法
- func (tn *Table) isGoonNext(isSite bool, codeSite string) {
- blockPackage := map[string]*u.BlockPackage{}
- for _, k := range tn.SortKV.Keys {
- if excludeKey.MatchString(k) || strings.Contains(k, "批复") || excludeKey3.MatchString(k) {
- continue
- }
- str := "" //拼装为冒号kv
- v := tn.SortKV.Map[k]
- nk := regReplAllSpace.ReplaceAllString(k, "")
- if vs, ok := v.([]string); ok {
- str += fmt.Sprintf("%s:%s\n", nk, strings.Join(vs, " "))
- } else {
- str += fmt.Sprintf("%s:%s\n", nk, v)
- }
- if excludeKey2.MatchString(str) {
- continue
- }
- b, _ := divisionPackageChild(&blockPackage, str, tn.Tag, false, false, isSite, codeSite) //分块之后分包
- if b && len(blockPackage) > 0 {
- tn.BPackage = true
- for mk, mv := range blockPackage {
- if tn.BlockPackage.Map[mk] == nil {
- tn.BlockPackage.AddKey(mk, mv)
- } else {
- bp := tn.BlockPackage.Map[mk].(*u.BlockPackage)
- if bp.TableKV == nil {
- bp.TableKV = u.NewJobKv()
- }
- if bp.SpaceKV == nil {
- bp.SpaceKV = u.NewJobKv()
- }
- for k2, v2 := range mv.ColonKV.KvTags {
- for _, v2v := range v2 {
- isExists := false
- for _, v2vv := range bp.TableKV.KvTags[k2] {
- if v2v.Value == v2vv.Value {
- isExists = true
- break
- }
- }
- if !isExists {
- bp.TableKV.KvTags[k2] = append(bp.TableKV.KvTags[k2], v2v)
- bp.Text += fmt.Sprintf("%v:%v\n", k2, v2)
- }
- }
- }
- for k2, v2 := range mv.SpaceKV.KvTags {
- for _, v2v := range v2 {
- isExists := false
- for _, v2vv := range bp.SpaceKV.KvTags[k2] {
- if v2v.Value == v2vv.Value {
- isExists = true
- break
- }
- }
- if !isExists {
- bp.SpaceKV.KvTags[k2] = append(bp.SpaceKV.KvTags[k2], v2v)
- bp.Text += fmt.Sprintf("%v:%v\n", k2, v2)
- }
- }
- }
- }
- }
- tn.BPackage = true
- tn.SortKV.RemoveKey(k)
- }
- }
- }
- // 根据table.SortKV的key判断是否分包,如果没有再根据value判断
- func foundPacBySortKV(tn *Table, val int, index []string, index_pos []int, keyExistsCount *map[string]int, commonKeyVals *map[string][]string, key_index int, hasPkgTd map[string]bool) (rval int, rindex []string, rindex_pos []int) {
- keyIsPkg := false
- for in, k := range tn.SortKV.Keys {
- if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) || excludeKey3.MatchString(k) || regFJWarap.MatchString(k) || regAZWarap.MatchString(k) { //判断分包前排除
- continue
- }
- v := tn.SortKV.Map[k]
- //key是分包的情况
- if ismatch := FindVal_1.MatchString(k); keyIsPkg || ismatch {
- if ismatch {
- keyIsPkg = true
- val += 4
- pkgFlag := FindVal_1.FindString(k) //对值进行分包判断
- k = strings.Replace(k, pkgFlag, "", -1)
- index = append(index, pkgFlag)
- index_pos = append(index_pos, len(index))
- val += 1
- //pac++
- } else {
- k = strings.TrimRight(k, "_")
- }
- (*keyExistsCount)[k] = (*keyExistsCount)[k] + 1
- (*commonKeyVals)[k] = append((*commonKeyVals)[k], qutil.ObjToString(v))
- } else if k1 := FilterKey_2.ReplaceAllString(k, ""); FindKey_2.MatchString(k1) {
- val += 4
- //value数组分包
- if vs, bvs1 := v.([]string); bvs1 {
- L:
- for in2, v1 := range vs {
- if len([]rune(v1)) < 20 && !moneyNum.MatchString(v1) && FindVal2_1.MatchString(v1) {
- for _, serial := range tn.TableResult.RuleBlock.TitleRegs {
- if serial.MatchString(v1) {
- break L
- }
- }
- if key_index == -1 {
- key_index = in
- } else if key_index != in {
- break
- }
- index = append(index, v1)
- index_pos = append(index_pos, in2)
- val += 1
- //pac++
- }
- }
- } else if v1, ok := v.(string); ok && !hasPkgTd[k] {
- //value字符串分包
- v1 = replPkgConfusion(v1) //替换分包中混淆的词
- for _, v2 := range strings.Split(v1, "/") {
- if len([]rune(v2)) < 20 && !moneyNum.MatchString(v2) && FindVal2_1.MatchString(v2) {
- key_index = in
- index = append(index, v1)
- index_pos = append(index_pos, 0)
- val += 1
- //pac++
- underline := ""
- for {
- underline += "_"
- if tn.SortKV.Map[k+underline] == nil {
- break
- } else if v3, v2_ok := tn.SortKV.Map[k+underline].(string); v2_ok && v3 != "" {
- index = append(index, v3)
- index_pos = append(index_pos, 1)
- } else if v3, v2_ok := tn.SortKV.Map[k+underline].([]string); v2_ok {
- for v2_k, v2_v := range v3 {
- index = append(index, v2_v)
- index_pos = append(index_pos, v2_k+1)
- }
- }
- }
- break
- }
- }
- }
- if k1 == "标段" && len(index) == 0 {
- continue
- } else {
- break
- }
- }
- }
- return val, index, index_pos
- }
- // 初始化CheckMultiPackageByTable方法需要的数据
- func initCheckMultiPackageByTable(tn *Table, key_index int, index []string, index_pos []int, val int, pac int, hasPkgTd map[string]bool) (rkey_index int, rindex []string, rindex_pos []int, rval int, rpac int, rhasPkgTd map[string]bool) {
- for in, k := range tn.SortKV.Keys {
- //涉及包号|包件号?|项目标号|规格|型号|招标范围|业绩|废标)|(^编号$)|([^包段标]编号)就跳过
- if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) || excludeKey3.MatchString(k) || strings.Contains(k, "批复") {
- continue
- }
- v := tn.SortKV.Map[k]
- if vs, bvs := v.([]string); bvs {
- //arr_count++
- haspkgs := []string{}
- for in2, v1 := range vs {
- v1 = replPkgConfusion(v1) //替换分包中混淆的词
- if len([]rune(v1)) < 30 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) {
- if key_index == -1 {
- key_index = in
- } else if key_index != in {
- break
- }
- index = append(index, FindVal_1.FindString(v1))
- index_pos = append(index_pos, in2)
- val += 1
- pac++
- } else if FindKey_3.MatchString(k) {
- //5db2a101a5cb26b9b73054ac
- index = append(index, v1)
- index_pos = append(index_pos, in2)
- val += 1
- pac++
- } else {
- if ok, v1new := isHasOnePkgAndNoKv(v1); ok { //td的值里面有一个包,并且没有冒号kv
- haspkgs = append(haspkgs, v1new)
- }
- }
- }
- /*处理这种情况:
- <tr><td>包一:xxxxxxxxx</td></tr>
- <tr><td>包二:xxxxxxxxx</td></tr>
- */
- if len(index) == 0 && len(haspkgs) > 0 && len(haspkgs) == len(vs) {
- for in2, v1 := range haspkgs {
- if key_index == -1 {
- key_index = in
- } else if key_index != in {
- break
- }
- index = append(index, v1)
- index_pos = append(index_pos, in2)
- val += 1
- pac++
- }
- }
- } else if v1, ok := v.(string); ok {
- v1 = replPkgConfusion(v1) //替换分包中混淆的词
- if len([]rune(v1)) < 8 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) {
- key_index = in
- index = append(index, FindVal_1.FindString(v1))
- index_pos = append(index_pos, 0)
- val += 1
- pac++
- } else if getTd := tn.GetTdByRCNo(0, tn.SortKV.Index[k]); getTd != nil && getTd.KVDirect == 2 { //纵向
- /*处理这种情况:
- <tr><td>包一:xxxxxxxxx</td></tr>
- */
- if ok, v1new := isHasOnePkgAndNoKv(v1); ok {
- hasPkgTd[k] = true
- key_index = in
- index = append(index, v1new)
- index_pos = append(index_pos, 0)
- val += 1
- pac++
- }
- }
- }
- }
- return key_index, index, index_pos, val, pac, hasPkgTd
- }
- // 组装解析到的分包,//key如果匹配到抽取关键词就添加到table.SortKV
- func (tn *Table) assemblePackage(k1, v1, key string, isSite bool, codeSite string) {
- bp := tn.BlockPackage.Map[key].(*u.BlockPackage)
- if bp.TableKV == nil {
- bp.TableKV = u.NewJobKv()
- }
- if v1 != "" {
- kvTags, _ := CommonDataAnaly(k1, "中标情况", "", v1, isSite, codeSite) //匹配抽取关键词
- for k3, v3 := range kvTags {
- if bp.TableKV.KvTags[k3] == nil {
- bp.TableKV.KvTags[k3] = append(bp.TableKV.KvTags[k3], v3...)
- } else if k3 == "预算" && bp.Budget <= 0 {
- moneys := clear.ObjToMoney([]interface{}{v3[0].Value, ""})
- if len(moneys) > 0 {
- if vf, ok := moneys[0].(float64); ok {
- bp.Budget = vf
- bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
- } else if vi, ok := moneys[0].(int); ok {
- bp.Budget = float64(vi)
- bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
- }
- }
- } else if k3 == "中标金额" && bp.Bidamount <= 0 {
- moneys := clear.ObjToMoney([]interface{}{v3[0].Value, ""})
- if len(moneys) > 0 {
- if vf, ok := moneys[0].(float64); ok {
- bp.Bidamount = vf
- bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
- } else if vi, ok := moneys[0].(int); ok {
- bp.Bidamount = float64(vi)
- bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
- }
- }
- } else if k3 == "中标单位" && bp.Winner == "" {
- new_str := qutil.ObjToString(winnerOrderEntity.clear("中标单位", v3[0].Value))
- if new_str != "" && WinnerOrderStr.MatchString(new_str) {
- bp.Winner = new_str
- }
- }
- }
- }
- k1 = regReplAllSpace.ReplaceAllString(k1, "")
- //拼接内容
- if !excludeKey.MatchString(k1) {
- bp.Text += fmt.Sprintf("%v:%v\n", k1, v1)
- }
- tn.BlockPackage.AddKey(key, bp)
- }
- // 初始化组装纵向数据
- func initLongitudinalData(table *Table) [][]string {
- res := make([][]string, len(table.TRs[0].TDs)) //创建table第一行的列数长度
- for n, _ := range res {
- res[n] = []string{}
- }
- for _, tr := range table.TRs {
- for n, td := range table.TRs[0].TDs { //第一行的所有td
- td1 := table.GetTdByRCNo(tr.TDs[0].StartRow, td.StartCol) //根据行号列号获取td对象
- if td1 != nil {
- res[n] = append(res[n], td1.Val)
- } else {
- res[n] = append(res[n], "")
- }
- }
- }
- return res
- }
- // tr单列,是否丢弃内容
- func trSingleColumn(tr *TR, bcon bool, table *Table) bool {
- if len(tr.TDs) == 1 {
- bcon = false
- td := tr.TDs[0]
- if td.StartCol == 0 && td.EndCol+1 == table.ColNum && len([]rune(td.Val)) > 4 && len([]rune(td.Val)) < 50 {
- res, _, _, _, _ := CheckCommon(td.Val, "abandontable")
- if res { //以下内容丢弃
- bcon = true
- }
- }
- }
- return bcon
- }
- // 获取中标人顺序
- // direct 0默认 1横向 2纵向
- func GetBidOrder(td *TD, direct, n int) (d int, res bool) {
- if td.Valtype != "BO" {
- return
- }
- if td.Rowspan > 1 {
- for i := 0; i < td.Rowspan; i++ {
- nextcol := 1
- L1:
- for {
- vtd := td.TR.Table.GetTdByRCNo(td.StartRow+i, td.EndCol+nextcol)
- if vtd == nil {
- break L1
- }
- nextcol += vtd.Colspan
- if filter_zbdw_v2.MatchString(vtd.Val) {
- arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
- if arrbo == nil {
- arrbo = []map[string]interface{}{}
- td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
- }
- a1 := arrbo.([]map[string]interface{})
- a1 = append(a1, map[string]interface{}{
- "entname": vtd.Val,
- "sortstr": td.Val,
- "sort": GetBidSort(td.Val, n),
- })
- res = true
- td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
- }
- }
- }
- } else if td.Colspan > 1 {
- for i := 1; i < td.Colspan; i++ {
- nextcol := 0
- L2:
- for {
- vtd := td.TR.Table.GetTdByRCNo(td.StartRow+i, td.StartCol+nextcol)
- if vtd == nil || vtd.Colspan >= td.Colspan {
- break L2
- }
- nextcol += vtd.Colspan
- if filter_zbdw_v2.MatchString(vtd.Val) {
- arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
- if arrbo == nil {
- arrbo = []map[string]interface{}{}
- td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
- }
- a1 := arrbo.([]map[string]interface{})
- a1 = append(a1, map[string]interface{}{
- "entname": vtd.Val,
- "sortstr": td.Val,
- "sort": GetBidSort(td.Val, n),
- })
- res = true
- td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
- }
- }
- }
- } else {
- rtd := td.TR.Table.GetTdByRCNo(td.StartRow, td.EndCol+1)
- btd := td.TR.Table.GetTdByRCNo(td.EndRow+1, td.StartCol)
- //if ((rtd != nil && !rtd.BH && rtd.Valtype == "BO") || direct == 1) && btd != nil && filter_zbdw_v.MatchString(btd.Val) {
- if ((rtd != nil && !rtd.BH) || direct == 1) && btd != nil && filter_zbdw_v2.MatchString(btd.Val) {
- d = 1
- arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
- if arrbo == nil {
- arrbo = []map[string]interface{}{}
- td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
- }
- a1 := arrbo.([]map[string]interface{})
- a1 = append(a1, map[string]interface{}{
- "entname": btd.Val,
- "sortstr": td.Val,
- "sort": GetBidSort(td.Val, n),
- })
- res = true
- td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
- //} else if ((btd != nil && !btd.BH && btd.Valtype == "BO") || direct == 2) && rtd != nil && filter_zbdw_v.MatchString(rtd.Val) {
- } else if ((btd != nil && !btd.BH) || direct == 2) && rtd != nil && filter_zbdw_v2.MatchString(rtd.Val) {
- d = 2
- arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
- if arrbo == nil {
- arrbo = []map[string]interface{}{}
- td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
- }
- a1 := arrbo.([]map[string]interface{})
- a1 = append(a1, map[string]interface{}{
- "entname": rtd.Val,
- "sortstr": td.Val,
- "sort": GetBidSort(td.Val, n),
- })
- res = true
- td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
- }
- }
- return
- }
- func GetBidSort(str string, n int) int {
- val := n
- if strings.Index(str, "首选") > -1 {
- val = 1
- } else {
- val = winnerOrderEntity.toNumber(str, n)
- }
- return val
- }
|