mxs 1 жил өмнө
parent
commit
f0fd98341c

+ 240 - 0
src/front/claim.go

@@ -0,0 +1,240 @@
+package front
+
+import (
+	"fmt"
+	qu "qfw/util"
+	"strings"
+	"sync"
+	"time"
+	. "util"
+)
+
+var (
+	//爬虫认领
+	ClaimMaxNum        = 10 //已认领爬虫上限
+	ClaimLock          = &sync.Mutex{}
+	ClaimPriorityLimit = 350 //区分外包和内部人员认领爬虫的优先级界限
+	ClaimQueryFields   = map[string]interface{}{
+		"site":            1,
+		"code":            1,
+		"channel":         1,
+		"priority":        1,
+		"spiderimportant": 1,
+		"modifyuser":      1,
+		"claimtime":       1,
+		"claimtype":       1,
+		"recovertime":     1,
+		//"grade":           1,
+	}
+)
+
+//type ClaimLog struct {
+//	Site             string `bson:"site"`
+//	Code             string `bson:"code"`
+//	Channel          string `bson:"channel"`
+//	ModifyUser       string `bson:"modifyuser"`
+//	Priority         int    `bson:"priority"`
+//	Comeintime       int64  `bson:"comeintime"`
+//	Important        bool   `bson:"important"`
+//	ClaimTime        int64  `bson:"claimtime"`
+//	RecoverTime      int64  `bson:"recovertime"`
+//	ReturnTime       int64  `bson:"returntime"`
+//	Stype            string `bson:"stype"`            //认领、回收、归还
+//	ReturnReason     string `bson:"returnreason"`     //归还原因
+//	ClaimRecoverType int    `bson:"claimrecovertype"` //认领或回收类型 1:主动;0:被动(爬虫分配)
+//}
+
+const CLAIMTYPEUNCLAIMED, CLAIMTYPECLAIMED, CLAIMTYPEHISTORY = 0, 1, 2 //未认领、已认领、历史爬虫
+
+func (f *Front) ClaimCode() {
+	ClaimLock.Lock()
+	defer ClaimLock.Unlock()
+	modifyuser := f.GetSession("loginuser")
+	identity := qu.IntAll(f.GetSession("identity"))
+	//1、已认领爬虫个数
+	q := map[string]interface{}{
+		"modifyuser": modifyuser,
+		"claimtype":  CLAIMTYPECLAIMED,
+		"state": map[string]interface{}{
+			"$in": []int{0, 2}, //待完成、未通过
+		},
+		"platform": map[string]interface{}{
+			"$nin": []string{"通用爬虫", "python"},
+		},
+	}
+	num := MgoEB.Count("luaconfig", q)
+	if num >= ClaimMaxNum {
+		f.ServeJson(map[string]interface{}{"msg": "已超爬虫认领上限!", "ok": false})
+		return
+	}
+	//2、认领爬虫逻辑
+	q = map[string]interface{}{
+		"claimtype": CLAIMTYPEUNCLAIMED, //待认领
+		"platform": map[string]interface{}{
+			"$nin": []string{"通用爬虫", "python"},
+		},
+	}
+
+	s := 1
+	if identity == 1 { //内部人员
+		s = -1
+		q["priority"] = map[string]interface{}{
+			"$gte": ClaimPriorityLimit,
+		}
+	} else { //外包指定优先级范围且简单的爬虫(若爬虫导入同站点爬虫有重点和非重点的爬虫,会被外包认领)
+		q["priority"] = map[string]interface{}{
+			"$gt": 0,
+			"$lt": ClaimPriorityLimit,
+		}
+		q["grade"] = 0
+	}
+	sort := map[string]interface{}{
+		"priority": s,
+	}
+	qu.Debug(f.GetSession("loginuser"), "认领爬虫:", q)
+	lua, _ := MgoEB.Find("luaconfig", q, sort, ClaimQueryFields, false, -1, -1)
+	if len(*lua) > 0 {
+		claimNum := 0                  //本次认领爬虫个数
+		claimSite := map[string]bool{} //本次认领的站点
+		for _, l := range *lua {
+			site := qu.ObjToString(l["site"])
+			if claimSite[site] {
+				continue
+			}
+			claimSite[site] = true
+			q["site"] = site //查询指定站点爬虫
+			//delete(q, "priority") //这里不限制优先级
+			tmpLua, _ := MgoEB.Find("luaconfig", q, nil, ClaimQueryFields, false, -1, -1)
+			claimNum += len(*tmpLua)
+			//更新数据、新增日志
+			UpdateCodeAndSaveLog(*tmpLua, f)
+			if num+claimNum >= ClaimMaxNum {
+				break
+			}
+		}
+		f.ServeJson(map[string]interface{}{"msg": "成功认领爬虫" + fmt.Sprint(claimNum) + "个", "ok": true})
+		return
+	}
+	f.ServeJson(map[string]interface{}{"msg": "暂无可认领爬虫!", "ok": false})
+}
+
+func (f *Front) ReturnCode() {
+	identity := qu.IntAll(f.GetSession("identity"))
+	if identity != 0 {
+		f.ServeJson(map[string]interface{}{"msg": "无权限归还爬虫!", "ok": false})
+		return
+	}
+	codes := f.GetString("codes")
+	returnreason := f.GetString("returnreason")
+	qu.Debug(codes)
+	cs := strings.Split(codes, ",")
+	q := map[string]interface{}{
+		"code": map[string]interface{}{
+			"$in": cs,
+		},
+	}
+	luas, _ := MgoEB.Find("luaconfig", q, nil, ClaimQueryFields, false, -1, -1)
+	if len(*luas) > 0 {
+		update := [][]map[string]interface{}{}
+		save := []map[string]interface{}{}
+		for _, l := range *luas {
+			now := time.Now().Unix()
+			up := []map[string]interface{}{
+				{"code": l["code"]},
+				{"$set": map[string]interface{}{
+					"claimtype":   CLAIMTYPEUNCLAIMED,
+					"claimtime":   int64(0),
+					"recovertime": int64(0),
+					"grade":       1, //外包归还爬虫后,爬虫难易度更新为困难
+				}},
+			}
+			update = append(update, up)
+			save = append(save, map[string]interface{}{
+				"site":             l["site"],
+				"code":             l["code"],
+				"channel":          l["channel"],
+				"modifyuser":       l["modifyuser"],
+				"priority":         l["priority"],
+				"stype":            "归还",
+				"comeintime":       now,
+				"claimtime":        l["claimtime"],
+				"recovertime":      l["recovertime"],
+				"returntime":       now,
+				"important":        l["spiderimportant"],
+				"returnreason":     returnreason,
+				"claimrecovertype": 1,
+			})
+		}
+		//更新爬虫信息
+		MgoEB.UpdateBulk("luaconfig", update...)
+		//保存认领日志
+		MgoEB.SaveBulk("lua_logs_claim", save...)
+		f.ServeJson(map[string]interface{}{"msg": "爬虫归还成功!", "ok": true})
+		return
+	}
+	f.ServeJson(map[string]interface{}{"msg": "爬虫归还失败!", "ok": false})
+}
+
+func UpdateCodeAndSaveLog(lua []map[string]interface{}, f *Front) {
+	update := [][]map[string]interface{}{}
+	save := []map[string]interface{}{}
+	for _, l := range lua {
+		loginuser := f.GetSession("loginuser")
+		userid := f.GetSession("userid")
+		priority := qu.IntAll(l["priority"])
+		spiderimportant, _ := l["spiderimportant"].(bool)
+		recovertime := CreateRecovertime(spiderimportant, priority)
+		now := time.Now().Unix()
+		up := []map[string]interface{}{
+			{"code": l["code"]},
+			{"$set": map[string]interface{}{
+				"claimtype":       CLAIMTYPECLAIMED,
+				"createuseremail": f.GetSession("email"),
+				"createuser":      loginuser,
+				"createuserid":    userid,
+				"modifyuser":      loginuser,
+				"modifyuserid":    userid,
+				"claimtime":       now,
+				"recovertime":     recovertime,
+			}},
+		}
+		update = append(update, up)
+		save = append(save, map[string]interface{}{
+			"site":             l["site"],
+			"code":             l["code"],
+			"channel":          l["channel"],
+			"modifyuser":       loginuser,
+			"priority":         priority,
+			"stype":            "认领",
+			"comeintime":       now,
+			"claimtime":        now,
+			"recovertime":      recovertime,
+			"returntime":       int64(0),
+			"important":        spiderimportant,
+			"returnreason":     "",
+			"claimrecovertype": 1,
+		})
+	}
+	//更新爬虫信息
+	MgoEB.UpdateBulk("luaconfig", update...)
+	//保存认领日志
+	MgoEB.SaveBulk("lua_logs_claim", save...)
+}
+
+// CreateRecovertime 生成归还时间
+func CreateRecovertime(important bool, priority int) int64 {
+	if important || priority >= ClaimPriorityLimit {
+		return time.Now().Add(24 * time.Hour).Unix()
+	} else {
+		return time.Now().Add(24 * 5 * time.Hour).Unix()
+	}
+}
+
+// UpdateLuaClaimtype 更新爬虫认领状态
+func UpdateLuaClaimtype(code string) {
+	MgoEB.Update("luaconfig", map[string]interface{}{"code": code}, map[string]interface{}{"$set": map[string]interface{}{
+		"claimtype":   CLAIMTYPEHISTORY,
+		"claimtime":   int64(0),
+		"recovertime": int64(0),
+	}}, false, false)
+}

