project.go 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. package front
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/tealeg/xlsx"
  6. "go.mongodb.org/mongo-driver/bson/primitive"
  7. "io/ioutil"
  8. "math"
  9. "mime/multipart"
  10. "mongodb"
  11. qu "qfw/util"
  12. "sort"
  13. "strings"
  14. "sync"
  15. "sync/atomic"
  16. "time"
  17. "util"
  18. )
  19. // ProjectList 项目列表
  20. func (f *Front) ProjectList() {
  21. defer qu.Catch()
  22. if f.Method() == "POST" {
  23. start, _ := f.GetInteger("start")
  24. limit, _ := f.GetInteger("length")
  25. draw, _ := f.GetInteger("draw")
  26. status := f.GetString("status")
  27. searchStr := f.GetString("search[value]")
  28. search := strings.TrimSpace(searchStr)
  29. //data := util.GetPostForm(f.Request)
  30. query := map[string]interface{}{}
  31. if status != "-1" {
  32. query["s_status"] = status
  33. }
  34. if search != "" {
  35. query["$or"] = []interface{}{
  36. map[string]interface{}{"s_name": map[string]interface{}{"$regex": search}},
  37. map[string]interface{}{"s_entname": map[string]interface{}{"$regex": search}},
  38. map[string]interface{}{"s_rule": map[string]interface{}{"$regex": search}},
  39. map[string]interface{}{"s_departname": map[string]interface{}{"$regex": search}},
  40. }
  41. }
  42. list, _ := util.Mgo.Find(util.PROJECTCOLLNAME, query, nil, nil, false, start, limit)
  43. count := util.Mgo.Count(util.PROJECTCOLLNAME, query)
  44. f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
  45. } else {
  46. query := map[string]interface{}{"s_type": "tag"}
  47. info, _ := util.Mgo.Find("v_field", query, nil, map[string]interface{}{"s_name": 1, "s_code": 1}, false, -1, -1)
  48. f.T["fields"] = *info
  49. _ = f.Render("project/project_list.html", &f.T)
  50. }
  51. }
  52. // ProjectSave 项目保存
  53. func (f *Front) ProjectSave() {
  54. defer qu.Catch()
  55. s_name := f.GetString("s_name") //项目名称
  56. if s_name == "" {
  57. f.ServeJson(map[string]interface{}{"success": false, "msg": "缺少项目名称字段"})
  58. return
  59. }
  60. success := false //导入数据是否成功
  61. msg := "" //异常信息
  62. successNum := int64(0) //导入成功条数
  63. importDataNum := 0 //查询数量
  64. var s_rulename []string //规则
  65. user := f.GetSession("user").(map[string]interface{})
  66. username := qu.ObjToString(user["s_name"]) //当前登录用户
  67. stype := f.GetString("s_type") //新建项目类型:数据库导入、excel导入
  68. s_sourceinfoTmp := f.GetString("s_sourceinfo") //数据表
  69. s_sourceinfo := "f_sourceinfo_" + s_sourceinfoTmp
  70. if stype != "edit" && s_sourceinfo == "" {
  71. f.ServeJson(map[string]interface{}{"success": false, "msg": "缺少数据存储表名"})
  72. return
  73. }
  74. s_departname, s_entname := "", ""
  75. query := map[string]interface{}{
  76. "s_name": s_name,
  77. }
  78. set := map[string]interface{}{}
  79. qu.Debug(stype)
  80. //导入数据
  81. if stype == "excel" { //excel导入
  82. s_entname = f.GetString("s_entname") //公司名称
  83. if s_entname == "" {
  84. f.ServeJson(map[string]interface{}{"success": false, "msg": "缺少公司名称字段"})
  85. return
  86. }
  87. s_departname = f.GetString("s_departname") //部门名称
  88. rulename := f.GetString("s_rulename") //规则名称
  89. s_rulename = strings.Split(rulename, ",")
  90. mf, _, err := f.GetFile("xlsx")
  91. qu.Debug(s_entname, s_departname, s_rulename)
  92. if err == nil {
  93. importDataNum = ImportDataByExcel(s_sourceinfo, mf, &success, &msg, &successNum)
  94. }
  95. //保存项目信息
  96. set = map[string]interface{}{
  97. "s_name": s_name, //项目名称
  98. "s_entname": s_entname, //公司名称
  99. "s_departname": s_departname, //部门名称
  100. "s_rulename": strings.Join(s_rulename, ","), //规则名称
  101. "i_importnum": importDataNum, //导入数量
  102. "s_sourceinfo": s_sourceinfo, //源数据表
  103. "s_sourcetaskinfo": "s_sourcetaskinfo_" + s_sourceinfoTmp, //源数据表
  104. "s_createname": username, //创建人
  105. "s_status": "未开始", //项目状态
  106. "i_createtime": time.Now().Unix(), //创建时间
  107. "s_importtype": "excel", //导入类型
  108. "b_isassessment": false, //是否进行了质量评估
  109. }
  110. } else if stype == "coll" { //数据库导入
  111. historyid := f.GetString("s_historyid")
  112. if historyid == "" {
  113. f.ServeJson(map[string]interface{}{"success": false, "msg": "数据导出ID字段"})
  114. return
  115. }
  116. s_departname, s_entname, s_rulename, importDataNum = ImportDataByColl(s_sourceinfo, historyid, &success, &msg, &successNum)
  117. qu.Debug(s_departname, s_entname, s_rulename, importDataNum)
  118. //保存项目信息
  119. set = map[string]interface{}{
  120. "s_name": s_name, //项目名称
  121. "s_entname": s_entname, //公司名称
  122. "s_departname": s_departname, //部门名称
  123. "s_rulename": strings.Join(s_rulename, ","), //规则名称
  124. "i_importnum": importDataNum, //导入数量
  125. "s_sourceinfo": s_sourceinfo, //源数据表
  126. "s_createname": username, //创建人
  127. "s_status": "未开始", //项目状态
  128. "i_createtime": time.Now().Unix(), //创建时间
  129. "s_importtype": "coll", //导入类型
  130. "s_historyid": historyid, //源数据集标识
  131. "b_isassessment": false, //是否进行了质量评估
  132. }
  133. } else if stype == "edit" { //编辑保存
  134. success = true
  135. //s_entname = f.GetString("s_entname") //公司名称
  136. s_departname = f.GetString("s_departname") //部门名称
  137. rulename := f.GetString("s_rulename") //规则名称
  138. s_rulename = strings.Split(rulename, ",")
  139. s_personname := f.GetString("s_personname")
  140. fields := f.GetString("v_fields")
  141. v_fields := map[string]interface{}{}
  142. if err := json.Unmarshal([]byte(fields), &v_fields); err != nil {
  143. qu.Debug("V_Filelds Unmarshal Failed:", err)
  144. f.ServeJson(map[string]interface{}{"success": false, "msg": err})
  145. return
  146. }
  147. set = map[string]interface{}{
  148. //"s_name": s_name, //项目名称
  149. //"s_entname": s_entname, //公司名称
  150. "s_departname": s_departname, //部门名称
  151. "s_rulename": strings.Join(s_rulename, ","), //规则名称
  152. "v_fields": v_fields, //标注字段
  153. "i_updatetime": username, //更新人
  154. "i_createtime": time.Now().Unix(), //更新时间
  155. "s_personname": s_personname, //售后人员
  156. //"i_starttime":,//开始时间
  157. //"i_completetime",//结束时间
  158. }
  159. }
  160. if success {
  161. success = util.Mgo.Update(util.PROJECTCOLLNAME, query, map[string]interface{}{"$set": set}, true, false)
  162. qu.Debug("Save Project:", success)
  163. if !success { //保存项目失败
  164. msg = "新建项目失败\n" + msg
  165. } else {
  166. msg = "保存项目成功"
  167. }
  168. }
  169. qu.Debug("Create Project:", success, "importnum:", importDataNum, "successnum:", successNum, "failnum:", int64(importDataNum)-successNum)
  170. qu.Debug("Msg:", msg)
  171. //返回信息
  172. if stype == "edit" {
  173. f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
  174. } else {
  175. f.ServeJson(map[string]interface{}{"success": success, "msg": msg, "importnum": importDataNum, "successnum": successNum, "failnum": int64(importDataNum) - successNum})
  176. }
  177. }
  178. // ProjectQualityAssessment 数据质量评估
  179. func (f *Front) ProjectQualityAssessment() {
  180. defer qu.Catch()
  181. msg := ""
  182. success := false
  183. //质量评估
  184. projectid := f.GetString("pid") //项目id
  185. qu.Debug("Project Id:", projectid)
  186. project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, projectid, map[string]interface{}{"b_isassessment": 1, "s_sourceinfo": 1})
  187. if project != nil && len(*project) > 0 {
  188. if isAssessment, ok := (*project)["b_isassessment"].(bool); ok && !isAssessment {
  189. if fields, ok := (*project)["v_fields"].([]interface{}); ok && len(fields) > 0 {
  190. var fieldsArr []string
  191. for _, fieldsTmp := range fields {
  192. fieldsMap := fieldsTmp.(map[string]interface{})
  193. for f, _ := range fieldsMap {
  194. fieldsArr = append(fieldsArr, f)
  195. }
  196. }
  197. sourceinfo := qu.ObjToString((*project)["s_sourceinfo"])
  198. success := QuaFieldScore(fieldsArr, sourceinfo) //调用数据质量评估接口
  199. if success {
  200. //点击清洗更新项目状态为进行中
  201. b := util.Mgo.UpdateById(util.PROJECTCOLLNAME, projectid, map[string]interface{}{"$set": map[string]interface{}{"b_isassessment": true, "s_status": "进行中", "i_starttime": time.Now().Unix()}})
  202. qu.Debug("Update Porject:"+projectid+" Status Success:", b)
  203. } else {
  204. msg = "质量评估失败"
  205. }
  206. } else {
  207. msg = "项目标注字段查询失败"
  208. }
  209. } else if ok && isAssessment {
  210. success = true
  211. } else {
  212. msg = "查询项目失败"
  213. }
  214. } else {
  215. msg = "查询项目失败"
  216. }
  217. f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
  218. }
  219. // ProjectTaskList 用户组任务分发列表
  220. func (f *Front) ProjectTaskList() {
  221. defer qu.Catch()
  222. projectid := f.GetString("pid") //项目id
  223. qu.Debug("Project Id:", projectid)
  224. if f.Method() == "POST" {
  225. //status := f.GetString("s_status") //任务状态
  226. searchStr := f.GetString("search[value]")
  227. search := strings.TrimSpace(searchStr)
  228. start, _ := f.GetInteger("start")
  229. limit, _ := f.GetInteger("length")
  230. draw, _ := f.GetInteger("draw")
  231. query := map[string]interface{}{ //查找用户组任务
  232. "s_projectid": projectid,
  233. "s_stype": "group",
  234. }
  235. //if status != "-1" {
  236. // query["s_status"] = status
  237. //}
  238. if search != "" {
  239. query["$or"] = []interface{}{
  240. map[string]interface{}{"s_groupname": map[string]interface{}{"$regex": search}},
  241. }
  242. }
  243. list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, nil, nil, false, start, limit)
  244. count := util.Mgo.Count(util.TASKCOLLNAME, query)
  245. for _, l := range *list {
  246. if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
  247. groupId := qu.ObjToString(l["s_groupid"])
  248. giveNum := qu.IntAll(l["i_givenum"])
  249. sourceinfo := qu.ObjToString(l["s_sourceinfo"])
  250. tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_groupid": groupId, "b_istag": true})
  251. progress := fmt.Sprint(math.Ceil(float64(tagNum)/float64(giveNum))) + "%"
  252. l["s_progress"] = progress
  253. //同步数据库
  254. util.Mgo.UpdateById(util.TASKCOLLNAME, l["_id"], map[string]interface{}{"$set": map[string]interface{}{"s_progress": progress}})
  255. }
  256. }
  257. f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
  258. } else {
  259. project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, projectid, map[string]interface{}{"s_sourceinfo": 1})
  260. sourceinfo := qu.ObjToString((*project)["s_sourceinfo"]) //数据源表
  261. qu.Debug(sourceinfo)
  262. okAllDataNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_istagging": false}) //达标数据总量
  263. okIsGiveDataNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_istagging": false, "b_isgivegroup": true}) //达标数据已分发量
  264. okNotGiveDataNum := okAllDataNum - okIsGiveDataNum //达标待分发量
  265. okIsTagDataNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_istagging": false, "b_istag": true}) //达标已标注量
  266. IsNoOkAllDataNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_istagging": true}) //未达标数据总量
  267. IsNoOkIsGiveDataNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_istagging": true, "b_isgivegroup": true}) //未达标数据已分发量
  268. IsNotOkNotGiveDataNum := IsNoOkAllDataNum - IsNoOkIsGiveDataNum //未达标待分发量
  269. IsNotOkIsTagDataNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_istagging": true, "b_istag": true}) //未达标已标注量
  270. allGiveDataNum := okIsGiveDataNum + IsNoOkIsGiveDataNum //总分发量
  271. allNoGiveDataNum := okNotGiveDataNum + IsNotOkNotGiveDataNum //总待分发量
  272. allIsTagDataNum := okIsTagDataNum + IsNotOkIsTagDataNum //已标注总量
  273. allDataNum := allGiveDataNum + allNoGiveDataNum
  274. qu.Debug("数据总量:", allDataNum, "已分发总量:", allGiveDataNum, "待分发总量:", allNoGiveDataNum, "已标注总量:", allIsTagDataNum)
  275. qu.Debug("达标量:", okAllDataNum, "达标已分发量:", okIsGiveDataNum, "达标待分发量:", okNotGiveDataNum, "达标已标注量:", okIsTagDataNum)
  276. qu.Debug(" 未达标量:", IsNoOkAllDataNum, " 未达标已分发量:", IsNoOkIsGiveDataNum, " 未达标待分发量:", IsNotOkNotGiveDataNum, " 未达标已标注量:", IsNotOkIsTagDataNum)
  277. f.T["s_projectid"] = projectid
  278. f.T["s_sourceinfo"] = sourceinfo
  279. f.T["allDataNum"] = allDataNum
  280. f.T["okAllDataNum"] = okAllDataNum
  281. f.T["okIsGiveDataNum"] = okIsGiveDataNum
  282. f.T["okNotGiveDataNum"] = okNotGiveDataNum
  283. f.T["IsNoOkAllDataNum"] = IsNoOkAllDataNum
  284. f.T["IsNoOkIsGiveDataNum"] = IsNoOkIsGiveDataNum
  285. f.T["IsNotOkNotGiveDataNum"] = IsNotOkNotGiveDataNum
  286. f.T["allGiveDataNum"] = allGiveDataNum
  287. f.T["allNoGiveDataNum"] = allNoGiveDataNum
  288. f.T["allIsTagDataNum"] = allIsTagDataNum
  289. f.T["okIsTagDataNum"] = okIsTagDataNum
  290. f.T["IsNotOkIsTagDataNum"] = IsNotOkIsTagDataNum
  291. _ = f.Render("project/project_clear.html", &f.T)
  292. }
  293. }
  294. // ProjectTaskSave 用户组任务分发
  295. func (f *Front) ProjectTaskSave() {
  296. defer qu.Catch()
  297. var groupArr []map[string]interface{}
  298. var taskArr []map[string]interface{}
  299. var groupIdArr []string
  300. var groupTaskIdArr []string
  301. groupIdTask := map[string]util.Task{}
  302. success := false
  303. msg := ""
  304. user := f.GetSession("user").(map[string]interface{})
  305. username := qu.ObjToString(user["s_name"]) //当前登录用户
  306. projectid := f.GetString("s_projectid") //项目标识
  307. project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, projectid, nil)
  308. projectname := qu.ObjToString((*project)["s_name"]) //项目名称
  309. sourceinfo := qu.ObjToString((*project)["s_sourceinfo"]) //源数据表
  310. sourcetaskinfo := qu.ObjToString((*project)["s_sourcetaskinfo"]) //任务日志表
  311. group := f.GetString("s_group")
  312. qu.Debug(group)
  313. stype := f.GetString("s_type")
  314. qu.Debug("项目id:", projectid, " 项目名称:", projectname, "sourcetaskinfo:", sourcetaskinfo)
  315. if err := json.Unmarshal([]byte(group), &groupArr); err != nil {
  316. qu.Debug("GroupInfo Unmarshal Failed:", err)
  317. msg = "用户组信息解析失败"
  318. } else {
  319. qu.Debug("用户组信息:", groupArr, stype)
  320. if stype == "notag" { //如果分发的是达标数据且进行了初步质检,将没有质检记录的字段从v_taginfo标注记录中删除
  321. DeleleDataTagInfo(sourceinfo)
  322. }
  323. for _, groupInfo := range groupArr {
  324. groupId := qu.ObjToString(groupInfo["s_groupid"])
  325. groupIdArr = append(groupIdArr, groupId)
  326. givenum := qu.IntAll(groupInfo["i_givenum"])
  327. groupTaskId := primitive.NewObjectID()
  328. groupTaskIdStr := mongodb.BsonIdToSId(groupTaskId)
  329. groupTaskIdArr = append(groupTaskIdArr, groupTaskIdStr)
  330. gt := util.Task{
  331. UserId: groupId,
  332. GiveNum: givenum,
  333. }
  334. groupIdTask[groupTaskIdStr] = gt
  335. groupTask := map[string]interface{}{
  336. "_id": groupTaskId, //生成任务id
  337. "s_projectid": projectid, //项目标识
  338. "s_projectname": projectname, //项目名称
  339. "s_status": "未开始", //任务状态
  340. "s_personid": qu.ObjToString(groupInfo["s_personid"]), //任务负责人标识
  341. "s_personname": qu.ObjToString(groupInfo["s_personname"]), //任务负责人
  342. "s_groupname": qu.ObjToString(groupInfo["s_groupname"]), //用户组名称
  343. "s_groupid": groupId, //用户组标识
  344. "i_givenum": givenum, //分发数据量
  345. "s_createname": username, //创建人
  346. "i_createtime": time.Now().Unix(), //创建时间
  347. "s_progress": "0%", //完成进度
  348. "s_sourceinfo": sourceinfo, //源数据表
  349. "s_sourcetaskinfo": sourcetaskinfo, //任务日志表
  350. "s_stype": "group", //任务类型
  351. "s_entname": qu.ObjToString((*project)["s_entname"]), //公司名称
  352. "s_departname": qu.ObjToString((*project)["s_departname"]), //部门名称
  353. "s_rulename": qu.ObjToString((*project)["s_rulename"]), //规则名称
  354. }
  355. taskArr = append(taskArr, groupTask)
  356. }
  357. }
  358. if len(taskArr) > 0 {
  359. //分发数据后更新项目中用户组标识信息和用户组任务id
  360. success = util.Mgo.UpdateById(util.PROJECTCOLLNAME, projectid, map[string]interface{}{
  361. "$push": map[string]interface{}{
  362. "v_groupids": map[string]interface{}{
  363. "$each": groupIdArr,
  364. },
  365. "v_grouptaskids": map[string]interface{}{
  366. "$each": groupTaskIdArr,
  367. },
  368. },
  369. })
  370. if !success {
  371. msg = "更新项目:" + projectname + "用户组标识失败"
  372. } else { //用户组分发任务
  373. success = util.Mgo.SaveBulk(util.TASKCOLLNAME, taskArr...)
  374. if success {
  375. msg = "任务分发成功"
  376. UpdateSourceinfo(sourceinfo, sourcetaskinfo, stype, groupIdTask) //用户组分发任务成功后,给数据源打上用户组标识,同时生成任务临时表
  377. }
  378. }
  379. }
  380. qu.Debug("Success:", success, "Msg:", msg)
  381. f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
  382. }
  383. // ProjectGetEntnameList 模糊查询公司名称
  384. func (f *Front) ProjectGetEntnameList() {
  385. defer qu.Catch()
  386. var entnameList []string
  387. entname := f.GetString("entname")
  388. query := map[string]interface{}{
  389. "username": map[string]interface{}{
  390. "$regex": entname,
  391. },
  392. }
  393. list, _ := util.MgoJy.Find(util.JyUser, query, nil, map[string]interface{}{"username": 1}, false, -1, -1)
  394. for _, l := range *list {
  395. entnameList = append(entnameList, qu.ObjToString(l["username"]))
  396. }
  397. f.ServeJson(map[string]interface{}{"entname": entnameList})
  398. }
  399. // ProjectTaskRepulse 用户组任务打回
  400. // TODO 关联用户组下所有用户任务的打回
  401. func (f *Front) ProjectTaskRepulse() {
  402. defer qu.Catch()
  403. success := false
  404. msg := ""
  405. user := f.GetSession("user").(map[string]interface{})
  406. username := qu.ObjToString(user["s_name"])
  407. status := f.GetString("s_status")
  408. taskId := f.GetString("id")
  409. groupId := f.GetString("s_groupid")
  410. sourceinfo := f.GetString("s_sourceinfo")
  411. sourcetaskinfo := f.GetString("s_sourcetaskinfo")
  412. if status == "已完成" {
  413. //更新数据状态
  414. //1、更新源数据表
  415. success1 := util.Mgo.Update(sourceinfo, map[string]interface{}{"s_groupid": groupId}, map[string]interface{}{
  416. "$set": map[string]interface{}{
  417. "b_istag": false,
  418. "i_updatetime": time.Now().Unix(),
  419. },
  420. "$unset": map[string]interface{}{
  421. "s_userid": "",
  422. },
  423. }, false, true)
  424. //2、删除临时任务表中对应数据
  425. success2 := util.Mgo.Del(sourcetaskinfo, map[string]interface{}{"s_groupid": groupId})
  426. if success1 && success2 {
  427. //清除最迟完成时间,更新任务状态
  428. success = util.Mgo.UpdateById(util.TASKCOLLNAME, taskId, map[string]interface{}{
  429. "$set": map[string]interface{}{
  430. "s_status": "未开始",
  431. "s_updateperson": username,
  432. "i_updatetime": time.Now().Unix(),
  433. "s_progress": "0%",
  434. },
  435. "$unset": map[string]interface{}{
  436. "i_completetime": "",
  437. },
  438. })
  439. if !success {
  440. msg += "更新任务:" + taskId + "失败"
  441. }
  442. } else {
  443. qu.Debug("Update "+sourceinfo+":", success1, " Delete "+sourcetaskinfo+":", success2)
  444. if !success1 {
  445. msg += "更新" + sourceinfo + "数据失败;"
  446. }
  447. if !success2 {
  448. msg += "删除" + sourcetaskinfo + "数据失败;"
  449. }
  450. }
  451. }
  452. qu.Debug("Task Repulse:", success, " Msg:", msg)
  453. f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
  454. }
  455. // ProjectTaskRetrieve 用户组任务收回
  456. // TODO 关联用户组下所有用户任务的收回
  457. func (f *Front) ProjectTaskRetrieve() {
  458. defer qu.Catch()
  459. success := false
  460. msg := ""
  461. num := 0
  462. user := f.GetSession("user").(map[string]interface{})
  463. username := qu.ObjToString(user["s_name"])
  464. status := f.GetString("s_status")
  465. taskId := f.GetString("id")
  466. groupId := f.GetString("s_groupid")
  467. sourceinfo := f.GetString("s_sourceinfo")
  468. sourcetaskinfo := f.GetString("s_sourcetaskinfo")
  469. if status == "已完成" {
  470. count1 := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_groupid": groupId, "b_istag": false})
  471. count2 := util.Mgo.Count(sourcetaskinfo, map[string]interface{}{"s_groupid": groupId, "b_iscomplete": false})
  472. if count1 != count2 { //数据源表和临时表数量不一致
  473. qu.Debug("Count Is Not Same:", sourceinfo+":", count1, sourceinfo+":", count2)
  474. }
  475. num = count1
  476. if count1 == 0 { //收回数据量为0
  477. success = true
  478. //更新任务状态、完成时间
  479. success = util.Mgo.UpdateById(util.TASKCOLLNAME, taskId, map[string]interface{}{
  480. "$set": map[string]interface{}{
  481. "s_status": "已完成",
  482. "s_updateperson": username,
  483. "i_updatetime": time.Now().Unix(),
  484. "i_completetime": time.Now().Unix(),
  485. "s_progress": "100%",
  486. },
  487. })
  488. if !success {
  489. msg += "更新任务:" + taskId + "失败"
  490. }
  491. } else {
  492. //1、更新源数据表
  493. success1 := util.Mgo.Update(sourceinfo, map[string]interface{}{"s_groupid": groupId, "b_istag": false}, map[string]interface{}{
  494. "$set": map[string]interface{}{
  495. "b_isgivegroup": false,
  496. "i_updatetime": time.Now().Unix(),
  497. },
  498. "$unset": map[string]interface{}{
  499. "s_groupid": "",
  500. },
  501. }, false, true)
  502. //2、删除临时任务表中对应未完成数据
  503. success2 := util.Mgo.Del(sourcetaskinfo, map[string]interface{}{"s_groupid": groupId, "b_iscomplete": false})
  504. if success1 && success2 {
  505. //更新任务状态、完成时间
  506. success = util.Mgo.UpdateById(util.TASKCOLLNAME, taskId, map[string]interface{}{
  507. "$set": map[string]interface{}{
  508. "s_status": "已完成",
  509. "s_updateperson": username,
  510. "i_updatetime": time.Now().Unix(),
  511. "i_completetime": time.Now().Unix(),
  512. },
  513. })
  514. if !success {
  515. msg += "更新任务:" + taskId + "失败"
  516. }
  517. } else {
  518. qu.Debug("Update "+sourceinfo+":", success1, " Delete "+sourcetaskinfo+":", success2)
  519. if !success1 {
  520. msg += "更新" + sourceinfo + "数据失败;"
  521. }
  522. if !success2 {
  523. msg += "删除" + sourcetaskinfo + "数据失败;"
  524. }
  525. }
  526. }
  527. }
  528. qu.Debug("Task Retrieve:", success, " num:", num, " Msg:", msg)
  529. f.ServeJson(map[string]interface{}{"success": success, "msg": msg, "num": num})
  530. }
  531. // ProjectTaskClose 用户组任务关闭
  532. func (f *Front) ProjectTaskClose() {
  533. defer qu.Catch()
  534. success := false
  535. user := f.GetSession("user").(map[string]interface{})
  536. username := qu.ObjToString(user["s_name"])
  537. status := f.GetString("s_status")
  538. taskId := f.GetString("id")
  539. if status == "已完成" {
  540. //更新任务状态
  541. success = util.Mgo.UpdateById(util.TASKCOLLNAME, taskId, map[string]interface{}{
  542. "$set": map[string]interface{}{
  543. "s_status": "已关闭",
  544. "s_updateperson": username,
  545. "i_updatetime": time.Now().Unix(),
  546. "s_progress": "100%",
  547. },
  548. })
  549. }
  550. f.ServeJson(map[string]interface{}{"success": success})
  551. }
  552. // DeleleDataTagInfo 删除标注记录
  553. func DeleleDataTagInfo(sourceinfo string) {
  554. defer qu.Catch()
  555. sess := util.Mgo.GetMgoConn()
  556. defer util.Mgo.DestoryMongoConn(sess)
  557. ch := make(chan bool, 5)
  558. wg := &sync.WaitGroup{}
  559. lock := &sync.Mutex{}
  560. query := map[string]interface{}{ //达标数据可能会分发后收回、打回再分发
  561. "b_istagging": false, //达标数据
  562. "b_cleartag": false, //未进行一次标注信息清理
  563. }
  564. fields := map[string]interface{}{
  565. "v_taginfo": 1,
  566. "v_check": 1,
  567. }
  568. updateArr := [][]map[string]interface{}{}
  569. it := sess.DB(util.Mgo.DbName).C(sourceinfo).Find(&query).Select(&fields).Iter()
  570. count, _ := sess.DB(util.Mgo.DbName).C(sourceinfo).Find(&query).Count()
  571. qu.Debug("Find Needs To Clearn Data Count:", count)
  572. n := 0
  573. for tmp := make(map[string]interface{}); it.Next(tmp); n++ {
  574. ch <- true
  575. wg.Add(1)
  576. go func(tmp map[string]interface{}) {
  577. defer func() {
  578. <-ch
  579. wg.Done()
  580. }()
  581. update := []map[string]interface{}{}
  582. update = append(update, map[string]interface{}{"_id": tmp["_id"]})
  583. tagInfo, _ := tmp["v_taginfo"].(map[string]interface{})
  584. checkInfo, _ := tmp["v_check"].(map[string]interface{})
  585. id := mongodb.BsonIdToSId(tmp["_id"])
  586. if id == "60b99c2d72c25c51c492af6a" {
  587. qu.Debug(tagInfo, checkInfo)
  588. }
  589. set := map[string]interface{}{
  590. "b_cleartag": true,
  591. }
  592. if len(tagInfo) != 0 && len(checkInfo) != 0 {
  593. for f, _ := range tagInfo {
  594. if checkInfo[f] == nil {
  595. delete(tagInfo, f)
  596. }
  597. }
  598. set["v_taginfo"] = tagInfo
  599. }
  600. update = append(update, map[string]interface{}{
  601. "$set": map[string]interface{}{
  602. "v_taginfo": tagInfo,
  603. },
  604. })
  605. lock.Lock()
  606. updateArr = append(updateArr, update)
  607. if len(updateArr) > 500 {
  608. util.Mgo.UpdateBulk(sourceinfo, updateArr...)
  609. updateArr = [][]map[string]interface{}{}
  610. }
  611. lock.Unlock()
  612. }(tmp)
  613. if n%100 == 0 {
  614. qu.Debug("current:", n)
  615. }
  616. tmp = map[string]interface{}{}
  617. }
  618. wg.Wait()
  619. lock.Lock()
  620. if len(updateArr) > 0 {
  621. util.Mgo.UpdateBulk(sourceinfo, updateArr...)
  622. updateArr = [][]map[string]interface{}{}
  623. }
  624. lock.Unlock()
  625. }
  626. // UpdateSourceinfo 用户组分发任务成功后,给数据源打上用户组标识,同时生成任务临时表
  627. func UpdateSourceinfo(sourceinfo, sourcetaskinfo, stype string, groupIdInfo map[string]util.Task) {
  628. defer qu.Catch()
  629. for groupTaskId, tInfo := range groupIdInfo {
  630. groupId := tInfo.UserId
  631. num := tInfo.GiveNum
  632. sess := util.Mgo.GetMgoConn()
  633. defer util.Mgo.DestoryMongoConn(sess)
  634. ch := make(chan bool, 5)
  635. wg := &sync.WaitGroup{}
  636. lock := &sync.Mutex{}
  637. query := map[string]interface{}{ //查找未分配对应stype的数据分发
  638. "b_isgivegroup": false,
  639. }
  640. if stype == "notag" { //达标数据
  641. query["b_istagging"] = false
  642. } else if stype == "tag" { //未达标数据
  643. query["b_istagging"] = true
  644. }
  645. fields := map[string]interface{}{
  646. "title": 1,
  647. }
  648. saveArr := []map[string]interface{}{}
  649. updateArr := [][]map[string]interface{}{}
  650. qu.Debug("Query:", query)
  651. it := sess.DB(util.Mgo.DbName).C(sourceinfo).Find(&query).Select(&fields).Limit(int64(num)).Iter()
  652. n := 0
  653. for tmp := make(map[string]interface{}); it.Next(tmp); n++ {
  654. ch <- true
  655. wg.Add(1)
  656. go func(tmp map[string]interface{}) {
  657. defer func() {
  658. <-ch
  659. wg.Done()
  660. }()
  661. id := mongodb.BsonIdToSId(tmp["_id"])
  662. title := qu.ObjToString(tmp["title"])
  663. update := []map[string]interface{}{}
  664. update = append(update, map[string]interface{}{"_id": tmp["_id"]})
  665. update = append(update, map[string]interface{}{
  666. "$set": map[string]interface{}{
  667. "s_groupid": groupId,
  668. "b_isgivegroup": true,
  669. "i_updatetime": time.Now().Unix(),
  670. },
  671. })
  672. save := map[string]interface{}{
  673. "s_infoid": id,
  674. "s_infotitle": title,
  675. "s_groupid": groupId,
  676. "i_createtime": time.Now().Unix(),
  677. "b_iscomplete": false,
  678. "s_grouptaskid": groupTaskId,
  679. "b_isgiveuser": false,
  680. }
  681. lock.Lock()
  682. updateArr = append(updateArr, update)
  683. saveArr = append(saveArr, save)
  684. if len(updateArr) > 500 {
  685. util.Mgo.UpdateBulk(sourceinfo, updateArr...)
  686. updateArr = [][]map[string]interface{}{}
  687. }
  688. if len(saveArr) > 500 {
  689. util.Mgo.SaveBulk(sourcetaskinfo, saveArr...)
  690. saveArr = []map[string]interface{}{}
  691. }
  692. lock.Unlock()
  693. }(tmp)
  694. if n%100 == 0 {
  695. qu.Debug("current:", n)
  696. }
  697. tmp = map[string]interface{}{}
  698. }
  699. wg.Wait()
  700. lock.Lock()
  701. if len(updateArr) > 0 {
  702. util.Mgo.UpdateBulk(sourceinfo, updateArr...)
  703. updateArr = [][]map[string]interface{}{}
  704. }
  705. if len(saveArr) > 0 {
  706. util.Mgo.SaveBulk(sourcetaskinfo, saveArr...)
  707. saveArr = []map[string]interface{}{}
  708. }
  709. lock.Unlock()
  710. }
  711. }
  712. //ImportDataByExcel 通过excel获取数据源
  713. func ImportDataByExcel(s_sourceinfo string, mf multipart.File, success *bool, msg *string, successNum *int64) (importDataNum int) {
  714. defer qu.Catch()
  715. binary, _ := ioutil.ReadAll(mf)
  716. xls, _ := xlsx.OpenBinary(binary)
  717. sheet := xls.Sheets[0]
  718. rows := sheet.Rows
  719. idcolnum := -1
  720. cellFieldName := map[int]string{} //记录客户需求字段所在的列
  721. idInfoMap := map[string]map[string]interface{}{} //记录数据id及需要保存的字段信息
  722. for rn, row := range rows {
  723. if rn == 0 {
  724. for index, cell := range row.Cells {
  725. title := cell.Value
  726. if fieldName := util.CustomerFieldMap_HE[title]; fieldName != "" { //客户需求字段
  727. cellFieldName[index] = fieldName
  728. }
  729. if title == "唯一标识" || title == "信息标识" { //id所在列
  730. idcolnum = index
  731. }
  732. }
  733. if idcolnum == -1 {
  734. break
  735. }
  736. continue
  737. }
  738. if len(row.Cells) < len(rows[0].Cells) {
  739. break
  740. }
  741. tmp := map[string]interface{}{}
  742. for index, f := range cellFieldName {
  743. if val := row.Cells[index].Value; val != "" {
  744. if f == "capital" { //注册资金(万元)
  745. cf, _ := row.Cells[index].Float()
  746. tmp[f] = cf
  747. } else if f == "createtime" { //创建时间
  748. ci, _ := row.Cells[index].Int64()
  749. tmp[f] = ci
  750. } else {
  751. tmp[f] = val
  752. }
  753. }
  754. }
  755. id := row.Cells[idcolnum].String() //加密的id
  756. if id == "" {
  757. break
  758. }
  759. id = util.SE.DecodeString(id) //解密后id
  760. idInfoMap[id] = tmp
  761. }
  762. importDataNum = len(idInfoMap)
  763. qu.Debug("Load Excel Count:", importDataNum)
  764. if importDataNum > 0 {
  765. GetDataById(idInfoMap, "excel", s_sourceinfo, success, msg, successNum)
  766. } else {
  767. *success = false
  768. *msg = "查询数据失败"
  769. }
  770. idInfoMap = map[string]map[string]interface{}{}
  771. return
  772. }
  773. //ImportDataByColl 通过表获取数据源
  774. func ImportDataByColl(s_sourceinfo, historyid string, success *bool, msg *string, successNum *int64) (departname, entname string, rulename []string, importDataNum int) {
  775. defer qu.Catch()
  776. rulenameMap := map[string]bool{}
  777. sess := util.MgoJy.GetMgoConn()
  778. defer util.MgoJy.DestoryMongoConn(sess)
  779. ch := make(chan bool, 3)
  780. wg := &sync.WaitGroup{}
  781. lock := &sync.Mutex{}
  782. idInfoMap := map[string]map[string]interface{}{} //记录数据id及需要保存的字段信息
  783. query := map[string]interface{}{
  784. "historyId": historyid,
  785. }
  786. it := sess.DB(util.MgoJy.DbName).C(util.JyHistory).Find(&query).Iter()
  787. n := 0
  788. for tmp := make(map[string]interface{}); it.Next(tmp); n++ {
  789. ch <- true
  790. wg.Add(1)
  791. go func(tmp map[string]interface{}) {
  792. defer func() {
  793. <-ch
  794. wg.Done()
  795. }()
  796. id := qu.ObjToString(tmp["id"]) //bidding id
  797. appid := qu.ObjToString(tmp["appid"]) //根据appid查user表获取公司名称
  798. departname = qu.ObjToString(tmp["departname"]) //部门名称。所有数据都应部门名称,若不一致,随机取
  799. needField := map[string]interface{}{}
  800. for f, _ := range util.CustomerFieldMap_EH {
  801. if tmp[f] != nil {
  802. needField[f] = tmp[f]
  803. }
  804. }
  805. if entname == "" { //获取一次公司名称即可
  806. user, _ := util.MgoJy.FindOne(util.JyUser, map[string]interface{}{"appid": appid})
  807. entname = qu.ObjToString((*user)["username"]) //公司名称
  808. }
  809. rname := qu.ObjToString(tmp["rulename"])
  810. lock.Lock()
  811. rulenameMap[rname] = true
  812. //rulename = append(rulename, qu.ObjToString(tmp["rulename"])) //规则名称
  813. idInfoMap[id] = needField
  814. lock.Unlock()
  815. }(tmp)
  816. if n%100 == 0 {
  817. qu.Debug("current:", n)
  818. }
  819. tmp = map[string]interface{}{}
  820. }
  821. wg.Wait()
  822. for r, _ := range rulenameMap {
  823. rulename = append(rulename, r)
  824. }
  825. importDataNum = len(idInfoMap) //查询数据总数
  826. if importDataNum > 0 {
  827. GetDataById(idInfoMap, "coll", s_sourceinfo, success, msg, successNum)
  828. } else {
  829. *msg = "查询数据失败"
  830. }
  831. idInfoMap = map[string]map[string]interface{}{}
  832. return
  833. }
  834. //GetDataById 通过id集从bidding、extract、project获取数据所有信息
  835. func GetDataById(idsInfo map[string]map[string]interface{}, importType, s_sourceinfo string, success *bool, msg *string, successNum *int64) {
  836. *success = true
  837. var msgArr []string
  838. wg := &sync.WaitGroup{}
  839. lock := &sync.Mutex{}
  840. ch := make(chan bool, 10)
  841. num := int64(0) //计数
  842. for id, info := range idsInfo {
  843. wg.Add(1)
  844. ch <- true
  845. go func(id string, tmp map[string]interface{}) {
  846. defer func() {
  847. wg.Done()
  848. <-ch
  849. }()
  850. /*
  851. 1.查bidding
  852. 2.查extract
  853. 3.extract合并到bidding(删除item字段与客户需要的item不是一个含义)
  854. 4.对比marked表,替换已标注过的字段值,补充标记
  855. 5.合并客户所需字段信息,补充id字段
  856. //6.若为同步时,删除原有id对应的信息,新增该id对应的_id信息
  857. 6.mgo查询项目信息
  858. */
  859. tagInfoMap := map[string]interface{}{} //记录数据已标注过的信息
  860. baseInfoMap := map[string]interface{}{} //记录其他信息
  861. //1.查bidding
  862. tmpBidColl := util.BidColl1 //bidding
  863. //查询bidding
  864. if id < util.BIDDINGSTARTID {
  865. tmpBidColl = util.BidColl2 //bidding_back
  866. }
  867. bidData, _ := util.MgoB.FindById(tmpBidColl, id, nil)
  868. if bidData != nil && len(*bidData) > 0 { //bidding表数据存在
  869. //2.查extract
  870. extData, _ := util.MgoE.FindById(util.ExtColl1, id, nil)
  871. if extData == nil || len(*extData) == 0 {
  872. extData, _ = util.MgoE.FindById(util.ExtColl2, id, nil)
  873. }
  874. //抽取表字段合并到bidding
  875. if extData != nil && len(*extData) > 0 {
  876. for k, v := range *extData {
  877. (*bidData)[k] = v
  878. }
  879. }
  880. //3.删除item
  881. //删除item
  882. delete((*bidData), "item")
  883. //4.对比marked表,对比marked表是否已标注该数据
  884. markData, _ := util.Mgo.FindById(util.AllToColl, id, nil)
  885. if markData != nil && len(*markData) > 0 {
  886. UpdateMarkColl(bidData, markData, &tagInfoMap, &baseInfoMap) //比对更新数据
  887. } else {
  888. baseInfoMap["i_ckdata"] = 0 //设置ck_data默认值0
  889. //多包、中标候选人、标的信息是否抽取
  890. //if packageMap, ok := (*bidData)["package"].(map[string]interface{}); ok && len(packageMap) > 0 {
  891. // baseInfoMap["b_pkgisext"] = true
  892. //} else {
  893. // baseInfoMap["b_pkgisext"] = false
  894. //}
  895. //if winorderArr, ok := (*bidData)["winnerorder"].([]interface{}); ok && len(winorderArr) > 0 {
  896. // baseInfoMap["b_wodrisext"] = true
  897. //} else {
  898. // baseInfoMap["b_wodrisext"] = false
  899. //}
  900. //if purchArr, ok := (*bidData)["purchasinglist"].([]interface{}); ok && len(purchArr) > 0 {
  901. // baseInfoMap["b_pclisext"] = true
  902. //} else {
  903. // baseInfoMap["b_pclisext"] = false
  904. //}
  905. }
  906. //合并导入表中客户所需的字段
  907. if len(tmp) > 0 {
  908. for k, v := range tmp {
  909. (*bidData)[k] = v
  910. }
  911. }
  912. //补充id
  913. //(*bidData)["id"] = id
  914. //if stype == "syncoll" { //同步数据时删除原始数据
  915. // if util.MgoM.Delete(coll, `{"id":"`+id+`"}`) == 0 {
  916. // lock.Lock()
  917. // *msg += "同步未删除成功数据id:" + id + ";\n"
  918. // *success = false
  919. // lock.Unlock()
  920. // }
  921. //}
  922. // 处理 package winner_all
  923. if p, o1 := (*bidData)["package"].(map[string]interface{}); o1 {
  924. for _, v := range p {
  925. v1 := v.(map[string]interface{})
  926. t := make(map[string]interface{})
  927. if v1["winner"] != nil {
  928. t["winner"] = v1["winner"]
  929. }
  930. if v1["bidamount"] != nil {
  931. t["bidamount"] = qu.Float64All(v1["bidamount"])
  932. }
  933. if len(t) > 0 {
  934. v1["winner_all"] = append([]map[string]interface{}{}, t)
  935. }
  936. }
  937. }
  938. // 补充filetext
  939. (*bidData)["filetext"] = util.GetFileText(*bidData)
  940. // 6.es查询项目合并信息
  941. //esQ := `{"query":{"bool":{"must":[{"term":{"ids":"` + id + `"}}]}}}`
  942. //info := util.Es.Get("projectset", "projectset", esQ)
  943. projectId := qu.ObjToString((*bidData)["projectId"])
  944. project, _ := util.MgoE.FindById(util.ProjectColl, projectId, map[string]interface{}{"ids": 1})
  945. if project != nil && len(*project) > 0 {
  946. ids := qu.ObjArrToStringArr((*project)["ids"].([]interface{}))
  947. if len(ids) > 0 {
  948. var infolist []map[string]interface{}
  949. for _, v := range ids {
  950. if v == id { // 当前公告
  951. continue
  952. }
  953. if v < util.BIDDINGSTARTID {
  954. tmpBidColl = util.BidColl2 //bidding_back
  955. }
  956. bid, b := util.MgoB.FindById(tmpBidColl, v, nil)
  957. if b && len(*bid) > 0 {
  958. tmp := make(map[string]interface{})
  959. tmp["id"] = v
  960. tmp["title"] = (*bid)["title"]
  961. tmp["href"] = (*bid)["href"]
  962. tmp["toptype"] = (*bid)["toptype"]
  963. tmp["subtype"] = (*bid)["subtype"]
  964. tmp["publishtime"] = (*bid)["publishtime"]
  965. tmp["detail"] = (*bid)["detail"]
  966. tmp["filetext"] = util.GetFileText(*bid)
  967. infolist = append(infolist, tmp)
  968. }
  969. }
  970. (*bidData)["info"] = infolist
  971. }
  972. } else {
  973. qu.Debug("Projectset Find Error", projectId)
  974. }
  975. baseInfoMap["id"] = id
  976. _id := (*bidData)["_id"]
  977. delete(*bidData, "_id")
  978. //保存数据
  979. baseInfoMap["_id"] = _id
  980. baseInfoMap["v_baseinfo"] = bidData
  981. if len(tagInfoMap) > 0 {
  982. baseInfoMap["v_taginfo"] = tagInfoMap
  983. }
  984. baseInfoMap["i_createtime"] = time.Now().Unix()
  985. baseInfoMap["b_isgivegroup"] = false //是否分配
  986. baseInfoMap["b_istag"] = false //是否已标注
  987. baseInfoMap["b_cleartag"] = false //是否清理标注信息
  988. if util.Mgo.SaveByOriID(s_sourceinfo, baseInfoMap) {
  989. atomic.AddInt64(successNum, 1) //保存成功计数
  990. } else {
  991. lock.Lock()
  992. *success = false
  993. if importType == "excel" {
  994. msgArr = append(msgArr, "第"+fmt.Sprint(num+2)+"行未导入id:"+id)
  995. //*msg += "第" + fmt.Sprint(num+2) + "行未保存成功数据_id:" + id + ";\n"
  996. } else {
  997. msgArr = append(msgArr, "未导入id:"+id)
  998. //*msg += "未保存成功数据_id:" + id + ";\n"
  999. }
  1000. lock.Unlock()
  1001. }
  1002. } else {
  1003. lock.Lock()
  1004. *success = false
  1005. if importType == "excel" {
  1006. msgArr = append(msgArr, "第"+fmt.Sprint(num+2)+"行未查询id:"+id)
  1007. //*msg += "第" + fmt.Sprint(num+2) + "行未查询到数据:" + id + ";\n"
  1008. } else {
  1009. msgArr = append(msgArr, "未查询id:"+id)
  1010. //*msg += "未查询到数据_id:" + id + ";\n"
  1011. }
  1012. lock.Unlock()
  1013. }
  1014. }(id, info)
  1015. }
  1016. wg.Wait()
  1017. sort.Strings(msgArr)
  1018. *msg = strings.Join(msgArr, ";\n")
  1019. }
  1020. // UpdateMarkColl 更新数据
  1021. func UpdateMarkColl(bidData, markData, tagInfoMap, baseInfoMap *map[string]interface{}) {
  1022. defer qu.Catch()
  1023. ckdata := qu.IntAll((*markData)["i_ckdata"])
  1024. v_taginfo := (*markData)["v_taginfo"].(map[string]interface{}) //标注信息
  1025. v_datainfo := (*markData)["v_datainfo"].(map[string]interface{}) //基本信息
  1026. for fk, _ := range v_taginfo {
  1027. if v_datainfo[fk] != nil {
  1028. (*bidData)[fk] = v_datainfo[fk] //字段更新
  1029. }
  1030. }
  1031. (*tagInfoMap) = v_taginfo //marked中已有的标注信息保存到新数据上
  1032. if ckdata == 2 { //某些字段已标注
  1033. (*baseInfoMap)["i_ckdata"] = 0 //marked表中该条数据如果为字段验证,临时表ck_data:0;若为数据验证ck_data:1
  1034. } else if ckdata == 1 {
  1035. (*baseInfoMap)["i_ckdata"] = 1
  1036. }
  1037. }