1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138 |
- // front
- package front
- import (
- "encoding/json"
- "io/ioutil"
- //"container/list"
- "fmt"
- qu "qfw/util"
- "qfw/util/redis"
- mgo "mongodb"
- "strings"
- "sync"
- "time"
- "util"
- "github.com/go-xweb/xweb"
- "go.mongodb.org/mongo-driver/bson"
- "github.com/tealeg/xlsx"
- es "gopkg.in/olivere/elastic.v1"
- )
- type Front struct {
- *xweb.Action
- // elist xweb.Mapper `xweb:"/elist"`
- login xweb.Mapper `xweb:"/"`
- saveUser xweb.Mapper `xweb:"/center/saveuser"`
- listInfo xweb.Mapper `xweb:"/center/list"`
- checkId xweb.Mapper `xweb:"/center/checkid"`
- detail xweb.Mapper `xweb:"/center/detail/(.*).html"`
- biaozhu xweb.Mapper `xweb:"/center/biaozhu"`
- importByExcel xweb.Mapper `xweb:"/center/importbyexcel"`
- importByEs xweb.Mapper `xweb:"/center/importbyes"`
- getEsCount xweb.Mapper `xweb:"/center/getescount"`
- finishCheck xweb.Mapper `xweb:"/center/finishcheck"`
- errCheck xweb.Mapper `xweb:"/center/errcheck"`
- syncMarked xweb.Mapper `xweb:"/center/syncmarked"`
- markedInit xweb.Mapper `xweb:"/center/markedinit"`
- review xweb.Mapper `xweb:"/center/review"` // 质检
- reviewList xweb.Mapper `xweb:"/center/reviewlist"` // 质检数据列表
- reviewDetail xweb.Mapper `xweb:"/center/reviewdetail/(.*).html"`
- reviewSave xweb.Mapper `xweb:"/center/reviewsave"`
- reviewStat xweb.Mapper `xweb:"/center/review/result"`
- reviewNext xweb.Mapper `xweb:"/center/review/next"`
- }
- var preKey = "ck_"
- var preErr = "err_"
- var SE = qu.SimpleEncrypt{Key: "topJYBX2019"}
- var CheckLock = &sync.Mutex{}
- var LABELER, AUDITOR, ADMIN = 1, 2, 3 //标注人员,审核人员,管理员
- /*
- status
- -1:初始未验证
- 1:正确
- 2:新增
- 3:修改
- 4:删除
- */
- //列表
- func (i *Front) ListInfo() error {
- //loginuser := i.GetSession("loginuser").(string)
- spidercode := i.GetString("spidercode")
- coll := i.GetString("coll")
- field := i.GetString("field")
- stype := i.GetString("type")
- min := i.GetString("minval") //min max不用int类型接收,以免有默认值0
- max := i.GetString("maxval")
- hasno, _ := i.GetBool("hasno")
- notag, _ := i.GetBool("notag")
- pagenum, _ := i.GetInteger("pagenum")
- labeler := i.GetString("labeler")
- if pagenum == 0 { //页码
- pagenum = 1
- }
- qu.Debug("coll:", coll, "stype:", stype, "field:", field, "hasno:", hasno, "notag:", notag, "max:", max, "min:", min, "pagenum:", pagenum, "labeler:", labeler)
- query := map[string]interface{}{}
- if spidercode != "" { //爬虫代码
- query["spidercode"] = spidercode
- }
- if stype != "-1" && stype != "" { //类型
- if stype == util.SPECIALTYPE {
- query["subtype"] = map[string]interface{}{
- "$exists": false,
- }
- } else {
- subtype := strings.Split(stype, "-")[1]
- query["subtype"] = subtype
- }
- }
- fieldScreen := false
- if field != "-1" && field != "" { //字段
- fieldScreen = true
- queryfield := map[string]interface{}{
- "$exists": !hasno,
- }
- if field == "budget" || field == "bidamount" { //金额区间
- numMap := map[string]interface{}{}
- if min != "" {
- minint := qu.IntAll(min)
- numMap["$gte"] = minint
- }
- if max != "" {
- maxint := qu.IntAll(max)
- numMap["$lte"] = maxint
- }
- if len(numMap) > 0 { //给定了区间,不再判断字段存在
- queryfield = numMap
- }
- }
- query[field] = queryfield
- }
- if fieldScreen && notag {
- query[preKey+field] = map[string]interface{}{
- "$exists": false,
- }
- } else if !fieldScreen && notag {
- query["ck_data"] = 0
- }
- //标注人员
- if labeler != "" {
- query["modifyuser"] = labeler
- }
- qu.Debug("query:", coll, query)
- if coll == "" {
- coll = util.Config.Fromtable
- }
- i.SetSession("coll", coll) //session中存入查询表
- i.SetSession("query", query) //session中存入查询条件
- listData := getListInfo(coll, query, pagenum)
- i.T["list"] = listData
- i.T["type"] = stype
- i.T["field"] = field
- i.T["spidercode"] = spidercode
- i.T["coll"] = coll
- i.T["topsubtype"] = util.TopSubStypeArr
- i.T["allfield"] = util.AllFieldArr
- i.T["fromtable"] = util.Config.Fromtable
- i.T["dbname"] = util.Config.Dbname
- i.T["max"] = max
- i.T["min"] = min
- i.T["hasno"] = hasno
- i.T["notag"] = notag
- checkedNum, allNum := GetCheckedAndAllDataInfo(query, coll) //已标和总数信息
- i.T["checkednum"] = checkedNum
- i.T["allnum"] = allNum
- i.T["pagenum"] = pagenum
- role := qu.IntAll(i.GetSession("role"))
- i.T["role"] = role
- i.T["labeler"] = labeler
- if role >= AUDITOR {
- i.T["labelers"] = GetLabeler(coll)
- }
- return i.Render("list.html", &i.T)
- }
- //判断id是否正在被标记
- func (i *Front) CheckId() {
- defer qu.Catch()
- CheckLock.Lock()
- defer CheckLock.Unlock()
- msg := ""
- id := i.GetString("id")
- coll := i.GetSession("coll").(string)
- qu.Debug(coll, id)
- if coll != "" {
- exists, err := redis.Exists("extcheck", coll+"_"+id)
- if err == nil {
- if exists {
- id, exists = GetNoCheckedId(id, coll)
- }
- } else {
- msg = "校验数据出错!"
- }
- i.ServeJson(map[string]interface{}{"msg": msg, "id": id, "exists": exists})
- return
- }
- i.ServeJson(map[string]interface{}{"msg": "数据校验表出错!"})
- }
- //标注
- func (i *Front) Biaozhu() error {
- b := false
- obj := []map[string]interface{}{}
- //ispackage := i.GetString("ispackage")
- key := i.GetString("key")
- _id := i.GetString("_id")
- stype, _ := i.GetInteger("stype")
- err := json.Unmarshal([]byte(key), &obj)
- if err != nil {
- i.ServeJson(b)
- return nil
- }
- //base := map[string]interface{}{}
- set := map[string]interface{}{} //更新、新增字段
- unset := map[string]interface{}{} //删除字段
- errset := map[string]interface{}{} //记录修改的字段信息
- isSaveMarked := false
- if len(obj) == 1 { //单独保存某个一级
- content, ok := obj[0]["content"].([]interface{})
- if !ok || len(content) == 0 {
- i.ServeJson(b)
- return nil
- }
- title := qu.ObjToString(obj[0]["title"])
- isext, _ := obj[0]["checkType"].(bool)
- istag, _ := obj[0]["checkAllTag"].(bool)
- status := qu.IntAll(obj[0]["status"])
- switch title {
- case "基本字段":
- BzJBZD(content, set, unset, errset)
- case "时间地点":
- BzSJDD(content, set, unset, errset)
- case "标的信息":
- BzBDXX(content, set, unset, errset, isext, istag, status)
- case "多包信息":
- BzDBXX(content, set, unset, errset, isext, status)
- case "中标候选人信息":
- BzZBHXRXX(content, set, unset, errset, isext, status)
- case "其余信息":
- BzQYXX(content, set, unset, errset)
- }
- } else {
- isSaveMarked = true
- for j, val := range obj {
- content, ok := val["content"].([]interface{})
- status := qu.IntAll(val["status"])
- if !ok {
- continue
- // i.ServeJson(b)
- // return nil
- }
- isext, _ := val["checkType"].(bool)
- istag, _ := val["checkAllTag"].(bool)
- if j == 0 { //基本信息
- BzJBZD(content, set, unset, errset)
- } else if j == 1 { //时间地点
- BzSJDD(content, set, unset, errset)
- } else if j == 2 { //标的物
- BzBDXX(content, set, unset, errset, isext, istag, status)
- } else if j == 3 { //多包
- BzDBXX(content, set, unset, errset, isext, status)
- } else if j == 4 { //候选人
- BzZBHXRXX(content, set, unset, errset, isext, status)
- } else { //其余信息
- BzQYXX(content, set, unset, errset)
- }
- }
- }
- qu.Debug("errset---", errset)
- qu.Debug("set---", set)
- qu.Debug("unset---", unset)
- userInfo := map[string]interface{}{} //记录本次标注日志
- modifyFields := map[string]interface{}{} //本次标注所有字段
- unerrset := map[string]interface{}{} //记录errdata错误信息表删除
- loginuser := i.GetSession("loginuser").(string)
- coll := i.GetSession("coll").(string)
- data, _ := util.MgoM.FindById(coll, _id, nil) //查询标注保存前的原始信息
- modifyuser := qu.ObjToString((*data)["modifyuser"])
- //标注多次操作处理
- if len(set) > 0 { //set中为本次标注保存的数据(ck_bidopentime:1;ck_buyer:2;buyer:"XXX")
- for s, sv := range set {
- //特殊字段处理
- if s == "ck_pclistag" && (*data)["ck_pclistag"] != nil {
- delete(set, s)
- continue
- }
- //区分是标记字段,还是普通字段(标记字段:ck_buyer;普通字段:buyer)
- if strings.HasPrefix(s, preKey) {
- status := qu.IntAll(sv) //标注字段状态
- field := s[3:] //去除前缀,被标注字段
- checkedStatus := qu.IntAll((*data)[s]) //数据库被标注状态
- if status == 1 && (checkedStatus == 2 || checkedStatus == 1) { //数据库已有标记,且页面标注正确,此次该字段不做标注保存
- qu.Debug("已标注字段field---", field)
- delete(set, field)
- delete(set, s)
- continue
- } else {
- qu.Debug("未标注字段field---", field, status)
- if set[field] == nil && status != 2 { //表示该字段没有要修改的值,此时标记为1或2(亦或是ck_wodrisext;ck_pkgisext;ck_pclisext)
- modifyFields[field] = set[s] //目前会有pclisext、pclistag、pkgisext、wodrisext
- continue
- } else { //此时有修改的值和标记2
- modifyFields[field] = status //记录标注的字段和状态
- if checkedStatus != 0 { //已有标注信息的状态
- if status == 2 && checkedStatus == 2 { //字段已被修改且本次也为修改
- errdata, _ := util.MgoM.FindById(util.Config.Totablel, _id, map[string]interface{}{"userinfo": 0})
- //if field == "package" || field == "purchasinglist" || field == "winnerorder" {
- //}
- if errdata != nil && len(*errdata) != 0 {
- qu.Debug(field, (*errdata)[field] != nil, fmt.Sprint((*errdata)[field]))
- delete(errset, field) //errdata中有该字段的错误记录,不再更新errdata
- //对比errdata错误值:相等变为1,errdata删除;不等变为2,标注表修改该字段
- errText := fmt.Sprint((*errdata)[field])
- text := fmt.Sprint(set[field])
- qu.Debug("errText---", errText, text)
- if errText == text {
- set[s] = 1 //更新标注表字段状态
- unerrset[field] = "" //删除errdata表字段
- //delete(errset, field)
- }
- }
- }
- }
- }
- }
- }
- }
- }
- qu.Debug("errset---", errset)
- qu.Debug("set---", set)
- qu.Debug("unset---", unset)
- qu.Debug("unerrset---", unerrset)
- //1、errdata操作
- //存储原错误信息
- errUpdata := map[string]interface{}{} //errdata所有要更新内容
- for f, v := range errset {
- qu.Debug("err filed---", f, v)
- //if f != "package" && f != "purchasinglist" && f != "winnerorder" {
- errset[f] = (*data)[f]
- //}
- }
- if len(modifyFields) > 0 { //有标注字段,记录标注信息
- errset["updatetime"] = time.Now().Unix()
- errset["modifyuser"] = loginuser
- userInfo["fields"] = modifyFields
- userInfo["updatetime"] = time.Now().Unix()
- userInfo["modifyuser"] = loginuser
- errUpdata["$push"] = map[string]interface{}{
- "userinfo": map[string]interface{}{
- "$each": []interface{}{userInfo},
- "$position": 0,
- },
- }
- }
- qu.Debug("set---", set)
- qu.Debug("errset---", errset)
- qu.Debug("unerrset---", unerrset)
- qu.Debug("userInfo---", userInfo)
- if len(errset) > 0 {
- errUpdata["$set"] = errset
- }
- if len(unerrset) > 0 {
- errUpdata["$unset"] = unerrset
- }
- if len(errUpdata) > 0 {
- util.MgoM.Update(util.Config.Totablel, `{"_id":"`+_id+`"}`, errUpdata, true, false)
- }
- //更新表操作
- //qu.Debug("set---", set)
- //更新正确信息
- update := map[string]interface{}{}
- if len(set) > 0 {
- set["ck_data"] = stype
- set["updatetime"] = time.Now().Unix()
- if modifyuser == "" {
- set["modifyuser"] = modifyuser
- }
- update["$set"] = set
- }
- qu.Debug("unset---", unset)
- if len(unset) > 0 {
- update["$unset"] = unset
- }
- qu.Debug("update---", update)
- if len(update) > 0 {
- b = util.MgoM.Update(coll, `{"_id":"`+_id+`"}`, update, false, false)
- if b {
- if coll != util.Config.Fromtable && isSaveMarked { //util.coll此时的标注表 util.Config.Fromtable默认标注表
- data, _ := util.MgoM.FindById(coll, _id, nil)
- if data != nil && len(*data) > 0 {
- update := map[string]interface{}{"$set": *data}
- if len(unset) > 0 {
- update["$unset"] = unset
- }
- if !util.MgoM.Update(util.Config.Fromtable, map[string]interface{}{"_id": (*data)["_id"]}, update, true, false) {
- qu.Debug("同步marked失败,", _id)
- }
- }
- }
- }
- i.ServeJson(b)
- } else {
- i.ServeJson(true)
- }
- return nil
- }
- //查询信息
- func (i *Front) Detail(id string) error {
- coll, _ := i.GetSession("coll").(string)
- //if coll != "" {
- // exists, _ := redis.Exists("extcheck", coll+"_"+id)
- // if exists {
- // tmpId, exists := GetNoCheckedId(id, coll)
- // if exists { //标注完成
- // return i.Render("finish.html", &i.T)
- // } else {
- // id = tmpId
- // }
- // }
- //} else {
- // i.T["err"] = "数据查询表为空!"
- // return i.Render("err.html", &i.T)
- //}
- query, _ := i.GetSession("query").(map[string]interface{})
- qu.Debug(coll, query)
- rep := getDetail(id, coll) //获取本条公告的信息
- i.T["otherInfo"] = rep["otherInfo"] //展示关联公告信息
- i.T["moreInfo"] = rep["moreInfo"] //更多关联公告信息
- //i.T["jyhref"] = util.JYHREFPRE + qu.CommonEncodeArticle("content", id) + ".html"
- i.T["info"] = rep["info"]
- i.T["common"] = rep["common"]
- i.T["worder"] = rep["worder"]
- i.T["packs"] = rep["packs"]
- i.T["packskey"] = rep["packskey"]
- //i.T["ck_pclisext"] = rep["ck_pclisext"]
- i.T["ck_pclistag"] = rep["ck_pclistag"]
- //i.T["ck_wodrisext"] = rep["ck_wodrisext"]
- //i.T["ck_pkgisext"] = rep["ck_pkgisext"]
- i.T["timeplace"] = rep["timeplace"]
- i.T["purchasinglist"] = rep["purchasinglist"]
- i.T["other"] = rep["other"]
- i.T["PurchasinglistField"] = util.PurchasinglistField
- i.T["WinnerorderField"] = util.WinnerorderField
- i.T["PackageField"] = util.PackageField
- i.T["topsubtype"] = util.TopSubStypeArr2
- i.T[preKey+"purchasinglist"] = rep[preKey+"purchasinglist"]
- i.T[preKey+"package"] = rep[preKey+"package"]
- i.T[preKey+"winnerorder"] = rep[preKey+"winnerorder"]
- i.T["worder_new"] = rep["worder_new"]
- i.T["pcl_new"] = rep["pcl_new"]
- i.T["pkg_new"] = rep["pkg_new"]
- i.T["nextid"] = GetNextDataId(id, coll, query) //下一条id
- checkedNum, allNum := GetCheckedAndAllDataInfo(query, coll) //已标和总数信息
- i.T["checkednum"] = checkedNum
- i.T["allnum"] = allNum
- i.T["fields"] = util.Config.Fields
- //存入Redis
- redis.Put("extcheck", coll+"_"+id, "", util.Config.RedisTimeout*60) //正在标注的数据存入redis避免多人同时标注(加上coll左前缀避免不同表相同id数据不能同时标注)
- return i.Render("detail.html", &i.T)
- }
- //通过excel表格导入
- func (i *Front) ImportByExcel() {
- defer qu.Catch()
- //success := false
- msg := ""
- importNum := 0
- successNum := int64(0)
- coll := i.GetString("excelcoll")
- if coll == "" {
- i.ServeJson(map[string]interface{}{"msg": "表名错误"})
- return
- }
- mf, _, err := i.GetFile("xlsx")
- if err == nil {
- binary, _ := ioutil.ReadAll(mf)
- xls, _ := xlsx.OpenBinary(binary)
- sheet := xls.Sheets[0]
- rows := sheet.Rows
- idcolnum := -1
- ids := []string{}
- cellFieldName := map[int]string{} //记录客户需求字段所在的列
- tmpMap := map[string]map[string]interface{}{} //excel表中需要保存字段集合
- for rn, row := range rows {
- if rn == 0 {
- for j, cell := range row.Cells {
- title := cell.Value
- if fieldName := util.Config.CustomerField[title]; fieldName != "" { //客户需求字段
- cellFieldName[j] = fieldName
- }
- if title == "唯一标识" || title == "信息标识" { //id所在列
- idcolnum = j
- }
- }
- if idcolnum == -1 {
- break
- }
- continue
- }
- if len(row.Cells) < len(rows[0].Cells) {
- break
- }
- tmp := map[string]interface{}{}
- for j, f := range cellFieldName {
- if val := row.Cells[j].Value; val != "" {
- if f == "capital" { //注册资金(万元)
- cf, _ := row.Cells[j].Float()
- tmp[f] = cf
- } else if f == "createtime" { //创建时间
- ci, _ := row.Cells[j].Int64()
- tmp[f] = ci
- } else {
- tmp[f] = val
- }
- }
- }
- id := row.Cells[idcolnum].String() //加密的id
- if id == "" {
- break
- }
- id = SE.DecodeString(id) //解密后id
- tmpMap[id] = tmp
- ids = append(ids, id)
- }
- importNum = len(ids) //excel表数据个数
- if importNum > 0 {
- _, msg, successNum = GetDataById1(coll, ids, "excel", tmpMap)
- tmpMap = map[string]map[string]interface{}{}
- ids = []string{}
- }
- }
- msg = fmt.Sprintf("共查询%d条,导入成功%d条\n", importNum, successNum) + msg
- i.ServeJson(map[string]interface{}{"msg": msg})
- }
- func (i *Front) GetEsCount() {
- defer qu.Catch()
- msg := ""
- count := int64(0)
- estext := i.GetString("estext") //es查询语句
- esJson := map[string]interface{}{}
- if json.Unmarshal([]byte(estext), &esJson) != nil || len(esJson) == 0 {
- msg = "Es语句错误"
- } else {
- count = util.Es.Count(util.Index, util.Itype, estext)
- }
- i.ServeJson(map[string]interface{}{"count": count, "msg": msg})
- }
- //通过es语句导入
- func (i *Front) ImportByEs() {
- defer qu.Catch()
- //success := false
- msg := ""
- successNum := int64(0)
- estext := i.GetString("estext") //es查询语句
- coll := i.GetString("coll") //导入表
- if coll == "" {
- i.ServeJson(map[string]interface{}{"msg": "表名错误"})
- return
- }
- client := util.Es.GetEsConn()
- defer util.Es.DestoryEsConn(client)
- ch := make(chan bool, 5)
- wg := &sync.WaitGroup{}
- lock := &sync.Mutex{}
- escount := util.Es.Count(util.Index, util.Itype, estext)
- qu.Debug("查询总数:", escount)
- if escount > 0 {
- //查询条件类型转换
- var q es.Query
- tmpQuery := es.BoolQuery{
- QueryStrings: estext,
- }
- q = tmpQuery
- //游标查询,index不支持别名,只能写索引库的名称
- res, err := client.Scroll(util.Index).Query(q).Size(200).Do() //查询一条获取游标
- ids := []string{} //id数据
- if err == nil {
- numDocs := 0
- scrollId := res.ScrollId
- for {
- if scrollId == "" {
- qu.Debug("ScrollId Is Error")
- break
- }
- searchResult, err := client.Scroll(util.Index).Size(200).ScrollId(scrollId).Do() //查询
- if err != nil {
- if err.Error() == "EOS" { //迭代完毕
- qu.Debug("Es Search Data Over:", err)
- } else {
- qu.Debug("Es Search Data Error:", err)
- }
- break
- }
- for _, hit := range searchResult.Hits.Hits {
- //开始处理数据
- wg.Add(1)
- ch <- true
- go func(tmpHit *es.SearchHit) {
- defer func() {
- <-ch
- wg.Done()
- }()
- tmp := make(map[string]interface{})
- if json.Unmarshal(*tmpHit.Source, &tmp) == nil {
- id := qu.ObjToString(tmp["_id"])
- tmp["id"] = id //记录数据原有id
- lock.Lock()
- ids = append(ids, id)
- lock.Unlock()
- }
- }(hit)
- numDocs += 1
- if numDocs%500 == 0 {
- qu.Debug("Current:", numDocs)
- }
- }
- scrollId = searchResult.ScrollId
- }
- wg.Wait()
- client.ClearScroll().ScrollId(scrollId).Do() //清理游标
- //qu.Debug("Result Data Count:", numDocs)
- } else {
- qu.Debug("Es Search Data Error")
- }
- //判断数量
- if int64(len(ids)) != escount {
- msg = "查询数据和结果不一致"
- } else { //入库
- _, msg, successNum = GetDataById(coll, ids, "es", map[string]map[string]interface{}{})
- }
- } else {
- msg = "无查询数据"
- }
- msg = fmt.Sprintf("共查询%d条,导入成功%d条\n", escount, successNum) + msg
- i.ServeJson(map[string]interface{}{"msg": msg})
- }
- //同步数据
- func (i *Front) SyncMarked() {
- syncColl := i.GetString("coll")
- sess := util.MgoM.GetMgoConn()
- defer util.MgoM.DestoryMongoConn(sess)
- it := sess.DB(util.Config.Dbname).C(syncColl).Find(nil).Iter()
- count, _ := sess.DB(util.Config.Dbname).C(syncColl).Find(nil).Count()
- qu.Debug(syncColl, count)
- n := 0
- lock := &sync.Mutex{}
- wg := &sync.WaitGroup{}
- ch := make(chan bool, 3)
- result := map[string]map[string]interface{}{}
- idArr := []string{}
- for tmp := make(map[string]interface{}); it.Next(tmp); n++ {
- wg.Add(1)
- ch <- true
- go func(tmp map[string]interface{}) {
- defer func() {
- <-ch
- wg.Done()
- }()
- id := qu.ObjToString(tmp["id"])
- if id == "" {
- return
- }
- tmpMap := map[string]interface{}{}
- for _, f := range util.Config.CustomerField {
- if val := tmp[f]; val != nil {
- tmpMap[f] = val
- }
- }
- lock.Lock()
- idArr = append(idArr, id)
- result[id] = tmpMap
- lock.Unlock()
- }(tmp)
- tmp = map[string]interface{}{}
- }
- wg.Wait()
- if count != int64(len(result)) {
- i.ServeJson(map[string]interface{}{"msg": "同步失败", "flag": false})
- return
- }
- //util.MgoM.C.Database(util.Config.Dbname).Collection(syncColl).Drop(util.MgoM.Ctx) //删除syncColl表(清空数据)
- success, msg, successNum := GetDataById(syncColl, idArr, "syncoll", result)
- result = map[string]map[string]interface{}{}
- idArr = []string{}
- msg = fmt.Sprintf("共查询%d条,同步成功%d条\n", count, successNum) + msg
- i.ServeJson(map[string]interface{}{"msg": msg, "flag": success})
- }
- //将marked表中ck_data:2更新为0
- func (i *Front) MarkedInit() {
- set := map[string]interface{}{
- "$set": map[string]interface{}{
- "ck_data": 0,
- },
- }
- b := util.MgoM.Update(util.Config.Fromtable, `{"ck_data":2}`, set, false, true)
- i.ServeJson(map[string]interface{}{"success": b})
- }
- //标注完成
- func (i *Front) FinishCheck() {
- i.Render("finish.html")
- }
- //错误页面
- func (i *Front) ErrCheck() {
- i.Render("err.html")
- }
- //统计抽查
- func (i *Front) Tj() error {
- comm := map[string]map[string]int{}
- comm_win := map[string]map[string]int{}
- pack := map[string]map[string]int{}
- pack_win := map[string]map[string]int{}
- list, _ := util.MgoM.Find(util.Config.Totablel, "{}", nil, nil, false, -1, -1)
- for _, tmp := range *list {
- for k, val := range tmp {
- if len(k) > 3 && k[:3] == preKey {
- comm = mapIntAdd(k, qu.ObjToString(val), comm)
- }
- }
- if winnerorder, ok := tmp["winnerorder"].([]interface{}); ok {
- for _, wd := range winnerorder {
- if winner, ok := wd.(map[string]interface{}); ok {
- for k, val := range winner {
- if len(k) > 3 && k[:3] == preKey {
- comm_win = mapIntAdd(k, qu.ObjToString(val), comm_win)
- }
- }
- }
- }
- }
- if ptmp, ok := tmp["package"].(map[string]interface{}); ok {
- for _, pktmp := range ptmp {
- if pkage, ok := pktmp.(map[string]interface{}); ok {
- for k, val := range pkage {
- if len(k) > 3 && k[:3] == preKey {
- pack = mapIntAdd(k, qu.ObjToString(val), pack)
- }
- if k == "winnerorder" {
- if wtmp, ok := val.([]interface{}); ok {
- for _, winner := range wtmp {
- if win, ok := winner.(map[string]interface{}); ok {
- for wk, wval := range win {
- if len(k) > 3 && k[:3] == preKey {
- pack_win = mapIntAdd(wk, qu.ObjToString(wval), pack_win)
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- //data := map[string]interface{}{"total": len(list), "comm": comm, "pack": pack, "pack_win": pack_win}
- //mongodb.Save("extcheck_tj", data)
- i.T["comm"] = comm
- i.T["pack"] = pack
- i.T["comm_win"] = comm_win
- i.T["pack_win"] = pack_win
- i.T["total"] = len(*list)
- return i.Render("tj.html", &i.T)
- }
- //标错列表
- func (i *Front) Elist() error {
- attrname := i.GetString("attrname")
- common := util.Config.Biaozhu["common"]
- elist, _ := util.MgoM.Find(util.Config.Totablel, `{"ck_`+attrname+`":"0"}`, `{"_id":1}`, `{"_id":1}`, false, -1, -1)
- for _, v := range *elist {
- v["_id"] = mgo.BsonIdToSId(v["_id"])
- }
- i.T["elist"] = *elist
- i.T["attrname"] = attrname
- i.T["common"] = common
- return i.Render("elist.html", &i.T)
- }
- func (i *Front) Review() error {
- defer qu.Catch()
- var labeler []map[string]interface{}
- sess := util.MgoM.GetMgoConn()
- defer util.MgoM.DestoryMongoConn(sess)
- sess.DB(util.MgoM.DbName).C(util.Config.Fromtable).Pipe([]map[string]interface{}{
- //查询条件
- {
- "$match": bson.M{
- "ck_data": bson.M{"$gte": 1},
- },
- },
- // 按照modifyuser分组,并统计
- {
- "$group": bson.M{
- "_id": "$modifyuser",
- "count": bson.M{"$sum": 1},
- },
- },
- // 排序
- {
- "$sort": bson.M{"count": -1},
- },
- }).All(&labeler)
- i.T["users"] = labeler
- qu.Debug(util.Config.Fields)
- i.T["fields"] = util.Config.Fields
- return i.Render("review.html", &i.T)
- }
- func (i *Front) ReviewList() {
- defer qu.Catch()
- if i.Method() == "POST" {
- user := i.GetString("user")
- q := make(map[string]interface{})
- q["ck_data"] = bson.M{"$gte": 1}
- if user != "0" && user != "-1" {
- q["modifyuser"] = user
- }
- qu.Debug(q, util.Config.Fromtable)
- datas, b := util.MgoM.Find(util.Config.Fromtable, q, bson.M{"_id": 1}, nil, false, -1, -1)
- if b && len(*datas) > 0 {
- i.ServeJson(map[string]interface{}{
- "rep": b,
- "data": *datas,
- })
- } else {
- i.ServeJson(map[string]interface{}{
- "rep": false,
- "msg": "未查询到数据",
- })
- }
- }
- }
- func (i *Front) ReviewDetail(id string) error {
- defer qu.Catch()
- coll, _ := i.GetSession("coll").(string)
- query, _ := i.GetSession("query").(map[string]interface{})
- rep := getDetail(id, coll) //获取本条公告的信息
- i.T["otherInfo"] = rep["otherInfo"] //展示关联公告信息
- i.T["moreInfo"] = rep["moreInfo"] //更多关联公告信息
- i.T["info"] = rep["info"]
- i.T["common"] = rep["common"]
- i.T["worder"] = rep["worder"]
- i.T["packs"] = rep["packs"]
- i.T["packskey"] = rep["packskey"]
- i.T["ck_pclisext"] = rep["ck_pclisext"]
- i.T["ck_wodrisext"] = rep["ck_wodrisext"]
- i.T["ck_pkgisext"] = rep["ck_pkgisext"]
- i.T["timeplace"] = rep["timeplace"]
- i.T["purchasinglist"] = rep["purchasinglist"]
- i.T["other"] = rep["other"]
- i.T["PurchasinglistField"] = util.PurchasinglistField
- i.T["WinnerorderField"] = util.WinnerorderField
- i.T["PackageField"] = util.PackageField
- i.T["topsubtype"] = util.TopSubStypeArr2
- i.T[preKey+"purchasinglist"] = rep[preKey+"purchasinglist"]
- i.T[preKey+"package"] = rep[preKey+"package"]
- i.T[preKey+"winnerorder"] = rep[preKey+"winnerorder"]
- i.T["worder_new"] = rep["worder_new"]
- i.T["pcl_new"] = rep["pcl_new"]
- i.T["pkg_new"] = rep["pkg_new"]
- i.T["fields"] = util.Config.Fields
- i.T["nextid"] = GetNextDataId(id, coll, query) //下一条id
- return i.Render("re_detail.html", &i.T)
- }
- func (i *Front) ReviewSave() error {
- defer qu.Catch()
- b := false
- obj := []map[string]interface{}{}
- key := i.GetString("key")
- _id := i.GetString("_id")
- //stype, _ := i.GetInteger("stype")
- err := json.Unmarshal([]byte(key), &obj)
- if err != nil {
- i.ServeJson(b)
- return nil
- }
- set := map[string]interface{}{} //更新、新增字段
- unset := map[string]interface{}{} //删除字段
- errset := map[string]interface{}{} //记录修改的字段信息
- isSaveMarked := false
- if len(obj) == 1 { //单独保存某个一级
- content, ok := obj[0]["content"].([]interface{})
- if !ok || len(content) == 0 {
- i.ServeJson(b)
- return nil
- }
- title := qu.ObjToString(obj[0]["title"])
- isext, _ := obj[0]["checkType"].(bool)
- istag, _ := obj[0]["checkAllTag"].(bool)
- status := qu.IntAll(obj[0]["status"])
- switch title {
- case "基本字段":
- BzJBZD(content, set, unset, errset)
- case "时间地点":
- BzSJDD(content, set, unset, errset)
- case "标的信息":
- BzBDXX(content, set, unset, errset, isext, istag, status)
- case "多包信息":
- BzDBXX(content, set, unset, errset, isext, status)
- case "中标候选人信息":
- BzZBHXRXX(content, set, unset, errset, isext, status)
- case "其余信息":
- BzQYXX(content, set, unset, errset)
- }
- } else {
- isSaveMarked = true
- for j, val := range obj {
- content, ok := val["content"].([]interface{})
- status := qu.IntAll(val["status"])
- if !ok {
- continue
- // i.ServeJson(b)
- // return nil
- }
- isext, _ := val["checkType"].(bool)
- istag, _ := val["checkAllTag"].(bool)
- if j == 0 { //基本信息
- BzJBZD(content, set, unset, errset)
- } else if j == 1 { //时间地点
- BzSJDD(content, set, unset, errset)
- } else if j == 2 { //标的物
- BzBDXX(content, set, unset, errset, isext, istag, status)
- } else if j == 3 { //多包
- BzDBXX(content, set, unset, errset, isext, status)
- } else if j == 4 { //候选人
- BzZBHXRXX(content, set, unset, errset, isext, status)
- } else { //其余信息
- BzQYXX(content, set, unset, errset)
- }
- }
- }
- userInfo := map[string]interface{}{} //记录本次标注日志
- modifyFields := map[string]interface{}{} //本次标注所有字段
- unerrset := map[string]interface{}{} //记录errdata错误信息表删除
- loginuser := i.GetSession("loginuser").(string)
- coll := i.GetSession("coll").(string)
- data, _ := util.MgoM.FindById(coll, _id, nil) //查询标注保存前的原始信息
- //modifyuser := qu.ObjToString((*data)["modifyuser"])
- remap := make(map[string]interface{}) // 质检信息
- reField := make(map[string]interface{})
- remap["user"] = loginuser
- remap["updatetime"] = time.Now().Unix()
- //标注多次操作处理
- if len(set) > 0 { //set中为本次标注保存的数据(ck_bidopentime:1;ck_buyer:2;buyer:"XXX")
- for s, sv := range set {
- //特殊字段处理
- if s == "ck_pclistag" && (*data)["ck_pclistag"] != nil {
- delete(set, s)
- continue
- }
- //区分是标记字段,还是普通字段(标记字段:ck_buyer;普通字段:buyer)
- if strings.HasPrefix(s, preKey) {
- status := qu.IntAll(sv) //标注字段状态
- field := s[3:] //去除前缀,被标注字段
- checkedStatus := qu.IntAll((*data)[s]) //数据库被标注状态
- rename := strings.Replace(s, "ck_", "re_", -1)
- reField[rename] = status
- if status == 1 && (checkedStatus == 2 || checkedStatus == 1) { //数据库已有标记,且页面标注正确,此次该字段不做标注保存
- delete(set, field)
- delete(set, s)
- continue
- } else {
- if set[field] == nil && status != 2 { //表示该字段没有要修改的值,此时标记为1或2(亦或是ck_wodrisext;ck_pkgisext;ck_pclisext)
- modifyFields[field] = set[s] //目前会有pclisext、pclistag、pkgisext、wodrisext
- continue
- } else { //此时有修改的值和标记2
- modifyFields[field] = status //记录标注的字段和状态
- if checkedStatus != 0 { //已有标注信息的状态
- if status == 2 && checkedStatus == 2 { //字段已被修改且本次也为修改
- errdata, _ := util.MgoM.FindById(util.Config.Totablel, _id, map[string]interface{}{"userinfo": 0})
- if errdata != nil && len(*errdata) != 0 {
- delete(errset, field) //errdata中有该字段的错误记录,不再更新errdata
- //对比errdata错误值:相等变为1,errdata删除;不等变为2,标注表修改该字段
- errText := fmt.Sprint((*errdata)[field])
- text := fmt.Sprint(set[field])
- if errText == text {
- set[s] = 1 //更新标注表字段状态
- unerrset[field] = "" //删除errdata表字段
- }
- }
- }
- }
- }
- }
- }
- }
- }
- remap["field"] = reField
- set["review"] = remap
- set["re_data"] = 1
- //存储原错误信息
- //1、errdata操作
- errUpdata := map[string]interface{}{} //errdata所有要更新内容
- for f, _ := range errset {
- errset[f] = (*data)[f]
- }
- if len(modifyFields) > 0 { //有标注字段,记录标注信息
- errset["updatetime"] = time.Now().Unix()
- errset["modifyuser"] = loginuser
- userInfo["fields"] = modifyFields
- userInfo["updatetime"] = time.Now().Unix()
- userInfo["modifyuser"] = loginuser
- errUpdata["$push"] = map[string]interface{}{
- "userinfo": map[string]interface{}{
- "$each": []interface{}{userInfo},
- "$position": 0,
- },
- }
- }
- if len(errset) > 0 {
- errUpdata["$set"] = errset
- }
- if len(unerrset) > 0 {
- errUpdata["$unset"] = unerrset
- }
- if len(errUpdata) > 0 {
- util.MgoM.Update(util.Config.Totablel, `{"_id":"`+_id+`"}`, errUpdata, true, false)
- }
- //更新表操作
- //更新正确信息
- update := map[string]interface{}{}
- if len(set) > 0 {
- if len(set) > 1 {
- set["updatetime"] = time.Now().Unix()
- set["modifyuser"] = loginuser
- }
- update["$set"] = set
- }
- if len(unset) > 0 {
- update["$unset"] = unset
- }
- if len(update) > 0 {
- b = util.MgoM.Update(coll, `{"_id":"`+_id+`"}`, update, false, false)
- if b {
- if coll != util.Config.Fromtable && isSaveMarked { //util.coll此时的标注表 util.Config.Fromtable默认标注表
- data, _ := util.MgoM.FindById(coll, _id, nil)
- if data != nil && len(*data) > 0 {
- update := map[string]interface{}{"$set": *data}
- if len(unset) > 0 {
- update["$unset"] = unset
- }
- if !util.MgoM.Update(util.Config.Fromtable, map[string]interface{}{"_id": (*data)["_id"]}, update, true, false) {
- qu.Debug("同步marked失败,", _id)
- }
- }
- }
- }
- i.ServeJson(b)
- } else {
- i.ServeJson(true)
- }
- return nil
- }
- func (i *Front) ReviewNext() {
- defer qu.Catch()
- id := i.GetString("id")
- coll := i.GetSession("coll").(string)
- q := bson.M{"_id": bson.M{"$gt": mgo.StringTOBsonId(id)}}
- info, b := util.MgoM.Find(coll, q, bson.M{"_id": 1}, bson.M{"_id": 1}, false, 0, 1)
- qu.Debug(q)
- if b && len(*info) > 0 {
- nxid := mgo.BsonIdToSId((*info)[0]["_id"])
- i.ServeJson(bson.M{"id": nxid, "exists": true})
- }else {
- i.ServeJson(bson.M{"exists": false})
- }
- }
- func (i *Front) ReviewStat() {
- defer qu.Catch()
- sess := util.MgoM.GetMgoConn()
- defer util.MgoM.DestoryMongoConn(sess)
- result := sess.DB(util.MgoM.DbName).C(util.Config.Fromtable).Find(nil).Iter()
- count, cmark, rmark, rgmark := 0, 0, 0, 0 // 总数, 标注数量, 审核数据, 审核数据完全正确的数据量
- cmaps := make(map[string]int) // 标注字段整体准确率
- umaps := make(map[string]interface{}) // 按人员 字段准确率
- for k, i2 := range util.Config.Fields {
- if i2 {
- cmaps[k] = 0
- }
- }
- for tmp := make(map[string]interface{}); result.Next(&tmp); {
- count ++
- if qu.IntAll(tmp["ck_data"]) >= 1 {
- cmark ++
- }
- if qu.IntAll(tmp["re_data"]) > 0 {
- rmark ++
- if reField, ok := tmp["review"].(map[string]interface{}); ok {
- remap, _ := reField["field"].(map[string]interface{})
- flag := true // 数据整体准确率
- // 按人员统计字段准备率
- user := qu.ObjToString(tmp["modifyuser"])
- var up map[string]int
- if umaps[user] == nil {
- up = make(map[string]int)
- }else {
- up = umaps[user].(map[string]int)
- }
- for k1 := range cmaps{
- k2 := "re_" + k1
- if qu.IntAll(remap[k2]) == 1 {
- cmaps[k1] += 1 // 字段整体正确率
- up[k1] += 1
- }else {
- flag = false
- }
- }
- up["count"] += 1
- umaps[user] = up
- if flag {
- rgmark ++
- }
- }
- }
- }
- qu.Debug("count:", count, ",cmark:", cmark, ",rmark:", rmark, ",rgmark:", rgmark)
- qu.Debug(cmaps)
- qu.Debug(umaps)
- save := bson.M{"total_count": count, "cmake_count": cmark, "rmark_count": rmark, "rgmark_count": rgmark}
- save["result"] = cmaps
- save["user_result"] = umaps
- id := util.MgoM.Save("review_result", save)
- if id != "" {
- i.ServeJson(map[string]interface{}{"rep": true})
- }else {
- i.ServeJson(map[string]interface{}{"rep": false})
- }
- }
|