+ 141 - 70
src/front/front.go

@@ -86,6 +86,10 @@ type Front struct {
 	//补采信息
 	supplementDayList  xweb.Mapper `xweb:"/center/supplement/daylist"`  //日补采列表
 	supplementWeekList xweb.Mapper `xweb:"/center/supplement/weeklist"` //周补采列表
+
+	//爬虫认领
+	claimCode  xweb.Mapper `xweb:"/center/claim/claimcode"`  //爬虫认领
+	returnCode xweb.Mapper `xweb:"/center/claim/returncode"` //爬虫归还
 }
 
 const Sp_state_0, Sp_state_1, Sp_state_2, Sp_state_3, Sp_state_4, Sp_state_5, Sp_state_6, Sp_state_7, Sp_state_8, Sp_state_9, Sp_state_10 = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 //0待完成,1待审核,2打回,3发布,4作废,5已上架,6已下架,7无发布,8需登录,9转python,10已删除
@@ -98,7 +102,7 @@ var Reg = regexp.MustCompile(`(http|https)://([\w]+\.)+[\w]+`)
 var ProjectHrefReg = regexp.MustCompile("projecthref")
 var Transfercode map[string]interface{}
 
-// 控制中心
+// 爬虫列表
 func (f *Front) LoadIndex() {
 	auth := qu.IntAll(f.GetSession("auth"))
 	if f.Method() == "POST" {
@@ -107,27 +111,37 @@ func (f *Front) LoadIndex() {
 		draw, _ := f.GetInteger("draw")
 		searchStr := f.GetString("search[value]")
 		event, _ := f.GetInteger("taskEvent") //节点
-		//searchN := strings.Replace(searchStr, " ", "", -1)
-		//search := strings.Replace(searchN, "\n", "", -1)
 		search := strings.TrimSpace(searchStr)
 		state, _ := f.GetInteger("state")
-		urgency, _ := f.GetInteger("urgency") //节点
 		platform := f.GetString("platform")
 		modifyuser := f.GetString("modifyuser")
-		infoformat, _ := f.GetInteger("infoformat") //节点
+		infoformat, _ := f.GetInteger("infoformat") //招标类型
+		priority := f.GetString("priority")         //优先级
 		query := map[string]interface{}{}
 		if event > -1 {
 			query["event"] = event
 		}
-		if urgency > -1 {
-			query["urgency"] = urgency
-		}
 		if platform != "-1" {
 			query["platform"] = platform
 		}
 		if modifyuser != "-1" {
 			query["modifyuser"] = modifyuser
 		}
+		if priority != "-1" {
+			priorityRange := strings.Split(priority, "-")
+			gte := qu.IntAll(priorityRange[0])
+			lt := qu.IntAll(priorityRange[1])
+			q := map[string]interface{}{}
+			if lt == 0 {
+				q["$gte"] = gte
+			} else {
+				q = map[string]interface{}{
+					"$gte": gte,
+					"$lt":  lt,
+				}
+			}
+			query["priority"] = q
+		}
 		if infoformat > -1 {
 			query["infoformat"] = infoformat
 		}
@@ -143,7 +157,14 @@ func (f *Front) LoadIndex() {
 				query["state"] = state
 			}
 			query["createuserid"] = f.GetSession("userid")
+			query["claimtype"] = map[string]interface{}{ //爬虫开发只能搜索已认领和历史爬虫
+				"$gte": CLAIMTYPECLAIMED,
+			}
 		} else {
+			claimtype, _ := f.GetInteger("claimtype") //认领状态
+			if claimtype > -1 {
+				query["claimtype"] = claimtype
+			}
 			identity := qu.IntAll(f.GetSession("identity"))
 			if identity == 0 { //外包管理员
 				ids := []string{}
@@ -160,24 +181,6 @@ func (f *Front) LoadIndex() {
 				query["state"] = Sp_state_1
 			}
 		}
-		//if auth == u.Role_Examine { //审核员
-		//	if state > -1 {
-		//		query["state"] = state
-		//	} else {
-		//		query["state"] = Sp_state_1
-		//	}
-		//
-		//} else if auth == u.Role_Dev { //开发员
-		//	if state > -1 {
-		//		query["state"] = state
-		//	}
-		//	query["createuserid"] = f.GetSession("userid")
-		//
-		//} else { //管理员
-		//	if state > -1 {
-		//		query["state"] = state
-		//	}
-		//}
 		sort := `{"%s":%d}`
 		orderIndex := f.GetString("order[0][column]")
 		orderName := f.GetString(fmt.Sprintf("columns[%s][data]", orderIndex))
@@ -198,14 +201,6 @@ func (f *Front) LoadIndex() {
 		count := u.MgoEB.Count("luaconfig", query)
 		for k, v := range *luas {
 			v["num"] = k + 1 + page*10
-			if v["modifytime"] != nil {
-				v["modifytime"] = time.Unix(v["modifytime"].(int64), 0).Format("2006-01-02 15:04:05")
-			} else {
-				v["modifytime"] = "-"
-			}
-			if v["modifyuser"] == nil {
-				v["modifytime"] = "-"
-			}
 			v["encode"] = util.Se.Encode2Hex(fmt.Sprint(v["code"]))
 			if v["event"] == nil { //节点
 				v["event"] = 0
@@ -220,6 +215,15 @@ func (f *Front) LoadIndex() {
 		for k, _ := range util.Config.Uploadevents {
 			events = append(events, k)
 		}
+		identity := qu.IntAll(f.GetSession("identity"))
+		ids := []string{}
+		if identity == 0 && auth > u.Role_Dev { //外包管理员
+			if tmpIds := f.GetSession("ids"); tmpIds != nil {
+				ids = qu.ObjArrToStringArr(tmpIds.([]interface{}))
+			}
+		}
+		f.T["identity"] = identity
+		f.T["ids"] = ids
 		f.T["modifyusers"] = u.GetModifyUsers()
 		sort.Strings(events)
 		f.T["events"] = events
@@ -331,10 +335,8 @@ func (f *Front) ImportLua() {
 							//continue
 						}
 						o["channeladdr"] = href
-						o["author"] = cells[5].Value
 						o["timestamp"] = time.Now().Unix()
-						o["status"] = 1
-						o["next"] = cells[5].Value
+						o["modifyuser"] = cells[5].Value
 						o["event"] = cells[6].Value
 						o["incrementevent"] = cells[7].Value
 						if cells[8].Value == "是" {
@@ -342,11 +344,7 @@ func (f *Front) ImportLua() {
 						} else {
 							o["isflow"] = 0
 						}
-						if cells[9].Value == "紧急" {
-							o["urgency"] = 1
-						} else {
-							o["urgency"] = 0
-						}
+						o["priority"], _ = cells[9].Int()
 						o["platform"] = cells[10].Value
 						o["area"] = cells[11].Value
 						o["city"] = cells[12].Value
@@ -370,11 +368,12 @@ func (f *Front) ImportLua() {
 						//table := cells[6].Value
 						//o["table"] = table
 						//o["transfercode"] = qu.IntAll(Transfercode[table])
-						ok, name := saveLua(o) //保存爬虫
+						ok := saveLua(o) //保存爬虫
 						if ok == false {
 							errorinfo[cells[1].Value] = "第" + strconv.Itoa(k) + "行找不到作者,已经过滤"
 						} else {
-							o["author"] = name
+							o["status"] = 1
+							o["author"] = o["modifyuser"]
 							o["importuser"] = f.GetSession("username")
 							u.MgoEB.Save("import", o)
 						}
@@ -388,17 +387,17 @@ func (f *Front) ImportLua() {
 	}
 }
 
-func saveLua(o map[string]interface{}) (bool, string) {
+func saveLua(o map[string]interface{}) bool {
 	AutoTpl["Base.SpiderName"] = o["name"]
 	AutoTpl["Base.SpiderCode"] = o["code"]
 	AutoTpl["Base.SpiderChannel"] = o["channel"]
 	AutoTpl["Base.SpiderTargetChannelUrl"] = o["channeladdr"]
-	author := o["author"].(string)
-	one, _ := u.MgoEB.FindOne("user", map[string]interface{}{"s_email": author})
-	id := mongodb.BsonIdToSId((*one)["_id"])
+	modifyuser := o["modifyuser"].(string)
+	one, _ := u.MgoEB.FindOne("user", map[string]interface{}{"s_name": modifyuser, "i_auth": 1})
 	if len(*one) == 0 {
-		return false, ""
+		return false
 	}
+	id := mongodb.BsonIdToSId((*one)["_id"])
 	common := []interface{}{
 		AutoTpl["Base.SpiderCode"],
 		AutoTpl["Base.SpiderName"],
@@ -454,10 +453,10 @@ func saveLua(o map[string]interface{}) (bool, string) {
 	param["site"] = o["name"]
 	param["href"] = o["channeladdr"]
 	param["channel"] = o["channel"]
-	param["createuser"] = (*one)["s_name"]
+	param["createuser"] = modifyuser
 	param["createuserid"] = id
 	param["createuseremail"] = (*one)["s_email"]
-	param["modifyuser"] = (*one)["s_name"]
+	param["modifyuser"] = modifyuser
 	param["modifyuserid"] = id
 	param["modifytime"] = time.Now().Unix()
 	param["state"] = 0 //未完成
@@ -471,8 +470,11 @@ func saveLua(o map[string]interface{}) (bool, string) {
 		model[k] = qu.ObjToString(o[k])
 	}
 	param["model"] = model
-	param["next"] = o["next"]
+	param["next"] = (*one)["s_email"]
 	param["urgency"] = o["urgency"]
+	param["priority"] = o["priority"] //优先级
+	param["recovertime"] = int64(0)   //回收时间
+	param["claimtime"] = int64(0)     //认领时间
 	param["isflow"] = o["isflow"]
 	param["spidertype"] = "history"
 	param["spiderremark"] = o["spiderremark"]
@@ -497,11 +499,12 @@ func saveLua(o map[string]interface{}) (bool, string) {
 		infotype = "舆情"
 	}
 	//默认字段
-	param["spidercompete"] = true     //2021-11-20后爬虫加此字段(表示新爬虫,剑鱼网站不展示原文)
-	param["spiderhistorymaxpage"] = 1 //历史最大页
-	param["pendstate"] = 0            //
-	param["grade"] = 0                //爬虫难易度(主要用于python爬虫使用)
-	param["spiderimportant"] = false  //是否为重点网站爬虫
+	param["spidercompete"] = true           //2021-11-20后爬虫加此字段(表示新爬虫,剑鱼网站不展示原文)
+	param["spiderhistorymaxpage"] = 1       //历史最大页
+	param["pendstate"] = 0                  //
+	param["grade"] = 0                      //爬虫难易度(主要用于python爬虫使用)
+	param["spiderimportant"] = false        //是否为重点网站爬虫
+	param["claimtype"] = CLAIMTYPEUNCLAIMED //爬虫认领状态(未认领)
 	//qu.Debug("param---", param)
 
 	ok := spider.SaveSpider(o["code"].(string), param)
@@ -564,7 +567,7 @@ func saveLua(o map[string]interface{}) (bool, string) {
 			}}, true, false)
 		}
 	}
-	return ok, (*one)["s_name"].(string)
+	return ok
 }
 
 func (f *Front) Importdata() {
@@ -667,19 +670,88 @@ func (f *Front) Assign() {
 				"$in": codesarr,
 			},
 		}
+		luas, _ := u.MgoEB.Find("luaconfig", query, nil, ClaimQueryFields, false, -1, -1)
+		update := [][]map[string]interface{}{}
+		save := []map[string]interface{}{}
+		for _, l := range *luas {
+			set := map[string]interface{}{}
+			now := time.Now().Unix()
+			claimtype := qu.IntAll(l["claimtype"])
+			priority := qu.IntAll(l["priority"])
+			spiderimportant, _ := l["spiderimportant"].(bool)
+			if claimtype <= CLAIMTYPECLAIMED {
+				recovertime := CreateRecovertime(spiderimportant, priority)
+				set = map[string]interface{}{
+					"claimtype":       CLAIMTYPECLAIMED,
+					"claimtime":       now,
+					"recovertime":     recovertime,
+					"createuseremail": (*user)["s_email"],
+					"createuser":      name,
+					"createuserid":    userid,
+					"modifyuser":      name,
+					"modifyuserid":    userid,
+					"platform":        (*user)["s_platform"],
+				}
+				if claimtype == CLAIMTYPECLAIMED {
+					//回收日志
+					recovelog := map[string]interface{}{
+						"site":             l["site"],
+						"code":             l["code"],
+						"channel":          l["channel"],
+						"modifyuser":       l["modifyuser"],
+						"priority":         priority,
+						"stype":            "回收",
+						"comeintime":       now,
+						"claimtime":        l["claimtime"],
+						"recovertime":      l["recovertime"],
+						"returntime":       int64(0),
+						"important":        spiderimportant,
+						"returnreason":     "",
+						"claimrecovertype": 0,
+					}
+					save = append(save, recovelog)
+				}
+				//认领日志
+				claimlog := map[string]interface{}{
+					"site":             l["site"],
+					"code":             l["code"],
+					"channel":          l["channel"],
+					"modifyuser":       name,
+					"priority":         priority,
+					"stype":            "认领",
+					"comeintime":       now,
+					"claimtime":        now,
+					"recovertime":      recovertime,
+					"returntime":       int64(0),
+					"important":        spiderimportant,
+					"returnreason":     "",
+					"claimrecovertype": 0,
+				}
+				save = append(save, claimlog)
+			} else { //历史爬虫
+				set = map[string]interface{}{
+					"createuserid":    userid,
+					"createuser":      name,
+					"createuseremail": (*user)["s_email"],
+					"modifyuser":      name,
+					"modifyuserid":    userid,
+					"platform":        (*user)["s_platform"],
+				}
+			}
+			//更新爬虫
+			up := []map[string]interface{}{
+				{"code": l["code"]},
+				{"$set": set},
+			}
+			update = append(update, up)
+		}
 		qu.Debug(query)
-		set := map[string]interface{}{
-			"$set": map[string]interface{}{
-				"createuserid":    userid,
-				"createuser":      name,
-				"createuseremail": (*user)["s_email"],
-				"modifyuser":      name,
-				"modifyuserid":    userid,
-				"platform":        (*user)["s_platform"],
-			},
+		//更新爬虫信息
+		b := u.MgoEB.UpdateBulk("luaconfig", update...)
+		//保存认领日志
+		if len(save) > 0 {
+			u.MgoEB.SaveBulk("lua_logs_claim", save...)
 		}
-		//b := u.MgoE.Update("luaconfig", query, set, false, true)
-		b := u.MgoEB.Update("luaconfig", query, set, false, true)
 		if b {
 			go editModify(codesarr, userid, name) //修改爬虫对应任务的维护人
 			f.Write("y")
@@ -689,7 +761,6 @@ func (f *Front) Assign() {
 	} else {
 		f.Write("null")
 	}
-
 }
 
 // 审核日志导出

+ 130 - 81
src/front/spider.go

@@ -760,13 +760,13 @@ func LuaTextCheck(infoformat int, param map[string]interface{}, param_list_chrom
 		city := qu.ObjToString(model["city"])
 		district := qu.ObjToString(model["district"])
 		if !strings.Contains(list, fmt.Sprintf(u.CheckText_Area+`="%s"`, area)) {
-			errmsg += `省份信息与模板不一致`
+			errmsg += `省份信息与模板不一致`
 		}
 		if !strings.Contains(list, fmt.Sprintf(u.CheckText_City+`="%s"`, city)) {
-			errmsg += `城市信息与模板不一致`
+			errmsg += `城市信息与模板不一致`
 		}
 		if !strings.Contains(list, fmt.Sprintf(u.CheckText_District+`="%s"`, district)) {
-			errmsg += `区/县信息与模板不一致`
+			errmsg += `区/县信息与模板不一致`
 		}
 
 		if infoformat == 2 && !strings.Contains(detail, "projectname") {
@@ -1305,44 +1305,142 @@ func (f *Front) Checktime() {
 	}
 }
 
+func (f *Front) Assort() {
+	state, _ := f.GetInteger("state")
+	code := f.GetString("code")
+	codes := u.SymbolReg.Split(code, -1)
+	msg := AssortOrDisablesCode(codes, state, "assort", "")
+	//for _, code := range codes {
+	//	query := map[string]interface{}{
+	//		"code": code,
+	//	}
+	//	//下架爬虫
+	//	//lua, _ := u.MgoE.FindOne("luaconfig", query)
+	//	lua, _ := u.MgoEB.FindOne("luaconfig", query)
+	//	event := qu.IntAll((*lua)["event"])
+	//	if (*lua)["downevent"] != nil { //爬虫开发修改爬虫节点,审核人员分类爬虫时,原来爬虫所在节点下架
+	//		event = qu.IntAll((*lua)["downevent"])
+	//	}
+	//	upresult, err := spider.UpdateSpiderByCodeState(code, "6", event)
+	//	qu.Debug("下架爬虫:", code, upresult, err)
+	//	if upresult && err == nil {
+	//		//更新爬虫状态
+	//		update := map[string]interface{}{
+	//			"$set": map[string]interface{}{
+	//				"state": state,
+	//				//"modifytime":   time.Now().Unix(),
+	//				"l_uploadtime": time.Now().Unix(),
+	//			},
+	//		}
+	//		//u.MgoE.Update("luaconfig", query, update, false, false)
+	//		u.MgoEB.Update("luaconfig", query, update, false, false)
+	//		//关闭任务
+	//		query = map[string]interface{}{
+	//			"s_code": code,
+	//		}
+	//		update = map[string]interface{}{
+	//			"$set": map[string]interface{}{
+	//				"i_state": 6,
+	//			},
+	//		}
+	//		u.MgoEB.Update("task", query, update, false, true)
+	//		DelSpiderHeart(code)     //删除心跳
+	//		UpdateSiteTask(code)     //更新重点站点任务
+	//		UpdateLuaClaimtype(code) //更新爬虫认领状态
+	//	} else {
+	//		success = false
+	//		msg += code + ";"
+	//	}
+	//}
+	f.ServeJson(map[string]interface{}{"msg": msg})
+}
+
 // 批量作废
 func (f *Front) Disables() error {
 	auth := qu.IntAll(f.GetSession("auth"))
-	events := strings.Split(f.GetString("events"), ",")
+	//events := strings.Split(f.GetString("events"), ",")
 	codes := strings.Split(f.GetString("codes"), ",")
 	disablereason := f.GetString("disablereason")
 	state, _ := f.GetInteger("state")
-	res := ""
+	msg := ""
 	if auth == u.Role_Admin {
-		for k, code := range codes {
-			//更新爬虫状态时爬虫下架
-			upresult, err := spider.UpdateSpiderByCodeState(code, "6", qu.IntAll(events[k])) //下架
-			qu.Debug("下架:", code, upresult)
-			if upresult && err == nil { //下架成功
-				//更新爬虫
-				u.MgoEB.Update("luaconfig", map[string]interface{}{"code": code}, map[string]interface{}{"$set": map[string]interface{}{"state": state, "disablereason": disablereason}}, false, false)
-				//修改任务状态
-				u.MgoEB.Update("task", map[string]interface{}{
-					"s_code": code,
-					"i_state": map[string]interface{}{
-						"$nin": []int{4, 6}, //更新除审核通过和已关闭的任务
-					},
-				},
-					map[string]interface{}{"$set": map[string]interface{}{"i_state": 6, "l_updatetime": time.Now().Unix()}}, false, true)
-				if err != nil {
-					res = res + code + ", OK" + qu.ObjToString(err.Error()) + ";"
-				} else {
-					res = res + code + ", OK" + ";"
+		msg = AssortOrDisablesCode(codes, state, "disables", disablereason)
+		//for k, code := range codes {
+		//	//更新爬虫状态时爬虫下架
+		//	upresult, err := spider.UpdateSpiderByCodeState(code, "6", qu.IntAll(events[k])) //下架
+		//	qu.Debug("下架:", code, upresult)
+		//	if upresult && err == nil { //下架成功
+		//		//更新爬虫
+		//		u.MgoEB.Update("luaconfig", map[string]interface{}{"code": code}, map[string]interface{}{"$set": map[string]interface{}{"state": state, "disablereason": disablereason}}, false, false)
+		//		//修改任务状态
+		//		u.MgoEB.Update("task", map[string]interface{}{
+		//			"s_code": code,
+		//			"i_state": map[string]interface{}{
+		//				"$nin": []int{4, 6}, //更新除审核通过和已关闭的任务
+		//			},
+		//		},
+		//			map[string]interface{}{"$set": map[string]interface{}{"i_state": 6, "l_updatetime": time.Now().Unix()}}, false, true)
+		//		if err != nil {
+		//			res = res + code + ", OK" + qu.ObjToString(err.Error()) + ";"
+		//		} else {
+		//			res = res + code + ", OK" + ";"
+		//		}
+		//	} else {
+		//		res = res + code + ", 更新失败;"
+		//	}
+		//}
+	} else {
+		msg = "没有权限"
+	}
+	f.ServeJson(map[string]interface{}{"msg": msg})
+	return nil
+}
+
+func AssortOrDisablesCode(codes []string, state int, stype, reason string) (msg string) {
+	for _, code := range codes {
+		//下架爬虫
+		lua, _ := u.MgoEB.FindOne("luaconfig", map[string]interface{}{"code": code})
+		event := qu.IntAll((*lua)["event"])
+		if (*lua)["downevent"] != nil { //爬虫开发修改爬虫节点,审核人员分类爬虫时,原来爬虫所在节点下架
+			event = qu.IntAll((*lua)["downevent"])
+		}
+		upresult, err := spider.UpdateSpiderByCodeState(code, "6", event)
+		qu.Debug("更新爬虫状态:", stype, code, upresult, err)
+		if upresult && err == nil {
+			//更新爬虫
+			setcode := map[string]interface{}{}
+			settask := map[string]interface{}{
+				"i_state":      6,
+				"l_updatetime": time.Now().Unix(),
+			}
+			if stype == "assort" {
+				setcode = map[string]interface{}{
+					"state":        state,
+					"l_uploadtime": time.Now().Unix(),
 				}
-			} else {
-				res = res + code + ", 更新失败;"
+			} else if stype == "disables" {
+				setcode = map[string]interface{}{
+					"state":         state,
+					"disablereason": reason,
+				}
+				settask["disables"] = reason
 			}
+			u.MgoEB.Update("luaconfig", map[string]interface{}{"code": code}, map[string]interface{}{"$set": setcode}, false, false)
+			//修改任务状态
+			u.MgoEB.Update("task", map[string]interface{}{
+				"s_code": code,
+				"i_state": map[string]interface{}{
+					"$nin": []int{4, 6}, //更新除审核通过和已关闭的任务
+				},
+			}, map[string]interface{}{"$set": settask}, false, true)
+			DelSpiderHeart(code)     //删除心跳
+			UpdateSiteTask(code)     //更新重点站点任务
+			UpdateLuaClaimtype(code) //更新爬虫认领状态
+		} else {
+			msg += code + ", 更新失败;"
 		}
-	} else {
-		res = "没有权限"
 	}
-	f.ServeJson(res)
-	return nil
+	return msg
 }
 
 // 批量上下架
@@ -1460,56 +1558,6 @@ func (f *Front) UpState() error {
 	}
 	return nil
 }
-func (f *Front) Assort() {
-	state, _ := f.GetInteger("state")
-	code := f.GetString("code")
-	codes := u.SymbolReg.Split(code, -1)
-	success := true
-	msg := ""
-	for _, code := range codes {
-		query := map[string]interface{}{
-			"code": code,
-		}
-		//下架爬虫
-		//lua, _ := u.MgoE.FindOne("luaconfig", query)
-		lua, _ := u.MgoEB.FindOne("luaconfig", query)
-		event := qu.IntAll((*lua)["event"])
-		if (*lua)["downevent"] != nil { //爬虫开发修改爬虫节点,审核人员分类爬虫时,原来爬虫所在节点下架
-			event = qu.IntAll((*lua)["downevent"])
-		}
-		upresult, err := spider.UpdateSpiderByCodeState(code, "6", event)
-		qu.Debug("下架爬虫:", code, upresult, err)
-		if upresult && err == nil {
-			//更新爬虫状态
-			update := map[string]interface{}{
-				"$set": map[string]interface{}{
-					"state": state,
-					//"modifytime":   time.Now().Unix(),
-					"l_uploadtime": time.Now().Unix(),
-				},
-			}
-			//u.MgoE.Update("luaconfig", query, update, false, false)
-			u.MgoEB.Update("luaconfig", query, update, false, false)
-			//关闭任务
-			query = map[string]interface{}{
-				"s_code": code,
-			}
-			update = map[string]interface{}{
-				"$set": map[string]interface{}{
-					"i_state": 6,
-				},
-			}
-			u.MgoEB.Update("task", query, update, false, true)
-			DelSpiderHeart(code) //删除心跳
-			UpdateSiteTask(code) //更新重点站点任务
-		} else {
-			success = false
-			msg += code + ";"
-		}
-	}
-
-	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
-}
 
 // 更新爬虫状态,并判断是否更新节点爬虫
 func UpStateAndUpSpider(code, id, reason, username string, state int) (bool, error) {
@@ -1606,7 +1654,8 @@ func UpStateAndUpSpider(code, id, reason, username string, state int) (bool, err
 					}
 					upset["frequencyerrtimes"] = 0 //爬虫审核通过,重置采集频率异常次数
 					upset["l_uploadtime"] = time.Now().Unix()
-					UpdateSiteTask(code) //更新重点站点任务
+					UpdateSiteTask(code)     //更新重点站点任务
+					UpdateLuaClaimtype(code) //更新爬虫认领状态
 				} else if state == Sp_state_2 { //打回原因
 					upset["reason"] = reason
 					//清理机检结果

+ 0 - 4
src/taskManager/sitetask.go

@@ -16,7 +16,6 @@ func (t *TaskM) SiteTask() {
 	repair := t.GetString("repair")
 	overdue := t.GetString("overdue")
 	latestdata := t.GetString("latestdata")
-	codestate := t.GetString("codestate")
 	searchStr := t.GetString("search[value]")
 	search := strings.TrimSpace(searchStr)
 	draw, _ := t.GetInteger("draw")
@@ -61,9 +60,6 @@ func (t *TaskM) SiteTask() {
 		if latestdata != "-1" {
 			query["b_latestdata"] = latestdata == "1"
 		}
-		if codestate != "-1" {
-			query["i_state"] = qu.IntAll(codestate)
-		}
 		sort := `{"%s":%d}`
 		orderIndex := t.GetString("order[0][column]")
 		orderName := t.GetString(fmt.Sprintf("columns[%s][data]", orderIndex))

+ 51 - 0
src/timetask/timetask.go

@@ -2,6 +2,7 @@ package timetask
 
 import (
 	"fmt"
+	. "front"
 	"github.com/cron"
 	"io/ioutil"
 	"luacheck"
@@ -27,9 +28,59 @@ func TimeTask() {
 	c.AddFunc("0 0 */1 ? * *", CheckLuaMove)            //7000节点转增量爬虫失败告警
 	c.AddFunc("0 */10 * * * *", SpiderMoveEvent)        //7000节点转增量爬虫
 	c.AddFunc("0 0 8 * * *", UpdateImportantCode)       //更新重点网站爬虫信息
+	c.AddFunc("0 */1 * * * *", RecoverCodes)            //认领爬虫回收定时任务
 	c.AddFunc("0 */1 * * * *", luacheck.TimeTaskGetLua) //爬虫机检定时任务
 }
 
+// 认领爬虫回收
+func RecoverCodes() {
+	defer qu.Catch()
+	//回收待完成、超期、已认领爬虫
+	q := map[string]interface{}{
+		"state":     0,
+		"claimtype": CLAIMTYPECLAIMED,
+		"recovertime": map[string]interface{}{
+			"$lt": time.Now().Unix(),
+		},
+	}
+	luas, _ := util.MgoEB.Find("luaconfig", q, nil, ClaimQueryFields, false, -1, -1)
+	if len(*luas) > 0 {
+		update := [][]map[string]interface{}{}
+		save := []map[string]interface{}{}
+		for _, l := range *luas {
+			up := []map[string]interface{}{
+				{"code": l["code"]},
+				{"$set": map[string]interface{}{
+					"claimtype":   CLAIMTYPEUNCLAIMED,
+					"claimtime":   int64(0),
+					"recovertime": int64(0),
+				}},
+			}
+			update = append(update, up)
+			now := time.Now().Unix()
+			save = append(save, map[string]interface{}{
+				"site":             l["site"],
+				"code":             l["code"],
+				"channel":          l["channel"],
+				"modifyuser":       l["modifyuser"],
+				"priority":         l["priority"],
+				"stype":            "回收",
+				"comeintime":       now,
+				"claimtime":        l["claimtime"],
+				"recovertime":      l["recovertime"],
+				"returntime":       int64(0),
+				"important":        l["spiderimportant"],
+				"returnreason":     "",
+				"claimrecovertype": 1,
+			})
+		}
+		//更新爬虫信息
+		util.MgoEB.UpdateBulk("luaconfig", update...)
+		//保存认领日志
+		util.MgoEB.SaveBulk("lua_logs_claim", save...)
+	}
+}
+
 // 检测创建任务失败的爬虫
 func CheckCreateTask() {
 	defer qu.Catch()

+ 267 - 161
src/web/templates/index.html

@@ -87,6 +87,38 @@
         </div><!-- /.modal-content -->
     </div><!-- /.modal -->
 </div>
+<!-- 归还爬虫模态框(Modal) -->
+<div class="modal fade" id="modal-returncode" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+	<div class="modal-dialog">
+		<div class="modal-content">
+			<div class="modal-header">
+				<div class="modal-header">
+					<button type="button" class="close" data-dismiss="modal" aria-hidden="true" style="margin-top: -19px">&times;</button>
+					<!--<div class="edit-form">-->
+					<div class="edit-info">
+						<span class="fa fa-copy" id="code-assign" aria-hidden="true"></span>
+						<span class="info">爬虫归还<span>
+					</div>
+					<form class="form-horizontal" role="form">
+						<div class="form-group">
+							<label for="modify" class="col-sm-2 control-label">归还原因:</label>
+							<div class="col-sm-10">
+								<textarea id="returnreason" rows="2" cols="50" ></textarea>
+							</div>
+						</div>
+						<div class="form-group" id="assign-style">
+							<div class="col-sm-offset-2 col-sm-10">
+								<input type="button" onclick="comfirm_returncode()" class="btn btn-primary" value="确定">
+								<input type="button" data-dismiss="modal" class="btn btn-default" value="取消">
+							</div>
+						</div>
+					</form>
+					<!--</div>	-->
+				</div>
+			</div>
+		</div><!-- /.modal-content -->
+	</div><!-- /.modal -->
+</div>
 <!-- 复制爬虫模态框(Modal) -->
 <div class="modal fade" id="modal-spidercopy" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
     <div class="modal-dialog">
@@ -163,12 +195,19 @@
    <h1>
      脚本列表
      <small>
-      <a class="btn btn-default btn-sm" onclick="spidercopy()">补采复制</a>
+		 {{if eq (session "auth") 1}}
+		 <a class="btn btn-success btn-sm" onclick="claimcode()">爬虫认领</a>
+
+		 	{{if eq (session "identity") 0}}
+		 	<a class="btn btn-danger btn-sm" onclick="returncode()">爬虫归还</a>
+		 	{{end}}
+		 {{end}}
+      	 <a class="btn btn-primary btn-sm" onclick="spidercopy()">补采复制</a>
 		{{if gt (session "auth") 2}}
 		<!--<a class="btn btn-default btn-sm" href="/center/spider">新建爬虫</a>-->
-		 <a class="btn btn-default btn-sm" onclick="spidercopysplit()">拆分复制</a>
-		<a class="btn btn-default btn-sm" id="assign" onclick="assign()">分配爬虫</a>
-		<a class="btn btn-default btn-sm" id="disables" onclick="disables()">状态修改</a>
+		 <a class="btn btn-info btn-sm" onclick="spidercopysplit()">拆分复制</a>
+		<a class="btn btn-success btn-sm" id="assign" onclick="assign()">分配爬虫</a>
+		<a class="btn btn-warning btn-sm" id="disables" onclick="disables()">状态修改</a>
 		{{end}}
 	 </small>
    </h1>
@@ -190,16 +229,16 @@
 					<th>栏目名称</th>
 					<th>爬虫代码</th>
 					<th>类型</th>
-					<th>紧急度</th>
 					<th>节点</th>
-					<th>作者</th>
-					<th>最后修改时间</th>
+					<th>维护人</th>
 					<th>状态</th>
 					<th>平台</th>
-					<th>挂起</th>
-					{{if eq (session "platform") "python"}}
-					<th>难易度</th>
-					{{end}}
+					<th>优先级</th>
+					<th>认领时间</th>
+					<th>回收时间</th>
+<!--					{{if eq (session "platform") "python"}}-->
+<!--					<th>难易度</th>-->
+<!--					{{end}}-->
 					<th class="hidden-xs">操作</th>
 					<th>机检结果</th>
                 </tr>
@@ -219,7 +258,7 @@ $(function(){
               "url": "/js/dataTables.chinese.lang"
           },
 		"columnDefs": [
-			{ "orderable": false, "targets": [0,2,4,5,6,7,9,10,11,12,13] },
+			{ "orderable": false, "targets": [0,2,4,5,6,7,12,13] },
 			//爬虫类型
 			{"targets":[4], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
 				{{if gt (session "auth") 2}}
@@ -250,34 +289,8 @@ $(function(){
 				});
 				{{end}}
 			}},
-			//更新紧急度
-			{"targets":[5], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
-					{{if gt (session "auth") 2}}
-					$(cell).click(function () {
-						$(this).html(updateUrgency(rowData._id,rowData.state,rowData.code));
-						var aInput = $(this).find(":input");
-						aInput.focus().val(cellData);
-					});
-					$(cell).on("click", ":input", function (e) {
-						e.stopPropagation();
-					});
-					$(cell).on("change", ":input", function () {
-						$(this).blur();
-					});
-					$(cell).on("blur", ":input", function () {
-						var text = $(this).find("option:selected").text();
-						if (text == "紧急"){
-							text = 1;
-						}else {
-							text = 0;
-						}
-						ttable.cell(cell).data(text);
-						cellData = text;
-					});
-					{{end}}
-				}},
 			//更新节点
-			{"targets":[6], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
+			{"targets":[5], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
 				  {{if gt (session "auth") 2}}
 					$(cell).click(function () {
 					  $(this).html(createComboxEvent(rowData._id,rowData.state,rowData.code));
@@ -298,7 +311,7 @@ $(function(){
 				{{end}}
 			}},
 			//更新状态
-			{"targets":[9], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
+			{"targets":[7], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
 				{{if gt (session "auth") 2}}
 				  $(cell).click(function () {
 					if(cellData!=4&&cellData!=7&&cellData!=8&&cellData!=9&&cellData!=10){
@@ -337,7 +350,7 @@ $(function(){
 				{{end}}
 			  }},
 			//更新平台
-			{"targets":[10], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
+			{"targets":[8], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
 				  $(cell).click(function () {
 					  $(this).html(createComboxPlatform(rowData.code,rowData._id));
 					  var aInput = $(this).find(":input");
@@ -354,33 +367,9 @@ $(function(){
 					  ttable.cell(cell).data(text);
 					  cellData = text;
 				  });
-			  }},
-			//爬虫挂起
-			{"targets":[11], createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
-				$(cell).click(function () {
-					$(this).html(createComboxPendState(rowData.code));
-					var aInput = $(this).find(":input");
-					aInput.focus().val(cellData);
-				});
-				$(cell).on("click", ":input", function (e) {
-					e.stopPropagation();
-				});
-				$(cell).on("change", ":input", function () {
-					$(this).blur();
-				});
-				$(cell).on("blur", ":input", function () {
-					var text = $(this).find("option:selected").text();
-					if(text == "否"){
-						text = 0;
-					}else if(text == "是"){
-						text = 1;
-					}
-					ttable.cell(cell).data(text);
-					cellData = text;
-				});
-			}}
+			  }}
 		],
-		"order": [[8,"desc"]],
+		"order": [[10,"desc"]],
 		"processing":true,
 		"serverSide": true,
 		"searching": true,
@@ -393,9 +382,9 @@ $(function(){
 		 },
 		"columns": [
 			{ "data": "_id",render:function(val,a,row){
-				return "<input type='checkbox' platform='"+row.platform+"' event='"+row.event+"' scope='"+row.i_scope+"' value='"+val+"' name='"+row.param_common[1]+"_"+row.param_common[2]+"' code='"+row.param_common[0]+"'/>"
+				return "<input type='checkbox' state='"+row.state+"' claimtype='"+row.claimtype+"' platform='"+row.platform+"' event='"+row.event+"' scope='"+row.i_scope+"' value='"+val+"' name='"+row.param_common[1]+"_"+row.param_common[2]+"' code='"+row.param_common[0]+"'/>"
 			}},
-			{ "data": "param_common","width":"200px",render:function(val,a,row){
+			{ "data": "param_common",render:function(val,a,row){
 				vals=val[1];
 				if(vals.length>15){
 					vals=vals.substr(0,15)+"...";
@@ -427,17 +416,14 @@ $(function(){
 					return "舆情";
 				}
 			}},
-			{ "data": "urgency",render:function(val){
-				if(val==1){
-				  return "紧急";
-				}else{
-				  return "普通";
+			{ "data": "event"},
+			{ "data": "modifyuser",render:function(val,a,row){
+				if(row.claimtype == 0 && row.platform != "python"){
+					return "无";
 				}
+				return val;
 			}},
-			{ "data": "event"},
-			{ "data": "createuser"},
-			{ "data": "modifytime"},
-			{ "data": "state","width":"70px",render:function(val,a,row){
+			{ "data": "state","width":"5%",render:function(val,a,row){
 				var state=row.state;
 				if(state==0){
 					val="<span class='text-info text-bold'>待完成</span>";
@@ -467,24 +453,34 @@ $(function(){
 				return val;
 			}},
 			{ "data": "platform"},
-			{ "data": "pendstate",render:function(val){
-				if(val == 0){
-					return "否";
-				}else{
-					return "是";
+			{ "data": "priority"},
+			{ "data": "claimtime","width":"6%",render:function(val,a,row){
+				if (val == 0){
+					return val;
 				}
+				var dt = new Date()
+				dt.setTime(parseInt(val) * 1000);
+				return dt.format("yyyy-MM-dd hh:mm:ss");
 			}},
-			{{if eq (session "platform") "python"}}
-			{ "data": "grade",render:function(val){
-				if(val == undefined||val == 0){
-					return "普通";
-				}else if (val == 1){
-					return "较难";
-				}else if (val == 2){
-					return "很难";
-				}
+			{ "data": "recovertime","width":"6%",render:function(val,a,row){
+					if (val == 0){
+						return val;
+					}
+					var dt = new Date()
+					dt.setTime(parseInt(val) * 1000);
+					return dt.format("yyyy-MM-dd hh:mm:ss");
 			}},
-			{{end}}
+			// {{if eq (session "platform") "python"}}
+			// { "data": "grade",render:function(val){
+			// 	if(val == undefined||val == 0){
+			// 		return "普通";
+			// 	}else if (val == 1){
+			// 		return "较难";
+			// 	}else if (val == 2){
+			// 		return "很难";
+			// 	}
+			// }},
+			// {{end}}
 			{ "data": "param_common","width":"95px",render:function(val,a,row){
 				var div=$("<div><div class=\"btn-group\"></div></div>");
 				var auth="{{session "auth"}}";
@@ -565,15 +561,22 @@ $(function(){
 		"fnServerParams": function (e) {  
 			var state=$("#type_state").val();
 			var taskEvent = $("#task_event").val();
-			var urgency = $("#luaurgency").val();
 			var platform = $("#platform").val();
 			var infoformat = $("#infoformat").val();
 			var modifyuser = $("#modifyuser").val();
-			//紧急度
-			if(urgency){
-				e.urgency=urgency;
+			var claimtype = $("#claimtype").val();
+			var priority = $("#priority").val();
+			//优先级
+			if(priority){
+				e.priority=priority;
+			}else{
+				e.priority="-1";
+			}
+			//认领状态
+			if(claimtype){
+				e.claimtype=claimtype;
 			}else{
-				e.urgency="-1";
+				e.claimtype="-1";
 			}
 		    //状态
 		    if(state){
@@ -613,15 +616,6 @@ $(function(){
 		if(search){
 			$("[type=search]").val(search);
 		}
-    	// 紧急度
-    	var urgency="<div class='form-group'><label for='name'>紧急程度:</label>"+
-			"<select id='luaurgency' onchange='checkclick(this.value)' class='form-control input-sm'>"+
-			"<option value='-1'>全部</option>"+
-      "<option value='0'>普通</option>"+
-      "<option value='1'>紧急</option>"+
-			"</select></div>";
-		$("#spider_filter").prepend("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
-		$("#spider_filter").prepend(urgency);
     	//爬虫状态
 		var opt="<option value='-1'>全部</option>";
 		var opt1="<option value='0'>待完成</option>";	
@@ -687,8 +681,22 @@ $(function(){
 		{{if gt (session "auth") 2}}
 		var modifyuser="<option value='-1'>全部</option>";
 		var modifyusers={{.T.modifyusers}};
+		var identity = {{.T.identity}};
+		var ids = {{.T.ids}};
 		for(k in modifyusers){
-			modifyuser+="<option value='"+modifyusers[k]["s_name"]+"'>"+modifyusers[k]["s_name"]+"</option>";
+			if (identity == 0){
+				var flag = false;
+				for(i in ids){
+					if (modifyusers[k]["_id"] == ids[i]){
+						flag = true;
+					}
+				}
+				if (flag){
+					modifyuser+="<option value='"+modifyusers[k]["s_name"]+"'>"+modifyusers[k]["s_name"]+"</option>";
+				}
+			}else{
+				modifyuser+="<option value='"+modifyusers[k]["s_name"]+"'>"+modifyusers[k]["s_name"]+"</option>";
+			}
 		}
 		var selectModifyuser="<div class='form-group'><label for='name'>维护人:</label>"+
 			"<select id='modifyuser' onchange='checkclick(this.value)' class='form-control input-sm'>"+
@@ -696,7 +704,28 @@ $(function(){
 			"</select></div>";
 		$("#spider_filter").prepend("&nbsp;&nbsp;");
 		$("#spider_filter").prepend(selectModifyuser);
+		// 认领状态
+		var claimtype="<div class='form-group'><label for='name'>认领状态:</label>"+
+				"<select id='claimtype' onchange='checkclick(this.value)' class='form-control input-sm'>"+
+				"<option value='-1'>全部</option>"+
+				"<option value='0'>待认领</option>"+
+				"<option value='1'>已认领</option>"+
+				"<option value='2'>历史爬虫</option>"+
+				"</select></div>";
+		$("#spider_filter").prepend("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
+		$("#spider_filter").prepend(claimtype);
 		{{end}}
+		// 优先级priority
+		var priority="<div class='form-group'><label for='name'>优先级:</label>"+
+				"<select id='priority' onchange='checkclick(this.value)' class='form-control input-sm'>"+
+				"<option value='-1'>全部</option>"+
+				"<option value='0-200'>200以下</option>"+
+				"<option value='200-500'>200-500</option>"+
+				"<option value='500-700'>500-700</option>"+
+				"<option value='700-'>700以上</option>"+
+				"</select></div>";
+		$("#spider_filter").prepend("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
+		$("#spider_filter").prepend(priority);
     	$("#spider_wrapper .col-sm-6").css({width:"100%"});//样式
 	});
 })
@@ -716,56 +745,56 @@ $(function(){
 	}
 
 	function format_X(d) {
-	var data = Object.assign({},d);
-	data = {...d};
-	var errInfo = data.check.err;
-	var errLen = Object.keys(errInfo).length;
-	var warnInfo = data.check.warn;
-	var warnLen = Object.keys(warnInfo).length;
+		var data = Object.assign({},d);
+		data = {...d};
+		var errInfo = data.check.err;
+		var errLen = Object.keys(errInfo).length;
+		var warnInfo = data.check.warn;
+		var warnLen = Object.keys(warnInfo).length;
 
-	var maxLen = Math.max(errLen, warnLen);
-	var errth = '';
-	var warnth = '';
-	if (errLen > 0){
-		errth = '<th>错误信息</th>';
-	}
-	if (warnLen > 0){
-		warnth = '<th>警告信息</th>';
-	}
-	var checkHtml = '';
-	for (let i = 0; i < maxLen; i++) {
-		var ei = errInfo[i];
-		var wi = warnInfo[i];
-		if (!ei){
-			ei = '';
-		}else{
-			ei = (i+1)+"."+ei;
-		}
-		if (!wi){
-			wi = '';
-		}else{
-			wi = (i+1)+"."+wi;
-		}
-		var errtd = ''
-		var warntd = ''
+		var maxLen = Math.max(errLen, warnLen);
+		var errth = '';
+		var warnth = '';
 		if (errLen > 0){
-			errtd = '<td>' +ei+'</td>';
+			errth = '<th>错误信息</th>';
 		}
 		if (warnLen > 0){
-			warntd = '<td>' +wi+'</td>';
+			warnth = '<th>警告信息</th>';
 		}
-		checkHtml += '<tr>' + errtd + warntd + '</tr>';
+		var checkHtml = '';
+		for (let i = 0; i < maxLen; i++) {
+			var ei = errInfo[i];
+			var wi = warnInfo[i];
+			if (!ei){
+				ei = '';
+			}else{
+				ei = (i+1)+"."+ei;
+			}
+			if (!wi){
+				wi = '';
+			}else{
+				wi = (i+1)+"."+wi;
+			}
+			var errtd = ''
+			var warntd = ''
+			if (errLen > 0){
+				errtd = '<td>' +ei+'</td>';
+			}
+			if (warnLen > 0){
+				warntd = '<td>' +wi+'</td>';
+			}
+			checkHtml += '<tr>' + errtd + warntd + '</tr>';
+		}
+		return (
+			'<table id="nestable" style="border-spacing: 9px;border-collapse: separate;background: aliceblue;">' +
+				'<tr>' +
+					errth +
+					warnth +
+				'</tr>' +
+				checkHtml+
+			'</table>'
+		);
 	}
-	return (
-		'<table id="nestable" style="border-spacing: 9px;border-collapse: separate;background: aliceblue;">' +
-			'<tr>' +
-				errth +
-				warnth +
-			'</tr>' +
-			checkHtml+
-		'</table>'
-	);
-}
 
 	function checkclick(me){
 		ttable.ajax.reload();
@@ -784,6 +813,88 @@ $(function(){
 			$("#spider td input[type=checkbox]").prop("checked",false);
 		}
 	}
+	//爬虫认领
+	function claimcode(){
+		showConfirm("确定认领爬虫?", function() {
+			$.ajax({
+				url: "/center/claim/claimcode",
+				type: "post",
+				success:function(r){
+					if(r&&r.ok){
+						showTip(r.msg, 2000);
+						ttable.ajax.reload();
+					}else{
+						showTip(r.msg, 2000);
+					}
+				}
+			})
+		})
+	}
+	//爬虫归还
+	function returncode(){
+		var codes=[];
+		var errcodes=[];
+		$("#spider td input[type=checkbox]").each(function(){
+			if($(this).prop("checked")){
+				var state = $(this).attr("state");
+				var claimtype =$(this).attr("claimtype");
+				if(claimtype == 1 && (state == 0 || state == 2)){//已认领且爬虫状态未待完成或者未通过的爬虫允许归还
+					codes.push($(this).attr("code"));
+				}else{//不允许归还的爬虫
+					errcodes.push($(this).attr("code"));
+				}
+			}
+		});
+		if (errcodes.length >0){
+			showTip("爬虫不允许归还!("+errcodes.join(",")+")", 5000, function() {});
+		}else if(codes.length>0){
+			$("#modal-returncode").modal("show");
+		}else{
+			showTip("未选择要被归还的爬虫!", 2000, function() {});
+			$("#selrow").prop('checked',false);
+		}
+	}
+	
+	function comfirm_returncode() {
+		var returnreason = $("#returnreason").val();
+		if (returnreason == ""){
+			alert("请填写归还原因!")
+			return;
+		}
+		var codes=[];
+		$("#spider td input[type=checkbox]").each(function(){
+			if($(this).prop("checked")){
+				var state = $(this).attr("state");
+				var claimtype =$(this).attr("claimtype");
+				if(claimtype == 1 && (state == 0 || state == 2)) {//已认领且爬虫状态未待完成或者未通过的爬虫允许归还
+					codes.push($(this).attr("code"));
+				}
+			}
+		});
+		if(codes.length > 0){
+			$.ajax({
+				url:"/center/claim/returncode",
+				type:"post",
+				data:{
+					"codes":codes.join(","),
+					"returnreason":returnreason
+				},
+				success:function(r){
+					if(r && r.ok){
+						showTip(r.msg, 1000, function() {});
+						$("#selrow").prop('checked',false);
+						$('#com-alert').on('hidden.bs.modal', function () {
+							$("#modal-returncode").modal("hide");
+							ttable.ajax.reload();
+						})
+					}else{
+						showTip(r.msg, 2000, function() {});
+					}
+				}
+			})
+		}
+	}
+
 	function spidercopy(){
 		$("#modal-spidercopy").modal("show");
 	}
@@ -968,12 +1079,10 @@ $(function(){
 			return;
 		}
 		$("#modal-disables").modal("hide");
-		var events=[];
 		var codes=[];
 		var disablereason = $("#disablereason").val();
 		$("#spider td input[type=checkbox]").each(function(){
 			if($(this).prop("checked")){
-				events.push($(this).attr("event"));
 				codes.push($(this).attr("code"));
 			}
 		});
@@ -983,11 +1092,13 @@ $(function(){
 				$.ajax({
 					url:"/center/spider/disable",
 					type:"post",
-					data:{"events":events.join(","),"codes":codes.join(","),"disablereason":disablereason,"state":state},
+					data:{"codes":codes.join(","),"disablereason":disablereason,"state":state},
 					success:function(r){
 						common.maskHide();
 						$("#selrow").prop('checked',false);
-						showMsg(r, function() {});
+						if (r.msg != ""){
+							showMsg(r, function() {});
+						}
 						ttable.ajax.reload(null,false);
 					}
 				})
@@ -1076,11 +1187,6 @@ $(function(){
 		var spiderInforformat="<option value=1>招标</option><option value=2>拟建/审批</option><option value=3>产权</option><option value=4>舆情</option>";
 		return "<select onchange='updateesp(this.value,\"infoformat\",\""+state+"\",\""+code+"\",\""+id+"\")' class='form-control input-sm'>"+spiderInforformat+"</select>";
 	};
-	//修改紧急度
-	function updateUrgency(id,state,code){
-		var spiderUrgency="<option value=0>普通</option><option value=1>紧急</option>";
-		return "<select onchange='updateesp(this.value,\"urgency\",\""+state+"\",\""+code+"\",\""+id+"\")' class='form-control input-sm'>"+spiderUrgency+"</select>";
-	};
     //修改节点
     function createComboxEvent(id,state,code){
     	var events={{.T.events}};

+ 14 - 14
src/web/templates/spideredit.html

@@ -101,20 +101,20 @@
 			       			type : "post",
 			       			data:{
     								"state":state,
-    			   				"code":code,
-    							},
-			       			success: function(r){
-                    if(r.success){
-                      showMsg("更新成功",function(){
-                        	window.location.href="/center"
-                      })
-                    }else{
-                      showMsg("更新失败",function(){
-                        	window.location.href="/center"
-                      })
-                    }
-			       			}
-			      });
+									"code":code,
+								},
+							success: function(r){
+								if(r.msg == ""){
+								  showMsg("更新成功",function(){
+										window.location.href="/center"
+								  })
+								}else{
+								  showMsg("更新失败",function(){
+										window.location.href="/center"
+								  })
+								}
+							}
+						});
 					})
 				</script>
 			<button class="btn btn-default btn-sm" onclick="common.spider.checkStatus(this,'{{.T.lua.code}}')">爬虫测试</button>