analytable.go 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. package pretreated
  2. import (
  3. "fmt"
  4. "jy/clear"
  5. u "jy/util"
  6. qutil "qfw/util"
  7. "strings"
  8. "unicode/utf8"
  9. )
  10. // 对table进行整体解析处理
  11. func (tn *Table) AnalyTables(contactFormat *u.ContactFormat, isSite bool, codeSite string) []*Table {
  12. ts := tn.tableSubDemolitionTable() //分包,拆表
  13. for n, table := range ts {
  14. //处理每个table
  15. if len(table.TRs) > 0 {
  16. //删除尾部空白行
  17. table.deleteTrimTr()
  18. //table.Print()
  19. //校对表格
  20. table.Adjust(isSite, codeSite)
  21. //查找表格的标签,table.Tag字段
  22. table.FindTag()
  23. //分割表格
  24. table.bSplit(n, ts, isSite, codeSite)
  25. table.TdContactFormat(contactFormat, isSite, codeSite) //contactFormat,处理采购单位,代理机构
  26. //开始查找kv,核心模块,table.SortKV
  27. table.FindKV(isSite, codeSite)
  28. //table中抽取品牌,table.BrandData
  29. if u.IsBrandGoods {
  30. table.analyBrand()
  31. }
  32. //table中抽取单价和个数
  33. if u.IsPriceNumber {
  34. //qutil.Debug("======================抽取price和number===========")
  35. table.extractPriceNumber()
  36. }
  37. res, _, _, _, _ := CheckCommon(table.Tag, "abandontable")
  38. if !res { //调试
  39. //过滤、标准化、合并kv,table.StandKV,table.StandKVWeight
  40. table.KVFilter(isSite, codeSite)
  41. }
  42. //对有表头表格的处理
  43. if table.Tag != "" && utf8.RuneCountInString(table.Tag) < 100 {
  44. co, m, b := CheckMultiPackage(table.Tag) //分包处理
  45. if b {
  46. table.BPackage = b
  47. if len(table.BlockPackage.Map) == 0 {
  48. for _, av := range m {
  49. kv := u.NewJobKv()
  50. kv.KvTags = table.StandKV
  51. bd := u.PackageNumberConvert(av[0])
  52. //切割文本分包
  53. blockPackage := &u.BlockPackage{
  54. Origin: av[0],
  55. Name: av[0],
  56. Text: co,
  57. TableKV: kv,
  58. Index: bd,
  59. }
  60. if bd != "" {
  61. table.BlockPackage.AddKey(bd, blockPackage)
  62. } else {
  63. table.BlockPackage.AddKey(av[0], blockPackage)
  64. }
  65. }
  66. }
  67. table.StandKV["项目名称"] = append(table.StandKV["项目名称"], &u.Tag{Key: "项目名称", Value: table.Tag, Weight: -300})
  68. }
  69. }
  70. //判断是否是多包,并处理分包的//遍历td分块
  71. table.CheckMultiPackageByTable(isSite, codeSite) //分包处理
  72. //MergeKvTags(table.TableResult.KvTags, table.StandKV)
  73. }
  74. }
  75. return ts
  76. }
  77. // 查找每一个单元格的表头,调用FindNear
  78. func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
  79. if td.Val == "" || strings.TrimSpace(td.Val) == "" {
  80. return
  81. }
  82. near := table.FindNear(td, direct)
  83. if near != nil && near.BH && (near.KeyDirect == vdirect || near.KeyDirect == 0) && (near.KVDirect == direct || near.KVDirect == 0) && near.KVDirect < 3 {
  84. near.KVDirect = direct
  85. near.KeyDirect = vdirect
  86. td.KVDirect = direct
  87. key := repSpace.ReplaceAllString(near.Val, "")
  88. //临时去掉换行-进行判断
  89. tmp_tdVal := strings.ReplaceAll(td.Val, "\n", "")
  90. if key == "名称" && near.StartCol == 0 && near.Rowspan > 0 {
  91. new_key := ""
  92. tr := table.TRs[:td.TR.RowPos]
  93. if len(tr) > len(tr)-1 && len(tr) > 0 {
  94. tds := tr[len(tr)-1].TDs
  95. if len(tds) > td.EndCol && tds != nil {
  96. td1 := tds[td.EndCol]
  97. if zbhxrSecondReg.MatchString(td1.Val) {
  98. new_key = td1.Val
  99. }
  100. }
  101. }
  102. if new_key == "" {
  103. for _, vn := range table.TRs[near.Rowspan-1].TDs {
  104. if strings.Contains(vn.Val, "代理") {
  105. key = "代理机构"
  106. break
  107. } else if strings.Contains(vn.Val, "招标") {
  108. key = "采购单位"
  109. break
  110. } else if strings.Contains(vn.Val, "中标") && utf8.RuneCountInString(tmp_tdVal) >= 4 {
  111. key = "中标单位"
  112. break
  113. }
  114. }
  115. } else {
  116. key = new_key
  117. }
  118. } else if zbhxrReg.MatchString(key) && findCandidate2.MatchString(tmp_tdVal) {
  119. new_key := "中标单位"
  120. tr_top := table.TRs[:td.TR.RowPos]
  121. if len(tr_top) > len(tr_top)-1 && len(tr_top) > 0 { //上临查询
  122. tds := tr_top[len(tr_top)-1].TDs
  123. if len(tds) > td.ColPos && tds != nil && len(tds) == len(td.TR.TDs) {
  124. td1 := tds[td.ColPos]
  125. if zbhxrSortNameReg.MatchString(td1.Val) {
  126. new_key = td1.Val
  127. } else {
  128. if zbhxrSortReg_1.MatchString(td1.Val) {
  129. new_key = "中标候选人" + td1.Val
  130. }
  131. }
  132. }
  133. }
  134. if new_key == "中标单位" { //最左临查询
  135. tr_left := table.TRs[:td.TR.RowPos+1]
  136. tds_left := tr_left[len(tr_left)-1].TDs
  137. if td.ColPos > 0 {
  138. td1 := tds_left[0]
  139. if zbhxrSortReg_2.MatchString(td1.Val) { //针对排名情况
  140. new_key = "中标候选人第" + td1.Val + "名"
  141. } else {
  142. if zbhxrSortReg_1.MatchString(td1.Val) {
  143. new_key = "中标候选人" + td1.Val
  144. }
  145. }
  146. }
  147. }
  148. if new_key != "中标单位" {
  149. td.Val = tmp_tdVal
  150. }
  151. key = new_key
  152. } else if zbhxrReg.MatchString(key) && findCandidate3.MatchString(tmp_tdVal) {
  153. key = "中标单位名称"
  154. } else if key == "投标人名称" || key == "单位名称" { //左临上临-拼接
  155. tmpnewnear := table.FindNear(near, 1)
  156. if tmpnewnear == nil {
  157. tmpnewnear = table.FindNear(near, 2)
  158. }
  159. if tmpnewnear != nil {
  160. if (table.Tag == "成交候选人" || table.Tag == "中标候选人") &&
  161. zbhxrSortReg_1.MatchString(tmpnewnear.Val) {
  162. key = "中选候选人" + tmpnewnear.Val
  163. } else if table.Tag == "中标情况" {
  164. if tmpnewnear.MustBH || tmpnewnear.BH {
  165. if tmpnewnear.Val == "标段名称" && findCandidate2.MatchString(td.Val) {
  166. key = "中标单位名称"
  167. }
  168. }
  169. } else {
  170. if tmpnewnear.MustBH || tmpnewnear.BH {
  171. if tmpnewnear.Val == "中标候选人情况" && zbhxrSortReg_3.MatchString(td.Val) {
  172. key = "中标候选人第" + zbhxrSortReg_3.FindString(td.Val) + "名"
  173. } else if tmpnewnear.Val == "名次" || tmpnewnear.Val == "排名" || tmpnewnear.Val == "序号" || tmpnewnear.Val == "中标候选人排名" {
  174. if vv, ok := table.SortKV.Map[tmpnewnear.Val].(string); ok {
  175. if vv == "1" && findCandidate2.MatchString(td.Val) && key == "单位名称" {
  176. key = "中标单位名称"
  177. }
  178. }
  179. } else {
  180. key = tmpnewnear.Val + near.Val
  181. }
  182. }
  183. }
  184. } else {
  185. if table.Tag == "成交单位" && key == "单位名称" {
  186. key = "中标单位名称"
  187. } else if key == "单位名称" {
  188. tmpdirect := 2
  189. if direct == 2 {
  190. tmpdirect = 1
  191. }
  192. tmpnewnear = table.FindNear(td, tmpdirect)
  193. if tmpnewnear != nil {
  194. if tmpnewnear.Val == "中标人" {
  195. key = "中标单位名称"
  196. }
  197. }
  198. }
  199. }
  200. } else if key == "采购人(乙方)" || key == "采购人(乙方)" {
  201. if findCandidate2.MatchString(td.Val) {
  202. key = "中标单位"
  203. }
  204. } else if key == "企业名称" {
  205. if findCandidate2.MatchString(td.Val) && strings.Contains(qutil.ObjToString(table.Tag), "履约信息") {
  206. key = "中标单位"
  207. }
  208. } else if key == "发布部门" || key == "主体名称" {
  209. if findCandidate2.MatchString(td.Val) && strings.Contains(qutil.ObjToString(table.Tag), "履约信息") {
  210. key = "采购单位"
  211. }
  212. } else if key == "金额" {
  213. //父级表格
  214. pre_near := table.FindNear(near, direct)
  215. if pre_near != nil {
  216. if pre_near.Val == "第一中标候选人" {
  217. key = pre_near.Val + key
  218. }
  219. }
  220. } else if key == "第一候选人" && qutil.Float64All(tmp_tdVal) > 0.0 {
  221. if tmp_near := table.FindNear(td, 2); tmp_near != nil {
  222. if winMoneyReg.MatchString(tmp_near.Val) {
  223. key = tmp_near.Val
  224. }
  225. }
  226. } else if key == "联系人" || key == "联系电话" {
  227. if table.Toptype_Old == "采购意向" {
  228. key = "采购" + key
  229. }
  230. }
  231. if near.Val == "" {
  232. key = fmtkey("k", near.TR.RowPos, near.ColPos)
  233. }
  234. val := table.SortKV.Map[key]
  235. //qutil.Debug("====================", "key:", key, "val:", val)
  236. bthiskey := false
  237. if val != nil {
  238. curpos := table.SortKV.Index[key]
  239. thistr := table.kTD[curpos]
  240. if thistr != near {
  241. if strings.TrimSpace(near.Val) == "名称" && near.TR != nil && len(near.TR.TDs) > 0 && near.ColPos-1 >= 0 {
  242. rv := near.TR.TDs[near.ColPos-1].Val
  243. if near.ColPos > 0 && (strings.Contains(rv, "招标") || strings.Contains(rv, "代理") || strings.Contains(rv, "采购") || strings.Contains(rv, "中标")) {
  244. near = near.TR.TDs[near.ColPos-1]
  245. }
  246. } else {
  247. bthiskey = true
  248. }
  249. } else {
  250. bthiskey = true
  251. }
  252. }
  253. bfind := false
  254. barr := false
  255. varrpos := -1
  256. if bthiskey {
  257. //处理是数组值,且有合并行或合并列的情况 kvscope,对数组值的处理
  258. pos := table.SortKV.Index[key]
  259. mval := table.kvscope[pos]
  260. bvalfind := false
  261. if direct == 1 { //kv是横向
  262. L1:
  263. for k3, v3 := range mval {
  264. for _, v4 := range v3 {
  265. if v4.EndRow+1 == td.StartRow && v4.EndCol == td.EndCol {
  266. varrpos = k3
  267. bvalfind = true
  268. break L1
  269. }
  270. }
  271. }
  272. } else { //kv是纵向
  273. L2:
  274. for k3, v3 := range mval {
  275. for _, v4 := range v3 {
  276. if v4.EndCol+1 == td.StartCol && v4.EndRow == td.EndRow {
  277. varrpos = k3
  278. bvalfind = true
  279. break L2
  280. }
  281. }
  282. }
  283. }
  284. if vals, ok := val.([]string); ok {
  285. if near.Val == "" {
  286. bn := false
  287. for _, vs := range vals {
  288. if vs != "" && NullTdReg.MatchString(vs) {
  289. bn = true
  290. } else {
  291. bn = false
  292. break
  293. }
  294. }
  295. if bn {
  296. near.Val = NullTxtBid
  297. key = NullTxtBid
  298. bfind = true
  299. }
  300. }
  301. if bvalfind && varrpos > -1 && len(vals) > varrpos {
  302. tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
  303. if tmapval == "" {
  304. vals = append(vals, td.Val) // 累加
  305. } else {
  306. vals = append(vals, tmapval) // 累加
  307. }
  308. val = vals
  309. //vals[varrpos] = td.Val // += "__" + td.Val
  310. } else {
  311. //添加时候去除空值和nil
  312. newVals := []string{}
  313. for _, isval := range vals {
  314. if isval == "" {
  315. continue
  316. }
  317. newVals = append(newVals, isval)
  318. }
  319. //vals = append(vals, td.Val)
  320. if td.Val != "" {
  321. newVals = append(newVals, td.Val)
  322. }
  323. val = newVals
  324. varrpos = len(vals) - 1
  325. }
  326. } else if vals, ok := val.(string); ok && vals != "" && td.Val != "" {
  327. tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(vals, "")) //已存在的kv
  328. tmapvaltd := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
  329. if bvalfind {
  330. if key == "中标单位" { //不能覆盖---
  331. } else {
  332. if tmapvaltd == "" {
  333. val = td.Val //vals + "__" + td.Val
  334. } else {
  335. val = tmapvaltd
  336. }
  337. }
  338. } else {
  339. if key == "中标单位" { //新增不能数组
  340. } else {
  341. if zbhxrSortNameReg.MatchString(key) {
  342. //特殊~不构建数组
  343. } else {
  344. tval := []string{}
  345. if tmapval == "" {
  346. tval = append(tval, vals)
  347. } else {
  348. tval = append(tval, tmapval)
  349. }
  350. if tmapvaltd == "" {
  351. tval = append(tval, td.Val)
  352. } else {
  353. tval = append(tval, tmapvaltd)
  354. }
  355. val = tval
  356. varrpos = 1
  357. }
  358. }
  359. }
  360. }
  361. barr = true
  362. } else {
  363. if td.Val != "" {
  364. tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
  365. if tmapval == "" {
  366. val = td.Val
  367. } else {
  368. val = tmapval
  369. }
  370. } else if len(near.SortKV.Map) == 1 && near.SortKV.Map[near.Val] != "" {
  371. val = near.SortKV.Map[near.Val]
  372. }
  373. }
  374. td.HeadTd = near
  375. if bfind {
  376. tkey := fmtkey("k", near.TR.RowPos, near.ColPos)
  377. table.SortKV.ReplaceKey(key, val, tkey)
  378. } else {
  379. if key == "单位名称" && len(near.TR.TDs) > 1 {
  380. if near.TR.TDs[0].Val != "序号" {
  381. key = near.TR.TDs[0].Val
  382. }
  383. }
  384. table.SortKV.AddKey(key, val)
  385. pos := table.SortKV.Index[key]
  386. if barr {
  387. mval := table.kvscope[pos]
  388. if mval != nil {
  389. tds := mval[varrpos]
  390. if tds != nil {
  391. tds = append(tds, td)
  392. } else {
  393. tds = []*TD{td}
  394. }
  395. if varrpos > -1 {
  396. mval[varrpos] = tds
  397. table.kvscope[pos] = mval
  398. }
  399. }
  400. } else {
  401. table.kvscope[pos] = map[int][]*TD{
  402. 0: []*TD{td},
  403. }
  404. table.kTD[pos] = near
  405. }
  406. }
  407. b = true
  408. }
  409. return
  410. }
  411. // 查找单元格的表头时,横向或纵向
  412. func (table *Table) FindNear(td *TD, direct int) *TD {
  413. if direct == 1 && td.StartCol > 0 { //左临
  414. tr := table.TRs[:td.TR.RowPos+1]
  415. for i := len(tr) - 1; i > -1; i-- {
  416. tds := tr[i].TDs
  417. for _, td1 := range tds {
  418. if td1.StartRow <= td.StartRow && td1.EndRow >= td.EndRow && td1.EndCol+1 == td.StartCol {
  419. //找到左临节点
  420. if td1.BH || (zbhxrSortReg_1.MatchString(td1.Val) && (table.Tag == "成交候选人" || table.Tag == "中标候选人")) {
  421. return td1
  422. } else {
  423. if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct {
  424. return td1.HeadTd
  425. }
  426. }
  427. }
  428. }
  429. }
  430. } else if direct == 2 && td.StartRow > 0 { //上临
  431. tr := table.TRs[:td.TR.RowPos]
  432. for i := len(tr) - 1; i > -1; i-- {
  433. tds := tr[i].TDs
  434. for it, td1 := range tds {
  435. if td1.StartCol <= td.StartCol && td1.EndCol >= td.EndCol && td1.EndRow+1 == td.StartRow {
  436. if td1.BH {
  437. //new_td := tds[td.ColPos] //列错落
  438. //if td.ColPos!=it && new_td.BH {
  439. // return new_td
  440. //}
  441. return td1
  442. } else if len(tr[i].TDs) == len(td.TR.TDs) && td1.HeadTd != nil && td1.HeadTd.KVDirect == direct {
  443. return td1.HeadTd
  444. } 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, "中标候选人") {
  445. return tds[it-1]
  446. } else if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct && td.Colspan == td1.Colspan && td.Rowspan == td.Rowspan {
  447. return td1.HeadTd
  448. } else {
  449. }
  450. } else if len(td.TR.TDs) == len(tds) && i == len(tr)-1 && len(tds) > td.ColPos &&
  451. it == td.ColPos && td1.EndRow+1 == td.StartRow {
  452. new_td := tds[td.ColPos]
  453. if new_td.BH {
  454. return new_td
  455. }
  456. }
  457. }
  458. }
  459. }
  460. return nil
  461. }
  462. // 根据行号列号获取td对象
  463. func (tn *Table) GetTdByRCNo(row, col int) *TD {
  464. for _, tr := range tn.TRs {
  465. for _, td := range tr.TDs {
  466. if td.StartCol <= col && td.EndCol >= col && td.StartRow <= row && td.EndRow >= row {
  467. return td
  468. }
  469. }
  470. }
  471. return nil
  472. }
  473. // 判断表格是否是分包
  474. func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool, index []string) {
  475. pac := 0 //包的数量
  476. val := 0 //分值
  477. index = []string{} //存储分包,使用tbale.SortKV的key和value使用正则等处理对值进行判断
  478. index_pos := []int{} //下标
  479. //是数组且能找到标段之类的提示
  480. //arr_count := 0 //计数table.SortKV的value是数组的数量,后面没用
  481. key_index := -1
  482. hasPkgTd := map[string]bool{}
  483. //初始化CheckMultiPackageByTable方法需要的数据
  484. key_index, index, index_pos, val, pac, hasPkgTd = initCheckMultiPackageByTable(tn, key_index, index, index_pos, val, pac, hasPkgTd)
  485. //key是分包的情况
  486. //记录key对应的值
  487. commonKeyVals := map[string][]string{}
  488. //记录key出现的次数
  489. keyExistsCount := map[string]int{}
  490. if pac > 1 {
  491. val = 10
  492. } else {
  493. //查找标签
  494. if TableMultiPackageReg_4.MatchString(tn.Tag) {
  495. val += 4
  496. } else if TableMultiPackageReg_2.MatchString(tn.Tag) {
  497. val += 4
  498. }
  499. //根据table.SortKV的key判断是否分包,如果没有再根据value判断
  500. val, index, index_pos = foundPacBySortKV(tn, val, index, index_pos, &keyExistsCount, &commonKeyVals, key_index, hasPkgTd)
  501. }
  502. // u.Debug(index)
  503. //过滤重复及标准化!
  504. standIndex := []string{}
  505. standIndex_pos := []int{}
  506. oldIndex := []string{} //存放包的原始值
  507. brepeat := map[string]bool{}
  508. for k, v := range index {
  509. v = u.PackageNumberConvert(v)
  510. if !brepeat[v] {
  511. brepeat[v] = true
  512. standIndex = append(standIndex, v)
  513. standIndex_pos = append(standIndex_pos, index_pos[k])
  514. oldIndex = append(oldIndex, index[k])
  515. }
  516. }
  517. index = standIndex
  518. //有一个以上的包,并且相同的key出现一次以上,认为这个key是属于包里面的
  519. if len(commonKeyVals) > 0 {
  520. for k, v := range commonKeyVals {
  521. if len(index) > 1 && keyExistsCount[k] < 2 {
  522. continue
  523. }
  524. tn.SortKV.AddKey(k, v)
  525. }
  526. }
  527. //
  528. isGoonNext := false
  529. if val > 4 && len(brepeat) > 0 {
  530. b = true
  531. //多包解析
  532. if b {
  533. tn.BPackage = true
  534. //pnum := len(index)
  535. //根据数组index分包长度添加table.BlockPackage子包数组
  536. for nk, v := range index {
  537. if tn.BlockPackage.Map[v] == nil {
  538. kv := u.NewJobKv()
  539. for tnk, tnv := range tn.StandKV {
  540. if nk >= len(tnv) {
  541. continue
  542. } else if len(index) == len(tnv) {
  543. if tnk == "预算" && isUnRealBudgetBp(tnv) {
  544. continue
  545. }
  546. if tnk == "预算" && codeSite == "ha_zmdszfcgw_cgxx" && len(tnv) > 1 {
  547. isEqErr, budget_v := false, ""
  548. for bk, bv := range tnv {
  549. if bk == 0 {
  550. budget_v = bv.Value
  551. } else {
  552. if budget_v != bv.Value {
  553. isEqErr = true
  554. break
  555. }
  556. }
  557. }
  558. if isEqErr {
  559. kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
  560. }
  561. } else {
  562. kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
  563. }
  564. }
  565. }
  566. //kv.KvTags = tn.StandKV
  567. bp := &u.BlockPackage{}
  568. bp.Index = v //序号 (转换后编号,只有数字或字母)
  569. bp.Origin = oldIndex[nk] //包的原始值
  570. bp.TableKV = kv //table kv (分出的对应的KV值)
  571. bp.Name = v
  572. if bp.TableKV != nil && bp.TableKV.KvTags != nil && len(bp.TableKV.KvTags) > 0 {
  573. for kc, cv := range bp.TableKV.KvTags {
  574. if kc == "预算" && bp.Budget <= 0 {
  575. moneys := clear.ObjToMoney([]interface{}{cv[0].Value, ""})
  576. if len(moneys) > 0 {
  577. if vf, ok := moneys[0].(float64); ok {
  578. bp.Budget = vf
  579. bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
  580. } else if vi, ok := moneys[0].(int); ok {
  581. bp.Budget = float64(vi)
  582. bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
  583. }
  584. }
  585. } else if kc == "中标金额" && bp.Bidamount <= 0 {
  586. moneys := clear.ObjToMoney([]interface{}{cv[0].Value, ""})
  587. if len(moneys) > 0 {
  588. if vf, ok := moneys[0].(float64); ok {
  589. bp.Bidamount = vf
  590. bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
  591. } else if vi, ok := moneys[0].(int); ok {
  592. bp.Bidamount = float64(vi)
  593. bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
  594. }
  595. }
  596. } else if kc == "中标单位" && bp.Winner == "" {
  597. bp.Winner = cv[0].Value
  598. }
  599. //拼接内容
  600. if !excludeKey.MatchString(kc) {
  601. bp.Text += fmt.Sprintf("%v:%v\n", kc, cv[0].Value)
  602. }
  603. }
  604. } else { //新增 - 特殊情况 - 查找sortKV - 预算 - 中标金额 - 中标单位
  605. for k, v := range tn.SortKV.Map {
  606. //kt := u.GetTags(k, isSite, codeSite)
  607. if budgetSortKVReg.MatchString(k) {
  608. if vs, ok := v.([]string); ok {
  609. if len(index) == len(vs) {
  610. moneys := clear.ObjToMoney([]interface{}{vs[nk], ""})
  611. if len(moneys) > 0 {
  612. if vf, ok := moneys[0].(float64); ok {
  613. if !strings.Contains(vs[nk], "万") &&
  614. strings.Contains(k, "万") {
  615. vf = 10000.0 * vf
  616. }
  617. bp.Budget = vf
  618. bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
  619. } else if vi, ok := moneys[0].(int); ok {
  620. if !strings.Contains(vs[nk], "万") &&
  621. strings.Contains(k, "万") {
  622. vi = 10000 * vi
  623. }
  624. bp.Budget = float64(vi)
  625. bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
  626. }
  627. }
  628. }
  629. }
  630. }
  631. if bidamountSortKVReg.MatchString(k) {
  632. if vs, ok := v.([]string); ok {
  633. if len(index) == len(vs) {
  634. moneys := clear.ObjToMoney([]interface{}{vs[nk], ""})
  635. if len(moneys) > 0 {
  636. if vf, ok := moneys[0].(float64); ok {
  637. if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") {
  638. vf = 10000.0 * vf
  639. }
  640. bp.Bidamount = vf
  641. bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
  642. } else if vi, ok := moneys[0].(int); ok {
  643. if !strings.Contains(vs[nk], "万") && strings.Contains(k, "万") {
  644. vi = 10000.0 * vi
  645. }
  646. bp.Bidamount = float64(vi)
  647. bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
  648. }
  649. }
  650. }
  651. }
  652. }
  653. if winnerSortKVReg.MatchString(k) {
  654. if vs, ok := v.([]string); ok {
  655. if len(index) == len(vs) {
  656. bp.Winner = vs[nk]
  657. }
  658. }
  659. }
  660. }
  661. }
  662. tn.BlockPackage.AddKey(v, bp) //table子包数组
  663. }
  664. }
  665. isGoonNext = tn.manyPackageProcessByIndex(index, standIndex_pos, isSite, codeSite) //多包处理,处理不同情况下的分包
  666. }
  667. } else {
  668. isGoonNext = true
  669. }
  670. if isGoonNext { //没有处理成数组的情况下,继续调用正文查找分包的方法
  671. tn.isGoonNext(isSite, codeSite)
  672. }
  673. //查找分包中的中标人排序-分包找候选人
  674. if tn.BlockPackage != nil && tn.BlockPackage.Keys != nil && len(tn.BlockPackage.Keys) > 0 {
  675. for _, v := range tn.BlockPackage.Keys {
  676. vv, ok := tn.BlockPackage.Map[v].(*u.BlockPackage)
  677. if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) {
  678. vv.WinnerOrder = winnerOrderEntity.Find(vv.Text, true, 2, isSite, codeSite)
  679. }
  680. //if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) && (tn.WinnerOrder == nil || len(tn.WinnerOrder) == 0) {
  681. // vv.WinnerOrder = tn.WinnerOrder
  682. //}
  683. }
  684. }
  685. return
  686. }
  687. // 多包处理,处理不同情况下的分包
  688. func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int, isSite bool, codeSite string) (isGoonNext bool) {
  689. if len(index) == 1 { //是一个的情况
  690. if len(tn.SortKV.Keys) < 10 && tn.ColNum < 10 && tn.RowNum < 4 { //table带排序的KV值小于10并且小于10列和小于4行
  691. beq := true
  692. for _, v2 := range tn.SortKV.Keys {
  693. if _, ok := tn.SortKV.Map[v2].(string); !ok {
  694. beq = false
  695. break
  696. }
  697. }
  698. if beq { //统一处理为数组
  699. td := tn.GetTdByRCNo(tn.RowNum-1, 0)
  700. if !td.BH && FindVal2_1.MatchString(td.Val) {
  701. for _, v2 := range tn.SortKV.Keys {
  702. tn.SortKV.AddKey(v2, []string{tn.SortKV.Map[v2].(string)})
  703. }
  704. } else {
  705. //没有处理成数组的情况下,继续调用正文查找分包的方法
  706. isGoonNext = true
  707. }
  708. }
  709. }
  710. }
  711. for _, k1 := range tn.SortKV.Keys {
  712. v1 := tn.SortKV.Map[k1]
  713. var v1_arr []string
  714. if vtmpv1, ok := v1.(string); ok {
  715. v1_arr = PreCon4.FindAllString(qutil.ObjToString(vtmpv1), -1)
  716. if len(v1_arr) > 0 {
  717. if dw := Precon4dw.FindString(vtmpv1); dw != "" {
  718. for i, v := range v1_arr {
  719. v1_arr[i] = v + dw
  720. }
  721. }
  722. }
  723. } else if vtmpv1s, ok := v1.([]string); ok {
  724. v1_arr = vtmpv1s
  725. }
  726. if len(v1_arr) > 0 && len(v1_arr) <= len(index) { //table.SortKV.Map.value数组小于等于分包index
  727. for k, v := range v1_arr {
  728. tn.assemblePackage(k1, v, index[k], isSite, codeSite) //组装解析到的分包
  729. }
  730. }
  731. }
  732. return isGoonNext
  733. }
  734. // 没有处理成数组的情况下,继续调用正文查找分包的方法
  735. func (tn *Table) isGoonNext(isSite bool, codeSite string) {
  736. blockPackage := map[string]*u.BlockPackage{}
  737. for _, k := range tn.SortKV.Keys {
  738. if excludeKey.MatchString(k) || strings.Contains(k, "批复") || excludeKey3.MatchString(k) {
  739. continue
  740. }
  741. str := "" //拼装为冒号kv
  742. v := tn.SortKV.Map[k]
  743. nk := regReplAllSpace.ReplaceAllString(k, "")
  744. if vs, ok := v.([]string); ok {
  745. str += fmt.Sprintf("%s:%s\n", nk, strings.Join(vs, " "))
  746. } else {
  747. str += fmt.Sprintf("%s:%s\n", nk, v)
  748. }
  749. if excludeKey2.MatchString(str) {
  750. continue
  751. }
  752. b, _ := divisionPackageChild(&blockPackage, str, tn.Tag, false, false, isSite, codeSite) //分块之后分包
  753. if b && len(blockPackage) > 0 {
  754. tn.BPackage = true
  755. for mk, mv := range blockPackage {
  756. if tn.BlockPackage.Map[mk] == nil {
  757. tn.BlockPackage.AddKey(mk, mv)
  758. } else {
  759. bp := tn.BlockPackage.Map[mk].(*u.BlockPackage)
  760. if bp.TableKV == nil {
  761. bp.TableKV = u.NewJobKv()
  762. }
  763. if bp.SpaceKV == nil {
  764. bp.SpaceKV = u.NewJobKv()
  765. }
  766. for k2, v2 := range mv.ColonKV.KvTags {
  767. for _, v2v := range v2 {
  768. isExists := false
  769. for _, v2vv := range bp.TableKV.KvTags[k2] {
  770. if v2v.Value == v2vv.Value {
  771. isExists = true
  772. break
  773. }
  774. }
  775. if !isExists {
  776. bp.TableKV.KvTags[k2] = append(bp.TableKV.KvTags[k2], v2v)
  777. bp.Text += fmt.Sprintf("%v:%v\n", k2, v2)
  778. }
  779. }
  780. }
  781. for k2, v2 := range mv.SpaceKV.KvTags {
  782. for _, v2v := range v2 {
  783. isExists := false
  784. for _, v2vv := range bp.SpaceKV.KvTags[k2] {
  785. if v2v.Value == v2vv.Value {
  786. isExists = true
  787. break
  788. }
  789. }
  790. if !isExists {
  791. bp.SpaceKV.KvTags[k2] = append(bp.SpaceKV.KvTags[k2], v2v)
  792. bp.Text += fmt.Sprintf("%v:%v\n", k2, v2)
  793. }
  794. }
  795. }
  796. }
  797. }
  798. tn.BPackage = true
  799. tn.SortKV.RemoveKey(k)
  800. }
  801. }
  802. }
  803. // 根据table.SortKV的key判断是否分包,如果没有再根据value判断
  804. 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) {
  805. keyIsPkg := false
  806. for in, k := range tn.SortKV.Keys {
  807. if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) || excludeKey3.MatchString(k) || regFJWarap.MatchString(k) || regAZWarap.MatchString(k) { //判断分包前排除
  808. continue
  809. }
  810. v := tn.SortKV.Map[k]
  811. //key是分包的情况
  812. if ismatch := FindVal_1.MatchString(k); keyIsPkg || ismatch {
  813. if ismatch {
  814. keyIsPkg = true
  815. val += 4
  816. pkgFlag := FindVal_1.FindString(k) //对值进行分包判断
  817. k = strings.Replace(k, pkgFlag, "", -1)
  818. index = append(index, pkgFlag)
  819. index_pos = append(index_pos, len(index))
  820. val += 1
  821. //pac++
  822. } else {
  823. k = strings.TrimRight(k, "_")
  824. }
  825. (*keyExistsCount)[k] = (*keyExistsCount)[k] + 1
  826. (*commonKeyVals)[k] = append((*commonKeyVals)[k], qutil.ObjToString(v))
  827. } else if k1 := FilterKey_2.ReplaceAllString(k, ""); FindKey_2.MatchString(k1) {
  828. val += 4
  829. //value数组分包
  830. if vs, bvs1 := v.([]string); bvs1 {
  831. L:
  832. for in2, v1 := range vs {
  833. if len([]rune(v1)) < 20 && !moneyNum.MatchString(v1) && FindVal2_1.MatchString(v1) {
  834. for _, serial := range tn.TableResult.RuleBlock.TitleRegs {
  835. if serial.MatchString(v1) {
  836. break L
  837. }
  838. }
  839. if key_index == -1 {
  840. key_index = in
  841. } else if key_index != in {
  842. break
  843. }
  844. index = append(index, v1)
  845. index_pos = append(index_pos, in2)
  846. val += 1
  847. //pac++
  848. }
  849. }
  850. } else if v1, ok := v.(string); ok && !hasPkgTd[k] {
  851. //value字符串分包
  852. v1 = replPkgConfusion(v1) //替换分包中混淆的词
  853. for _, v2 := range strings.Split(v1, "/") {
  854. if len([]rune(v2)) < 20 && !moneyNum.MatchString(v2) && FindVal2_1.MatchString(v2) {
  855. key_index = in
  856. index = append(index, v1)
  857. index_pos = append(index_pos, 0)
  858. val += 1
  859. //pac++
  860. underline := ""
  861. for {
  862. underline += "_"
  863. if tn.SortKV.Map[k+underline] == nil {
  864. break
  865. } else if v3, v2_ok := tn.SortKV.Map[k+underline].(string); v2_ok && v3 != "" {
  866. index = append(index, v3)
  867. index_pos = append(index_pos, 1)
  868. } else if v3, v2_ok := tn.SortKV.Map[k+underline].([]string); v2_ok {
  869. for v2_k, v2_v := range v3 {
  870. index = append(index, v2_v)
  871. index_pos = append(index_pos, v2_k+1)
  872. }
  873. }
  874. }
  875. break
  876. }
  877. }
  878. }
  879. if k1 == "标段" && len(index) == 0 {
  880. continue
  881. } else {
  882. break
  883. }
  884. }
  885. }
  886. return val, index, index_pos
  887. }
  888. // 初始化CheckMultiPackageByTable方法需要的数据
  889. 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) {
  890. for in, k := range tn.SortKV.Keys {
  891. //涉及包号|包件号?|项目标号|规格|型号|招标范围|业绩|废标)|(^编号$)|([^包段标]编号)就跳过
  892. if excludeKey.MatchString(BracketsTextReg.ReplaceAllString(k, "")) || excludeKey3.MatchString(k) || strings.Contains(k, "批复") {
  893. continue
  894. }
  895. v := tn.SortKV.Map[k]
  896. if vs, bvs := v.([]string); bvs {
  897. //arr_count++
  898. haspkgs := []string{}
  899. for in2, v1 := range vs {
  900. v1 = replPkgConfusion(v1) //替换分包中混淆的词
  901. if len([]rune(v1)) < 30 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) {
  902. if key_index == -1 {
  903. key_index = in
  904. } else if key_index != in {
  905. break
  906. }
  907. index = append(index, FindVal_1.FindString(v1))
  908. index_pos = append(index_pos, in2)
  909. val += 1
  910. pac++
  911. } else if FindKey_3.MatchString(k) {
  912. //5db2a101a5cb26b9b73054ac
  913. index = append(index, v1)
  914. index_pos = append(index_pos, in2)
  915. val += 1
  916. pac++
  917. } else {
  918. if ok, v1new := isHasOnePkgAndNoKv(v1); ok { //td的值里面有一个包,并且没有冒号kv
  919. haspkgs = append(haspkgs, v1new)
  920. }
  921. }
  922. }
  923. /*处理这种情况:
  924. <tr><td>包一:xxxxxxxxx</td></tr>
  925. <tr><td>包二:xxxxxxxxx</td></tr>
  926. */
  927. if len(index) == 0 && len(haspkgs) > 0 && len(haspkgs) == len(vs) {
  928. for in2, v1 := range haspkgs {
  929. if key_index == -1 {
  930. key_index = in
  931. } else if key_index != in {
  932. break
  933. }
  934. index = append(index, v1)
  935. index_pos = append(index_pos, in2)
  936. val += 1
  937. pac++
  938. }
  939. }
  940. } else if v1, ok := v.(string); ok {
  941. v1 = replPkgConfusion(v1) //替换分包中混淆的词
  942. if len([]rune(v1)) < 8 && !moneyNum.MatchString(v1) && FindVal_1.MatchString(v1) {
  943. key_index = in
  944. index = append(index, FindVal_1.FindString(v1))
  945. index_pos = append(index_pos, 0)
  946. val += 1
  947. pac++
  948. } else if getTd := tn.GetTdByRCNo(0, tn.SortKV.Index[k]); getTd != nil && getTd.KVDirect == 2 { //纵向
  949. /*处理这种情况:
  950. <tr><td>包一:xxxxxxxxx</td></tr>
  951. */
  952. if ok, v1new := isHasOnePkgAndNoKv(v1); ok {
  953. hasPkgTd[k] = true
  954. key_index = in
  955. index = append(index, v1new)
  956. index_pos = append(index_pos, 0)
  957. val += 1
  958. pac++
  959. }
  960. }
  961. }
  962. }
  963. return key_index, index, index_pos, val, pac, hasPkgTd
  964. }
  965. // 组装解析到的分包,//key如果匹配到抽取关键词就添加到table.SortKV
  966. func (tn *Table) assemblePackage(k1, v1, key string, isSite bool, codeSite string) {
  967. bp := tn.BlockPackage.Map[key].(*u.BlockPackage)
  968. if bp.TableKV == nil {
  969. bp.TableKV = u.NewJobKv()
  970. }
  971. if v1 != "" {
  972. kvTags, _ := CommonDataAnaly(k1, "中标情况", "", v1, isSite, codeSite) //匹配抽取关键词
  973. for k3, v3 := range kvTags {
  974. if bp.TableKV.KvTags[k3] == nil {
  975. bp.TableKV.KvTags[k3] = append(bp.TableKV.KvTags[k3], v3...)
  976. } else if k3 == "预算" && bp.Budget <= 0 {
  977. moneys := clear.ObjToMoney([]interface{}{v3[0].Value, ""})
  978. if len(moneys) > 0 {
  979. if vf, ok := moneys[0].(float64); ok {
  980. bp.Budget = vf
  981. bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
  982. } else if vi, ok := moneys[0].(int); ok {
  983. bp.Budget = float64(vi)
  984. bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
  985. }
  986. }
  987. } else if k3 == "中标金额" && bp.Bidamount <= 0 {
  988. moneys := clear.ObjToMoney([]interface{}{v3[0].Value, ""})
  989. if len(moneys) > 0 {
  990. if vf, ok := moneys[0].(float64); ok {
  991. bp.Bidamount = vf
  992. bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
  993. } else if vi, ok := moneys[0].(int); ok {
  994. bp.Bidamount = float64(vi)
  995. bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
  996. }
  997. }
  998. } else if k3 == "中标单位" && bp.Winner == "" {
  999. new_str := qutil.ObjToString(winnerOrderEntity.clear("中标单位", v3[0].Value))
  1000. if new_str != "" && WinnerOrderStr.MatchString(new_str) {
  1001. bp.Winner = new_str
  1002. }
  1003. }
  1004. }
  1005. }
  1006. k1 = regReplAllSpace.ReplaceAllString(k1, "")
  1007. //拼接内容
  1008. if !excludeKey.MatchString(k1) {
  1009. bp.Text += fmt.Sprintf("%v:%v\n", k1, v1)
  1010. }
  1011. tn.BlockPackage.AddKey(key, bp)
  1012. }
  1013. // 初始化组装纵向数据
  1014. func initLongitudinalData(table *Table) [][]string {
  1015. res := make([][]string, len(table.TRs[0].TDs)) //创建table第一行的列数长度
  1016. for n, _ := range res {
  1017. res[n] = []string{}
  1018. }
  1019. for _, tr := range table.TRs {
  1020. for n, td := range table.TRs[0].TDs { //第一行的所有td
  1021. td1 := table.GetTdByRCNo(tr.TDs[0].StartRow, td.StartCol) //根据行号列号获取td对象
  1022. if td1 != nil {
  1023. res[n] = append(res[n], td1.Val)
  1024. } else {
  1025. res[n] = append(res[n], "")
  1026. }
  1027. }
  1028. }
  1029. return res
  1030. }
  1031. // tr单列,是否丢弃内容
  1032. func trSingleColumn(tr *TR, bcon bool, table *Table) bool {
  1033. if len(tr.TDs) == 1 {
  1034. bcon = false
  1035. td := tr.TDs[0]
  1036. if td.StartCol == 0 && td.EndCol+1 == table.ColNum && len([]rune(td.Val)) > 4 && len([]rune(td.Val)) < 50 {
  1037. res, _, _, _, _ := CheckCommon(td.Val, "abandontable")
  1038. if res { //以下内容丢弃
  1039. bcon = true
  1040. }
  1041. }
  1042. }
  1043. return bcon
  1044. }
  1045. // 获取中标人顺序
  1046. // direct 0默认 1横向 2纵向
  1047. func GetBidOrder(td *TD, direct, n int) (d int, res bool) {
  1048. if td.Valtype != "BO" {
  1049. return
  1050. }
  1051. if td.Rowspan > 1 {
  1052. for i := 0; i < td.Rowspan; i++ {
  1053. nextcol := 1
  1054. L1:
  1055. for {
  1056. vtd := td.TR.Table.GetTdByRCNo(td.StartRow+i, td.EndCol+nextcol)
  1057. if vtd == nil {
  1058. break L1
  1059. }
  1060. nextcol += vtd.Colspan
  1061. if filter_zbdw_v2.MatchString(vtd.Val) {
  1062. arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
  1063. if arrbo == nil {
  1064. arrbo = []map[string]interface{}{}
  1065. td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
  1066. }
  1067. a1 := arrbo.([]map[string]interface{})
  1068. a1 = append(a1, map[string]interface{}{
  1069. "entname": vtd.Val,
  1070. "sortstr": td.Val,
  1071. "sort": GetBidSort(td.Val, n),
  1072. })
  1073. res = true
  1074. td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
  1075. }
  1076. }
  1077. }
  1078. } else if td.Colspan > 1 {
  1079. for i := 1; i < td.Colspan; i++ {
  1080. nextcol := 0
  1081. L2:
  1082. for {
  1083. vtd := td.TR.Table.GetTdByRCNo(td.StartRow+i, td.StartCol+nextcol)
  1084. if vtd == nil || vtd.Colspan >= td.Colspan {
  1085. break L2
  1086. }
  1087. nextcol += vtd.Colspan
  1088. if filter_zbdw_v2.MatchString(vtd.Val) {
  1089. arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
  1090. if arrbo == nil {
  1091. arrbo = []map[string]interface{}{}
  1092. td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
  1093. }
  1094. a1 := arrbo.([]map[string]interface{})
  1095. a1 = append(a1, map[string]interface{}{
  1096. "entname": vtd.Val,
  1097. "sortstr": td.Val,
  1098. "sort": GetBidSort(td.Val, n),
  1099. })
  1100. res = true
  1101. td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
  1102. }
  1103. }
  1104. }
  1105. } else {
  1106. rtd := td.TR.Table.GetTdByRCNo(td.StartRow, td.EndCol+1)
  1107. btd := td.TR.Table.GetTdByRCNo(td.EndRow+1, td.StartCol)
  1108. //if ((rtd != nil && !rtd.BH && rtd.Valtype == "BO") || direct == 1) && btd != nil && filter_zbdw_v.MatchString(btd.Val) {
  1109. if ((rtd != nil && !rtd.BH) || direct == 1) && btd != nil && filter_zbdw_v2.MatchString(btd.Val) {
  1110. d = 1
  1111. arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
  1112. if arrbo == nil {
  1113. arrbo = []map[string]interface{}{}
  1114. td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
  1115. }
  1116. a1 := arrbo.([]map[string]interface{})
  1117. a1 = append(a1, map[string]interface{}{
  1118. "entname": btd.Val,
  1119. "sortstr": td.Val,
  1120. "sort": GetBidSort(td.Val, n),
  1121. })
  1122. res = true
  1123. td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
  1124. //} else if ((btd != nil && !btd.BH && btd.Valtype == "BO") || direct == 2) && rtd != nil && filter_zbdw_v.MatchString(rtd.Val) {
  1125. } else if ((btd != nil && !btd.BH) || direct == 2) && rtd != nil && filter_zbdw_v2.MatchString(rtd.Val) {
  1126. d = 2
  1127. arrbo := td.TR.Table.SortKV.Map[NullTxtBid]
  1128. if arrbo == nil {
  1129. arrbo = []map[string]interface{}{}
  1130. td.TR.Table.SortKV.AddKey(NullTxtBid, arrbo)
  1131. }
  1132. a1 := arrbo.([]map[string]interface{})
  1133. a1 = append(a1, map[string]interface{}{
  1134. "entname": rtd.Val,
  1135. "sortstr": td.Val,
  1136. "sort": GetBidSort(td.Val, n),
  1137. })
  1138. res = true
  1139. td.TR.Table.SortKV.AddKey(NullTxtBid, a1)
  1140. }
  1141. }
  1142. return
  1143. }
  1144. func GetBidSort(str string, n int) int {
  1145. val := n
  1146. if strings.Index(str, "首选") > -1 {
  1147. val = 1
  1148. } else {
  1149. val = winnerOrderEntity.toNumber(str, n)
  1150. }
  1151. return val
  1152. }