remark.go 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. package front
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/shopspring/decimal"
  6. "go.mongodb.org/mongo-driver/bson"
  7. "math"
  8. mgo "mongodb"
  9. qu "qfw/util"
  10. "sort"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "util"
  15. )
  16. func (f *Front) RemarkList() {
  17. qu.Catch()
  18. pid := qu.ObjToString(f.GetString("pid"))
  19. tid := qu.ObjToString(f.GetString("tid"))
  20. sourceinfo := qu.ObjToString(f.GetString("s_sourceinfo"))
  21. if f.Method() == "POST" {
  22. //user := f.GetSession("user").(map[string]interface{})
  23. start, _ := f.GetInteger("start")
  24. limit, _ := f.GetInteger("length")
  25. draw, _ := f.GetInteger("draw")
  26. searchStr := f.GetString("search[value]")
  27. search := strings.TrimSpace(searchStr)
  28. query := map[string]interface{}{"s_usertaskid": tid}
  29. ckdata, err := f.GetInteger("i_ckdata")
  30. if err != nil {
  31. ckdata = -1
  32. }
  33. if ckdata == 0 {
  34. query["b_istag"] = false
  35. } else if ckdata == 1 {
  36. query["b_istag"] = true
  37. }
  38. if search != "" {
  39. query["$or"] = []interface{}{
  40. bson.M{"v_baseinfo.title": bson.M{"$regex": search}},
  41. }
  42. }
  43. qu.Debug(query)
  44. field := map[string]interface{}{"v_baseinfo.title": 1, "b_istag": 1, "i_ckdata": 1}
  45. info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, field, false, start, limit)
  46. count := util.Mgo.Count(sourceinfo, query)
  47. qu.Debug(query, sourceinfo, count)
  48. f.ServeJson(map[string]interface{}{
  49. "draw": draw,
  50. "data": *info,
  51. "recordsFiltered": count,
  52. "recordsTotal": count,
  53. })
  54. } else {
  55. f.T["pid"] = pid
  56. f.T["tid"] = tid
  57. f.T["s_sourceinfo"] = sourceinfo
  58. _ = f.Render("project/remark_list.html", &f.T)
  59. }
  60. }
  61. func (f *Front) RemarkDetail() {
  62. pid := f.GetString("pid")
  63. tid := f.GetString("tid")
  64. did := f.GetString("did")
  65. coll := f.GetString("s_sourceinfo")
  66. project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, `{"v_fields": 1}`)
  67. if len(*project) > 0 {
  68. field := make(map[string]bool)
  69. vf := (*project)["v_fields"].(map[string]interface{})
  70. for k := range vf {
  71. field[k] = true
  72. }
  73. f.T["fields"] = field
  74. }
  75. qu.Debug(pid, did, coll)
  76. rep := getDetail(did, coll) //获取本条公告的信息
  77. f.T["otherInfo"] = rep["otherInfo"] //展示关联公告信息
  78. f.T["moreInfo"] = rep["moreInfo"] //更多关联公告信息
  79. f.T["pid"] = pid
  80. f.T["tid"] = tid
  81. f.T["did"] = did
  82. f.T["coll"] = coll
  83. f.T["info"] = rep["info"]
  84. f.T["common"] = rep["common"]
  85. f.T["worder"] = rep["worder"]
  86. f.T["packs"] = rep["packs"]
  87. f.T["packskey"] = rep["packskey"]
  88. f.T["ck_pclistag"] = rep["purchasingTag"]
  89. f.T["timeplace"] = rep["timeplace"]
  90. f.T["purchasinglist"] = rep["purchasinglist"]
  91. f.T["other"] = rep["other"]
  92. f.T["PurchasinglistField"] = util.PurchasinglistField
  93. f.T["WinnerorderField"] = util.WinnerorderField
  94. f.T["PackageField"] = util.PackageField
  95. f.T["topsubtype"] = util.TopSubStypeArr2
  96. f.T["ck_purchasinglist"] = rep["ck_purchasinglist"]
  97. f.T["ck_package"] = rep["ck_package"]
  98. f.T["ck_winnerorder"] = rep["ck_winnerorder"]
  99. f.T["worder_new"] = rep["worder_new"]
  100. f.T["pcl_new"] = rep["pcl_new"]
  101. f.T["pkg_new"] = rep["pkg_new"]
  102. f.T["nextid"] = GetNextDataId(did, coll, tid) //下一条id
  103. _ = f.Render("project/remark_detail.html", &f.T)
  104. }
  105. func getDetail(id, coll string) map[string]interface{} {
  106. rep := map[string]interface{}{}
  107. infoTmp, _ := util.Mgo.FindById(coll, id, ``)
  108. baseInfo := (*infoTmp)["v_baseinfo"].(map[string]interface{}) //字段值
  109. var bzInfo map[string]interface{} //标注信息
  110. if (*infoTmp)["v_taginfo"] != nil {
  111. bzInfo = (*infoTmp)["v_taginfo"].(map[string]interface{})
  112. } else {
  113. bzInfo = make(map[string]interface{})
  114. }
  115. baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + qu.ObjToString(baseInfo["detail"])
  116. baseInfo["_id"] = mgo.BsonIdToSId(baseInfo["_id"])
  117. purchasingTag, _ := baseInfo["purchasinglist_alltag"].(bool)
  118. rep["purchasingTag"] = purchasingTag
  119. href := qu.ObjToString(baseInfo["href"])
  120. if !strings.HasPrefix(href, "http") {
  121. baseInfo["href"] = "https://" + href
  122. }
  123. rep["info"] = baseInfo
  124. common, timeplace, other := setExtComMap(baseInfo, bzInfo) //拼装抽取common值
  125. rep["common"] = common
  126. rep["timeplace"] = timeplace
  127. rep["other"] = other
  128. packs, packskey, pkg_new := setPaceMap(baseInfo) //拼装子包信息
  129. rep["packs"] = packs
  130. rep["packskey"] = packskey
  131. rep["pkg_new"] = pkg_new
  132. purchasinglist, isNewStatus := setPurchasingMap(baseInfo) //标的物
  133. rep["purchasinglist"] = purchasinglist
  134. rep["pcl_new"] = isNewStatus
  135. worder, worder_new := setWorderMap(baseInfo) //中标候选人
  136. rep["worder"] = worder
  137. rep["worder_new"] = worder_new
  138. otherInfo, moreInfo := setOtherInfo(baseInfo) //处理公告关联信息
  139. rep["otherInfo"] = otherInfo
  140. rep["moreInfo"] = moreInfo
  141. //
  142. if bzInfo["purchasinglist"] != nil {
  143. rep["ck_purchasinglist"] = "1"
  144. } else {
  145. rep["ck_purchasinglist"] = "-1"
  146. }
  147. if bzInfo["package"] != nil {
  148. rep["ck_package"] = "1"
  149. } else {
  150. rep["ck_package"] = "-1"
  151. }
  152. if bzInfo["winnerorder"] != nil {
  153. rep["ck_winnerorder"] = "1"
  154. } else {
  155. rep["ck_winnerorder"] = "-1"
  156. }
  157. return rep
  158. }
  159. //拼装抽取common值
  160. func setExtComMap(info, bzInfo map[string]interface{}) ([]interface{}, []interface{}, []interface{}) {
  161. //基本参数
  162. common, _ := util.BiaoZhu["common"].([]interface{})
  163. for k, tmp := range common {
  164. if cp, ok := tmp.(map[string]interface{}); ok {
  165. if info[fmt.Sprint(cp["key"])] == nil {
  166. cp["value"] = ""
  167. } else {
  168. if cp["key"] == "subtype" {
  169. if info["toptype"] != nil && info["subtype"] != nil {
  170. cp["value"] = qu.ObjToString(info["toptype"]) + "-" + qu.ObjToString(info[fmt.Sprint(cp["key"])])
  171. } else {
  172. cp["value"] = ""
  173. }
  174. } else {
  175. cp["value"] = info[fmt.Sprint(cp["key"])]
  176. }
  177. }
  178. if bzInfo[fmt.Sprint(cp["key"])] == nil {
  179. cp["status"] = "-1"
  180. } else {
  181. cp["status"] = "1"
  182. }
  183. common[k] = cp
  184. }
  185. }
  186. //时间地点信息
  187. timeplace, _ := util.BiaoZhu["timeplace"].([]interface{})
  188. for k, tmp := range timeplace {
  189. if tp, ok := tmp.(map[string]interface{}); ok {
  190. if info[fmt.Sprint(tp["key"])] == nil {
  191. tp["value"] = ""
  192. } else {
  193. key := tp["key"]
  194. if key == "bidopentime" || key == "publishtime" || key == "bidendtime" || key == "project_startdate" || key == "project_completedate" {
  195. tmpTime := qu.Int64All(info[fmt.Sprint(tp["key"])])
  196. if tmpTime > 0 {
  197. tp["value"] = qu.FormatDateByInt64(&tmpTime, qu.Date_Full_Layout)
  198. } else {
  199. tp["value"] = info[qu.ObjToString(tp["key"])]
  200. }
  201. } else {
  202. tp["value"] = info[fmt.Sprint(tp["key"])]
  203. }
  204. }
  205. if bzInfo[fmt.Sprint(tp["key"])] == nil {
  206. tp["status"] = "-1"
  207. } else {
  208. tp["status"] = "1"
  209. }
  210. timeplace[k] = tp
  211. }
  212. }
  213. //other信息
  214. other, _ := util.BiaoZhu["other"].([]interface{})
  215. for k, tmp := range other {
  216. if cp, ok := tmp.(map[string]interface{}); ok {
  217. if info[fmt.Sprint(cp["key"])] == nil {
  218. cp["value"] = ""
  219. } else {
  220. if cp["key"] == "signaturedate" {
  221. bidopentime := qu.Int64All(info[fmt.Sprint(cp["key"])])
  222. if bidopentime > 0 {
  223. cp["value"] = qu.FormatDateByInt64(&bidopentime, qu.Date_Full_Layout)
  224. } else {
  225. cp["value"] = info[qu.ObjToString(cp["key"])]
  226. }
  227. } else {
  228. cp["value"] = info[fmt.Sprint(cp["key"])]
  229. }
  230. }
  231. //log.Println(cp)
  232. if bzInfo[fmt.Sprint(cp["key"])] == nil {
  233. cp["status"] = "-1"
  234. } else {
  235. cp["status"] = "1"
  236. }
  237. other[k] = cp
  238. }
  239. }
  240. return common, timeplace, other
  241. }
  242. //拼装子包信息
  243. func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string, []bool) {
  244. var confpack []interface{}
  245. confpack, _ = util.BiaoZhu["package"].([]interface{})
  246. //bzpack := bzInfo["package"].(map[string]interface{})
  247. packs := map[string]map[string]interface{}{}
  248. var sortpackskey []string
  249. isNewPkg := map[string]bool{} //记录子包是否是新增的
  250. if packages, ok := info["package"].(map[string]interface{}); ok && len(packages) > 0 {
  251. for k, tmpackage := range packages { //遍历分包
  252. if tmppack, ok := tmpackage.(map[string]interface{}); ok {
  253. //isNew, _ := tmppack["isnew"].(bool)
  254. isNew := false
  255. status := "-1"
  256. if tmppack["package_son"] != nil {
  257. status = "1"
  258. }
  259. isNewPkg[k] = isNew
  260. sortpackskey = append(sortpackskey, k)
  261. var pack []interface{}
  262. for _, cpack := range confpack {
  263. cpack, _ := cpack.(map[string]interface{})
  264. key := qu.ObjToString(cpack["key"])
  265. if key == "winner" || key == "bidamount" { //中标单位和中标金额winner_all特殊处理
  266. continue
  267. }
  268. tp := map[string]interface{}{
  269. "key": key,
  270. "descript": cpack["descript"],
  271. }
  272. if tmppack[fmt.Sprint(tp["key"])] != nil {
  273. tp["value"] = tmppack[qu.ObjToString(tp["key"])]
  274. } else {
  275. tp["value"] = ""
  276. }
  277. tp["status"] = status
  278. pack = append(pack, tp)
  279. }
  280. //特殊处理中标单位和中标金额
  281. winnerall := []interface{}{}
  282. if tmpWinnerAll, ok := tmppack["winner_all"].([]interface{}); ok && len(tmpWinnerAll) > 0 {
  283. for _, tmp := range tmpWinnerAll {
  284. tmpMap := tmp.(map[string]interface{})
  285. win := map[string]interface{}{
  286. "descript": "标段(包)中标单位",
  287. "key": "winner",
  288. "status": status,
  289. "value": qu.ObjToString(tmpMap["winner"]),
  290. }
  291. winnerall = append(winnerall, win)
  292. var bidamount interface{}
  293. if tmpMap["bidamount"] == nil {
  294. bidamount = ""
  295. } else {
  296. bidamount = strconv.FormatFloat(qu.Float64All(tmpMap["bidamount"]), 'f', -1, 64)
  297. }
  298. bid := map[string]interface{}{
  299. "descript": "标段(包)中标金额",
  300. "key": "bidamount",
  301. "status": status,
  302. "value": bidamount,
  303. }
  304. winnerall = append(winnerall, bid)
  305. }
  306. } else {
  307. winnerall = append(winnerall, map[string]interface{}{
  308. "descript": "标段(包)中标单位",
  309. "key": "winner",
  310. "status": "-1",
  311. "value": "",
  312. })
  313. winnerall = append(winnerall, map[string]interface{}{
  314. "descript": "标段(包)中标金额",
  315. "key": "bidamount",
  316. "status": "-1",
  317. "value": "",
  318. })
  319. }
  320. packs[k] = map[string]interface{}{
  321. "pack": pack,
  322. "packstatus": status,
  323. "winnerall": winnerall,
  324. }
  325. }
  326. }
  327. }
  328. sort.Strings(sortpackskey)
  329. var packages []map[string]interface{}
  330. var isNewPkgArr []bool
  331. for _, v := range sortpackskey {
  332. packages = append(packages, packs[v])
  333. isNewPkgArr = append(isNewPkgArr, isNewPkg[v])
  334. }
  335. return packages, sortpackskey, isNewPkgArr
  336. }
  337. //拼装标的物
  338. func setPurchasingMap(info map[string]interface{}) ([]interface{}, []map[string]interface{}) {
  339. purchasinglist, _ := util.BiaoZhu["purchasinglist"].([]interface{})
  340. var purchasinglists []interface{}
  341. //isNewPcl := []bool{} //记录子包是否是新增的
  342. var isNewAndStatus []map[string]interface{}
  343. if tmpcls, ok := info["purchasinglist"].([]interface{}); ok {
  344. for _, v := range tmpcls {
  345. if pcl, ok := v.(map[string]interface{}); ok {
  346. //isNew, _ := pcl["isnew"].(bool)
  347. isNew := false
  348. status := "-1"
  349. if pcl["purchasinglist_son"] != nil {
  350. status = "1"
  351. }
  352. //isNewPcl = append(isNewPcl, isNew)
  353. isNewAndStatus = append(isNewAndStatus, map[string]interface{}{"isnew": isNew, "status": status})
  354. var pcls []interface{}
  355. for _, ps := range purchasinglist {
  356. ps, _ := ps.(map[string]interface{})
  357. value := pcl[qu.ObjToString(ps["key"])]
  358. if value == nil {
  359. value = ""
  360. }
  361. tp := map[string]interface{}{
  362. "key": ps["key"],
  363. "descript": ps["descript"],
  364. "value": value,
  365. "status": status,
  366. }
  367. // if pcl[preKey+fmt.Sprint(tp["key"])] == nil {
  368. // tp["status"] = "-1"
  369. // } else {
  370. // tp["status"] = "1"
  371. // }
  372. pcls = append(pcls, tp)
  373. }
  374. purchasinglists = append(purchasinglists, pcls)
  375. }
  376. }
  377. }
  378. return purchasinglists, isNewAndStatus
  379. }
  380. //拼装中标候选人
  381. func setWorderMap(info map[string]interface{}) ([]interface{}, []map[string]interface{}) {
  382. //基本参数--中标候选人
  383. winnerorder, _ := util.BiaoZhu["winnerorder"].([]interface{})
  384. worders := []interface{}{}
  385. isNewAndStatus := []map[string]interface{}{}
  386. if tmpwds, ok := info["winnerorder"].([]interface{}); ok {
  387. for _, v := range tmpwds {
  388. if wd, ok := v.(map[string]interface{}); ok {
  389. //isNew, _ := wd["isnew"].(bool)
  390. isNew := false
  391. status := "-1"
  392. if wd["winnerorder_son"] != nil {
  393. status = "1"
  394. }
  395. isNewAndStatus = append(isNewAndStatus, map[string]interface{}{"isnew": isNew, "status": status})
  396. wds := []interface{}{}
  397. for _, cp := range winnerorder {
  398. cp, _ := cp.(map[string]interface{})
  399. value := wd[qu.ObjToString(cp["key"])]
  400. if value == nil {
  401. value = ""
  402. }
  403. tp := map[string]interface{}{
  404. "key": cp["key"],
  405. "descript": cp["descript"],
  406. "value": value,
  407. "status": status,
  408. }
  409. wds = append(wds, tp)
  410. }
  411. worders = append(worders, wds)
  412. }
  413. }
  414. }
  415. return worders, isNewAndStatus
  416. }
  417. //获取公告关联信息
  418. func setOtherInfo(info map[string]interface{}) (result, moreArr []map[string]interface{}) {
  419. if otherInfo, ok := info["info"].([]interface{}); ok && len(otherInfo) > 0 {
  420. //中标,成交、合同、招标(不含变更)
  421. /*
  422. [
  423. {},
  424. {},
  425. ]
  426. */
  427. zbArr := []map[string]interface{}{}
  428. cjArr := []map[string]interface{}{}
  429. htArr := []map[string]interface{}{}
  430. zbbArr := []map[string]interface{}{}
  431. for _, tmp := range otherInfo {
  432. tmpInfo := tmp.(map[string]interface{})
  433. tmpInfo["detail"] = qu.ObjToString(tmpInfo["title"]) + "</br>" + qu.ObjToString(tmpInfo["title"])
  434. toptype := tmpInfo["toptype"]
  435. subtype := tmpInfo["subtype"]
  436. ptime := ""
  437. tmpPtime := qu.Int64All(tmpInfo["publishtime"])
  438. if tmpPtime > 0 {
  439. ptime = qu.FormatDateByInt64(&tmpPtime, qu.Date_Full_Layout)
  440. }
  441. tmpInfo["publishtime_str"] = ptime
  442. if subtype == "中标" {
  443. zbArr = append(zbArr, tmpInfo)
  444. } else if subtype == "成交" {
  445. cjArr = append(cjArr, tmpInfo)
  446. } else if subtype == "合同" {
  447. htArr = append(htArr, tmpInfo)
  448. } else if toptype == "招标" && subtype != "变更" {
  449. zbbArr = append(zbbArr, tmpInfo)
  450. } else { //标注页不展示的信息,更多中展示
  451. moreArr = append(moreArr, map[string]interface{}{
  452. "publishtime": tmpInfo["publishtime_str"],
  453. "subtype": subtype,
  454. "title": tmpInfo["title"],
  455. "href": util.GetJyHref(qu.ObjToString(tmpInfo["id"])),
  456. })
  457. }
  458. }
  459. publishtime := qu.Float64All(info["publishtime"])
  460. //中标信息
  461. if zbLen := len(zbArr); zbLen > 0 {
  462. rzb := DealData(zbLen, publishtime, zbArr, &moreArr)
  463. result = append(result, rzb)
  464. }
  465. //成交
  466. if cjLen := len(cjArr); cjLen > 0 {
  467. rcj := DealData(cjLen, publishtime, cjArr, &moreArr)
  468. result = append(result, rcj)
  469. }
  470. //合同
  471. if htLen := len(htArr); htLen > 0 {
  472. rht := DealData(htLen, publishtime, htArr, &moreArr)
  473. result = append(result, rht)
  474. }
  475. result = append(result, zbbArr...)
  476. }
  477. return
  478. }
  479. func DealData(tmpLen int, publishtime float64, tmp []map[string]interface{}, moreArr *[]map[string]interface{}) (resultTmp map[string]interface{}) {
  480. if tmpLen == 1 || publishtime <= 0 { //相同类型只有一条或者原公告发布时间异常取第一条公告
  481. resultTmp = tmp[0]
  482. for _, t := range tmp[1:] { //将过滤掉的数据加入到更多中
  483. *moreArr = append(*moreArr, map[string]interface{}{
  484. "publishtime": t["publishtime_str"],
  485. "subtype": t["subtype"],
  486. "title": t["title"],
  487. "href": util.GetJyHref(qu.ObjToString(t["id"])),
  488. })
  489. }
  490. return
  491. } else {
  492. diff := float64(0) //记录差值
  493. index := 0
  494. for i, zb := range tmp {
  495. pTmp := qu.Float64All(zb["publishtime"])
  496. diffTmp := math.Abs(publishtime - pTmp) //绝对值
  497. if i == 0 {
  498. diff = diffTmp
  499. } else if diffTmp < diff { //记录较小差值的数据索引位置
  500. diff = diffTmp
  501. index = i
  502. } else { //将过滤掉的数据加入到更多中
  503. *moreArr = append(*moreArr, map[string]interface{}{
  504. "publishtime": zb["publishtime_str"],
  505. "subtype": zb["subtype"],
  506. "title": zb["title"],
  507. "href": util.GetJyHref(qu.ObjToString(zb["id"])),
  508. })
  509. }
  510. }
  511. resultTmp = tmp[index]
  512. }
  513. return
  514. }
  515. // GetNextDataId 获取当前数据下一条的id
  516. func GetNextDataId(id, coll, tid string) string {
  517. nextIdQuery := map[string]interface{}{
  518. "_id": map[string]interface{}{
  519. "$gt": mgo.StringTOBsonId(id),
  520. },
  521. }
  522. if tid != "" {
  523. nextIdQuery["s_usertaskid"] = tid
  524. }
  525. one, _ := util.Mgo.Find(coll, nextIdQuery, `{"_id":1}`, `{"_id":1}`, true, 0, 1)
  526. if len(*one) == 1 && len((*one)[0]) > 0 {
  527. return mgo.BsonIdToSId((*one)[0]["_id"])
  528. } else {
  529. delete(nextIdQuery, "_id")
  530. one, _ = util.Mgo.Find(coll, nextIdQuery, `{"_id":1}`, `{"_id":1}`, true, 0, 1)
  531. if len(*one) == 1 && len((*one)[0]) > 0 {
  532. return mgo.BsonIdToSId((*one)[0]["_id"])
  533. }
  534. }
  535. return id
  536. }
  537. // GetNextDataId1 质检下一条
  538. func GetNextDataId1(id, coll, tid string) string {
  539. nextIdQuery := map[string]interface{}{
  540. "_id": map[string]interface{}{
  541. "$gt": mgo.StringTOBsonId(id),
  542. },
  543. }
  544. if tid != "" {
  545. // 数据有任务 查询带上标注标记
  546. nextIdQuery["i_ckdata"] = 2
  547. nextIdQuery["s_usertaskid"] = tid
  548. } else {
  549. nextIdQuery["i_ckdata"] = 2
  550. }
  551. qu.Debug(nextIdQuery, coll)
  552. one, _ := util.Mgo.Find(coll, nextIdQuery, `{"_id":1}`, `{"_id":1}`, true, 0, 1)
  553. if len(*one) == 1 && len((*one)[0]) > 0 {
  554. return mgo.BsonIdToSId((*one)[0]["_id"])
  555. } else {
  556. delete(nextIdQuery, "_id")
  557. one, _ = util.Mgo.Find(coll, nextIdQuery, `{"_id":1}`, `{"_id":1}`, true, 0, 1)
  558. if len(*one) == 1 && len((*one)[0]) > 0 {
  559. return mgo.BsonIdToSId((*one)[0]["_id"])
  560. }
  561. }
  562. return id
  563. }
  564. func (f *Front) CheckList() {
  565. qu.Catch()
  566. if f.Method() == "POST" {
  567. user := f.GetSession("user").(map[string]interface{})
  568. iRole := qu.ObjToString(user["i_role"])
  569. gid := qu.ObjToString(user["s_groupid"])
  570. start, _ := f.GetInteger("start")
  571. limit, _ := f.GetInteger("length")
  572. draw, _ := f.GetInteger("draw")
  573. status := f.GetString("s_status")
  574. searchStr := f.GetString("search[value]")
  575. search := strings.TrimSpace(searchStr)
  576. query := map[string]interface{}{
  577. "s_stype": "user",
  578. }
  579. if iRole != "0" {
  580. query["s_groupid"] = gid
  581. }
  582. if status != "-1" { //任务状态
  583. query["s_status"] = status
  584. }
  585. if search != "" {
  586. query["$or"] = []interface{}{
  587. map[string]interface{}{"s_projectname": map[string]interface{}{"$regex": search}},
  588. }
  589. }
  590. qu.Debug("Query:", query)
  591. count := util.Mgo.Count(util.TASKCOLLNAME, query)
  592. list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, start, limit)
  593. for _, l := range *list {
  594. if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
  595. giveNum := qu.IntAll(l["i_givenum"])
  596. sourceinfo := qu.ObjToString(l["s_sourceinfo"])
  597. tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_usertaskid": mgo.BsonIdToSId(l["_id"]), "b_istag": true})
  598. progressFloat := float64(tagNum) / float64(giveNum)
  599. value, _ := strconv.ParseFloat(fmt.Sprintf("%.4f", progressFloat), 64)
  600. progress := fmt.Sprint(value*100) + "%"
  601. l["s_progress"] = progress
  602. }
  603. }
  604. f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
  605. } else {
  606. _ = f.Render("project/check_task_list.html")
  607. }
  608. }
  609. func (f *Front) CheckData() {
  610. qu.Catch()
  611. pid := f.GetString("pid")
  612. tid := f.GetString("tid")
  613. stype := f.GetString("stype")
  614. sourceinfo := f.GetString("s_sourceinfo")
  615. datatype, _ := f.GetInteger("datatype")
  616. if f.Method() == "POST" {
  617. start, _ := f.GetInteger("start")
  618. limit, _ := f.GetInteger("length")
  619. draw, _ := f.GetInteger("draw")
  620. searchStr := f.GetString("search[value]")
  621. search := strings.TrimSpace(searchStr)
  622. query := make(map[string]interface{})
  623. if tid != "" {
  624. // 任务数据质检
  625. if stype == "group" {
  626. query["s_grouptaskid"] = tid
  627. } else {
  628. query["s_usertaskid"] = tid
  629. }
  630. query["b_istag"] = true
  631. } else {
  632. if stype == "notag" {
  633. if datatype == 1 {
  634. // 待分发数据
  635. query["b_isgivegroup"] = false
  636. query["b_istagging"] = false
  637. } else {
  638. // 标注数据
  639. query["i_ckdata"] = 2
  640. query["b_isgivegroup"] = false
  641. }
  642. } else if stype == "tag" {
  643. query["b_istagging"] = true //未达标
  644. query["i_ckdata"] = 2
  645. } else {
  646. query["i_ckdata"] = 2
  647. }
  648. }
  649. ckdata, err := f.GetInteger("i_ckdata")
  650. if err != nil {
  651. ckdata = -1
  652. }
  653. if ckdata == 0 {
  654. query["b_istag"] = false
  655. } else if ckdata == 1 {
  656. query["b_istag"] = true
  657. }
  658. if search != "" {
  659. query["$or"] = []interface{}{
  660. map[string]interface{}{"v_baseinfo.title": map[string]interface{}{"$regex": search}},
  661. }
  662. }
  663. qu.Debug("Query:", query)
  664. fields := map[string]interface{}{"v_baseinfo.title": 1, "b_check": 1, "i_ckdata": 1, "s_login": 1}
  665. info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, fields, false, start, limit)
  666. count := util.Mgo.Count(sourceinfo, query)
  667. qu.Debug(query, sourceinfo, count)
  668. f.ServeJson(map[string]interface{}{
  669. "draw": draw,
  670. "data": *info,
  671. "recordsFiltered": count,
  672. "recordsTotal": count,
  673. })
  674. } else {
  675. if tid == "" {
  676. //project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"i_importnum": 1})
  677. //f.T["taskNum"] = (*project)["i_importnum"]
  678. query1 := make(map[string]interface{})
  679. if stype == "all" {
  680. query1["i_ckdata"] = 2
  681. } else if stype == "notag" {
  682. if datatype == 1 {
  683. // 待分发数据
  684. query1["b_isgivegroup"] = false
  685. query1["b_istagging"] = false
  686. } else {
  687. // 标注数据
  688. query1["i_ckdata"] = 2
  689. query1["b_isgivegroup"] = false
  690. }
  691. } else if stype == "tag" {
  692. query1["b_istagging"] = true //未达标
  693. query1["i_ckdata"] = 2
  694. } else {
  695. query1["i_ckdata"] = 2
  696. }
  697. qu.Debug(sourceinfo, query1)
  698. f.T["taskNum"] = util.Mgo.Count(sourceinfo, query1)
  699. query1["b_check"] = true // 已质检
  700. checkCount := util.Mgo.Count(sourceinfo, query1)
  701. f.T["taskTagNum"] = 0
  702. f.T["taskCheckNum"] = checkCount
  703. } else {
  704. task, _ := util.Mgo.FindById(util.TASKCOLLNAME, tid, map[string]interface{}{"i_givenum": 1})
  705. f.T["taskNum"] = (*task)["i_givenum"]
  706. tagCount, checkCount := 0, 0
  707. if stype == "group" {
  708. tagCount = util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": tid, "b_istag": true})
  709. checkCount = util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": tid, "b_check": true})
  710. } else {
  711. tagCount = util.Mgo.Count(sourceinfo, map[string]interface{}{"s_usertaskid": tid, "b_istag": true})
  712. checkCount = util.Mgo.Count(sourceinfo, map[string]interface{}{"s_usertaskid": tid, "b_check": true})
  713. }
  714. f.T["taskTagNum"] = tagCount
  715. f.T["taskCheckNum"] = checkCount
  716. }
  717. f.T["pid"] = pid
  718. f.T["tid"] = tid
  719. f.T["sourceinfo"] = sourceinfo
  720. f.T["stype"] = stype
  721. f.T["datatype"] = datatype
  722. _ = f.Render("project/check_data_list.html", &f.T)
  723. }
  724. }
  725. func (f *Front) CheckDetail() {
  726. qu.Catch()
  727. tid := f.GetString("tid")
  728. pid := f.GetString("pid")
  729. did := f.GetString("did")
  730. coll := f.GetString("s_sourceinfo")
  731. project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, `{"v_fields": 1}`)
  732. if len(*project) > 0 {
  733. field := make(map[string]bool)
  734. vf := (*project)["v_fields"].(map[string]interface{})
  735. for k := range vf {
  736. field[k] = true
  737. }
  738. f.T["fields"] = field
  739. }
  740. qu.Debug(pid, did, coll)
  741. rep := getDetail(did, coll) //获取本条公告的信息
  742. f.T["otherInfo"] = rep["otherInfo"] //展示关联公告信息
  743. f.T["moreInfo"] = rep["moreInfo"] //更多关联公告信息
  744. f.T["pid"] = pid
  745. f.T["tid"] = tid
  746. f.T["did"] = did
  747. f.T["coll"] = coll
  748. f.T["info"] = rep["info"]
  749. f.T["common"] = rep["common"]
  750. f.T["worder"] = rep["worder"]
  751. f.T["packs"] = rep["packs"]
  752. f.T["packskey"] = rep["packskey"]
  753. f.T["ck_pclistag"] = rep["purchasingTag"]
  754. f.T["timeplace"] = rep["timeplace"]
  755. f.T["purchasinglist"] = rep["purchasinglist"]
  756. f.T["other"] = rep["other"]
  757. f.T["PurchasinglistField"] = util.PurchasinglistField
  758. f.T["WinnerorderField"] = util.WinnerorderField
  759. f.T["PackageField"] = util.PackageField
  760. f.T["topsubtype"] = util.TopSubStypeArr2
  761. f.T["ck_purchasinglist"] = rep["ck_purchasinglist"]
  762. f.T["ck_package"] = rep["ck_package"]
  763. f.T["ck_winnerorder"] = rep["ck_winnerorder"]
  764. f.T["worder_new"] = rep["worder_new"]
  765. f.T["pcl_new"] = rep["pcl_new"]
  766. f.T["pkg_new"] = rep["pkg_new"]
  767. f.T["nextid"] = GetNextDataId1(did, coll, tid) //下一条id
  768. _ = f.Render("project/check_detail.html", &f.T)
  769. }
  770. func (f *Front) CheckSave() {
  771. defer qu.Catch()
  772. success := false
  773. msg := ""
  774. user := f.GetSession("user").(map[string]interface{})
  775. username := qu.ObjToString(user["s_login"]) //当前登录用户
  776. userId := qu.ObjToString(user["id"]) //当前登录用户标识
  777. userRole := qu.ObjToString(user["i_role"]) //当前登录用户权限
  778. var obj []map[string]interface{}
  779. infoId := f.GetString("s_infoid")
  780. sourceInfo := f.GetString("s_sourceinfo")
  781. pid := f.GetString("pid")
  782. qu.Debug("Data ID:", infoId)
  783. project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"s_name": 1, "v_fields": 1})
  784. data := f.GetString("data")
  785. err := json.Unmarshal([]byte(data), &obj)
  786. if err != nil {
  787. qu.Debug("Json Unmarshal Error")
  788. f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
  789. return
  790. }
  791. tagSet := map[string]interface{}{} //被标注字段状态
  792. baseSet := map[string]interface{}{} //要修改的字段信息
  793. baseUnset := map[string]interface{}{} //要删除的字段信息
  794. if len(obj) == 1 { //单独保存某个一级
  795. content, ok := obj[0]["content"].([]interface{})
  796. if !ok || len(content) == 0 {
  797. f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
  798. return
  799. }
  800. title := qu.ObjToString(obj[0]["title"])
  801. istag, _ := obj[0]["checkAllTag"].(bool)
  802. status := qu.IntAll(obj[0]["status"])
  803. switch title {
  804. case "基本字段":
  805. MarkBase(content, tagSet, baseSet, baseUnset)
  806. case "时间地点":
  807. MarkTimePlace(content, tagSet, baseSet, baseUnset)
  808. case "标的信息":
  809. MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
  810. case "多包信息":
  811. MarkPackage(content, tagSet, baseSet, baseUnset, status)
  812. case "中标候选人信息":
  813. MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
  814. case "其余信息":
  815. MarkOther(content, tagSet, baseSet, baseUnset)
  816. }
  817. } else {
  818. for j, val := range obj {
  819. content, ok := val["content"].([]interface{})
  820. status := qu.IntAll(val["status"])
  821. if !ok {
  822. qu.Debug("Content Error")
  823. continue
  824. }
  825. istag, _ := val["checkAllTag"].(bool)
  826. if j == 0 { //基本信息
  827. MarkBase(content, tagSet, baseSet, baseUnset)
  828. } else if j == 1 { //时间地点
  829. MarkTimePlace(content, tagSet, baseSet, baseUnset)
  830. } else if j == 2 { //标的物
  831. MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
  832. } else if j == 3 { //多包
  833. MarkPackage(content, tagSet, baseSet, baseUnset, status)
  834. } else if j == 4 { //候选人
  835. MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
  836. } else { //其余信息
  837. MarkOther(content, tagSet, baseSet, baseUnset)
  838. }
  839. }
  840. }
  841. dataInfo, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1}) //查询标注保存前的原始信息
  842. tagInfo, _ := (*dataInfo)["v_taginfo"].(map[string]interface{})
  843. baseInfo, _ := (*dataInfo)["v_baseinfo"].(map[string]interface{})
  844. if tagInfo != nil && len(tagInfo) > 0 {
  845. for field, tmpStatus := range tagSet { //比对本次标注信息和历史标注信息
  846. status := qu.IntAll(tmpStatus) //此次被标注字段的状态
  847. markedStatus := qu.IntAll(tagInfo[field]) //历史标注状态
  848. if status == 1 && markedStatus != 0 { //此次标注结果为正确,且有历史标注记录,不做修改
  849. qu.Debug("已标注字段field---", field)
  850. //delete(tagSet, field)
  851. delete(baseSet, field)
  852. //continue
  853. }
  854. }
  855. }
  856. allTagFields := map[string]interface{}{} //记录此此标注所有标注信息,用于日志记录
  857. for k, _ := range tagSet {
  858. allTagFields[k] = true
  859. }
  860. for k, v := range baseSet {
  861. allTagFields[k] = v
  862. }
  863. for k, _ := range baseUnset {
  864. allTagFields[k] = nil
  865. }
  866. qu.Debug("allTagFields===", allTagFields)
  867. qu.Debug("tagSet===", tagSet)
  868. // 质检时,标注标记变成质检标记
  869. checkFields, _ := (*project)["v_fields"].(map[string]interface{})
  870. checkSet := make(map[string]interface{})
  871. for k := range checkFields {
  872. checkSet[k] = tagSet[k]
  873. }
  874. if len(checkSet) > 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
  875. //1、更新数据源信息
  876. setResult := map[string]interface{}{ //更新字段集
  877. "i_updatetime": time.Now().Unix(),
  878. "b_check": true,
  879. "s_checkid": userId,
  880. "b_istag": true,
  881. "b_isgivegroup": true,
  882. "b_isgiveuser": true,
  883. "s_userid": userId,
  884. }
  885. //for field, val := range tagSet { //更新质检字段
  886. // setResult["v_taginfo."+field] = val
  887. //}
  888. setResult["v_checkinfo"] = checkSet
  889. for field, val := range baseSet { //更新基本字段
  890. setResult["v_baseinfo."+field] = val
  891. }
  892. baseUnsetResult := map[string]interface{}{} //删除字段集
  893. for field, _ := range baseUnset { //删除基本字段
  894. baseUnsetResult["v_baseinfo."+field] = ""
  895. }
  896. set := map[string]interface{}{
  897. "$set": setResult,
  898. }
  899. if len(baseUnsetResult) > 0 {
  900. set["$unset"] = baseUnsetResult
  901. }
  902. qu.Debug("set---", set)
  903. success = util.Mgo.UpdateById(sourceInfo, infoId, set)
  904. //2、更新marked表
  905. tmp, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1, "i_ckdata": 1})
  906. qu.Debug("infoId:", infoId)
  907. delete(*tmp, "_id")
  908. (*tmp)["updatetime"] = time.Now().Unix()
  909. b := util.Mgo.Update(util.AllToColl, map[string]interface{}{"_id": mgo.StringTOBsonId(infoId)}, map[string]interface{}{"$set": tmp}, true, false)
  910. qu.Debug("Update Marked:", b)
  911. }
  912. //3、保存标注日志
  913. b := SaveLog(infoId, "", username, userId, userRole, qu.ObjToString((*project)["s_name"]), "质检", baseInfo, allTagFields)
  914. qu.Debug("Save Log:", b)
  915. f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
  916. }
  917. func (f *Front) CheckResult() {
  918. qu.Catch()
  919. pid := f.GetString("pid")
  920. tid := f.GetString("tid")
  921. sourceinfo := f.GetString("s_sourceinfo")
  922. stype := f.GetString("stype")
  923. datatype, _ := f.GetInteger("datatype")
  924. task, _ := util.Mgo.FindById(util.TASKCOLLNAME, tid, map[string]interface{}{"i_givenum": 1})
  925. projcet, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"v_fields": 1})
  926. //tagCount := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": tid, "b_istag": true})
  927. //checkCount := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": tid, "b_check": true})
  928. allNum := (*task)["i_givenum"] //任务数据量
  929. markNum, checkNum, checkNumR := 0, 0, 0 // 标注数量, 审核数据量, 审核数据完全正确的数据量
  930. cmaps := make(map[string]int) // 标注字段整体准确率
  931. umaps := make(map[string]interface{}) // 按人员 字段准确率
  932. for k := range (*projcet)["v_fields"].(map[string]interface{}) {
  933. cmaps[k] = 0
  934. }
  935. sess := util.Mgo.GetMgoConn()
  936. defer util.Mgo.DestoryMongoConn(sess)
  937. query := make(map[string]interface{})
  938. if tid == "" {
  939. query1 := make(map[string]interface{})
  940. if stype == "all" {
  941. query1["i_ckdata"] = 2
  942. } else if stype == "notag" {
  943. if datatype == 1 {
  944. // 待分发数据
  945. query1["b_isgivegroup"] = false
  946. query1["b_istagging"] = false
  947. } else {
  948. // 标注数据
  949. query1["i_ckdata"] = 2
  950. query1["b_isgivegroup"] = false
  951. }
  952. } else if stype == "tag" {
  953. query1["b_istagging"] = true //未达标
  954. query1["i_ckdata"] = 2
  955. }
  956. f.T["taskNum"] = util.Mgo.Count(sourceinfo, query1)
  957. } else {
  958. if stype == "group" {
  959. query["s_grouptaskid"] = tid
  960. } else {
  961. query["s_usertaskid"] = tid
  962. }
  963. }
  964. query["b_check"] = true
  965. qu.Debug(query)
  966. checkNum = util.Mgo.Count(sourceinfo, query)
  967. result := sess.DB(util.Mgo.DbName).C(sourceinfo).Find(query).Iter()
  968. if checkNum == 0 {
  969. f.ServeJson(map[string]interface{}{"rep": false, "msg": "无质检审核数据!"})
  970. return
  971. }
  972. for tmp := make(map[string]interface{}); result.Next(&tmp); markNum++ {
  973. user := qu.ObjToString(tmp["s_login"])
  974. var up map[string]int
  975. if umaps[user] == nil {
  976. up = make(map[string]int)
  977. } else {
  978. up = umaps[user].(map[string]int)
  979. }
  980. up["ck_count"] += 1
  981. umaps[user] = up
  982. if tmp["b_check"].(bool) {
  983. if f, ok := tmp["v_checkinfo"].(map[string]interface{}); ok {
  984. flag := true // 数据整体准确率
  985. // 按人员统计字段准备率
  986. var up map[string]int
  987. if umaps[user] == nil {
  988. up = make(map[string]int)
  989. } else {
  990. up = umaps[user].(map[string]int)
  991. }
  992. for k1 := range cmaps {
  993. if qu.IntAll(f[k1]) == 1 {
  994. cmaps[k1] += 1 // 字段整体正确率
  995. up[k1] += 1
  996. } else {
  997. flag = false
  998. }
  999. }
  1000. up["re_count"] += 1
  1001. umaps[user] = up
  1002. if flag {
  1003. checkNumR++
  1004. up["re_rg_count"] += 1
  1005. }
  1006. }
  1007. }
  1008. }
  1009. qu.Debug(cmaps)
  1010. qu.Debug(umaps)
  1011. // 前台页面数据
  1012. dataSource := make(map[string]interface{})
  1013. var userSelect []string
  1014. var dataSelect []map[string]interface{}
  1015. userSelect = append(userSelect, "全部")
  1016. tmp := make(map[string]interface{})
  1017. tmp["name"] = "全部"
  1018. tmp["num1"] = allNum
  1019. tmp["num2"] = checkNum
  1020. tmp["num3"] = checkNumR
  1021. tmp["num4"] = CountPr(checkNumR, checkNum)
  1022. dataSelect = append(dataSelect, tmp)
  1023. for k, v := range (*projcet)["v_fields"].(map[string]interface{}) {
  1024. tmp1 := make(map[string]interface{})
  1025. tmp1["name"] = v
  1026. tmp1["num1"] = markNum
  1027. tmp1["num2"] = checkNum
  1028. tmp1["num3"] = cmaps[k]
  1029. tmp1["num4"] = CountPr(cmaps[k], checkNum)
  1030. dataSelect = append(dataSelect, tmp1)
  1031. }
  1032. dataSource["全部"] = dataSelect
  1033. for k1, v1 := range umaps {
  1034. if v2, o := v1.(map[string]int); o {
  1035. userSelect = append(userSelect, k1)
  1036. var dataSelect1 []map[string]interface{}
  1037. tmp2 := make(map[string]interface{})
  1038. tmp2["name"] = "全部"
  1039. tmp2["num1"] = v2["ck_count"]
  1040. tmp2["num2"] = v2["re_count"]
  1041. tmp2["num3"] = v2["re_rg_count"]
  1042. tmp2["num4"] = CountPr(v2["re_rg_count"], v2["re_count"])
  1043. dataSelect1 = append(dataSelect1, tmp2)
  1044. for k, v := range (*projcet)["v_fields"].(map[string]interface{}) {
  1045. tmp1 := make(map[string]interface{})
  1046. tmp1["name"] = v
  1047. tmp1["num1"] = v2["ck_count"]
  1048. tmp1["num2"] = v2["re_count"]
  1049. tmp1["num3"] = v2[k]
  1050. tmp1["num4"] = CountPr(v2[k], v2["re_count"])
  1051. dataSelect1 = append(dataSelect1, tmp1)
  1052. }
  1053. dataSource[k1] = dataSelect1
  1054. }
  1055. }
  1056. f.T["pid"] = pid
  1057. f.T["tid"] = tid
  1058. f.T["taskNum"] = allNum
  1059. f.T["taskTagNum"] = markNum
  1060. f.T["taskCheckNum"] = checkNum
  1061. f.T["taskCheckRight"] = checkNumR
  1062. f.T["tableData"] = dataSource
  1063. f.T["userSelect"] = userSelect
  1064. _ = f.Render("project/check_result.html", &f.T)
  1065. }
  1066. // CountPr 计算百分比
  1067. func CountPr(c1, c2 int) string {
  1068. decimal.DivisionPrecision = 2
  1069. if c1 == 0 || c2 == 0 {
  1070. return "0"
  1071. }
  1072. d := decimal.NewFromInt32(int32(c1)).Div(decimal.NewFromInt32(int32(c2))).Mul(decimal.NewFromInt32(100))
  1073. return d.String() + "%"
  1074. }