Эх сурвалжийг харах

异常任务-生成任务流程

maxiaoshan 2 жил өмнө
parent
commit
24e3d35092

+ 7 - 5
src/config.json

@@ -4,14 +4,14 @@
   "udport": 1483,
   "spiderchan": 5,
   "systemdb": {
-    "addr": "192.168.3.207:29099",
+    "addr": "192.168.3.71:29099",
     "db": "recapture",
     "size": 5,
     "username": "",
     "password": ""
   },
   "datadb": {
-    "addr": "192.168.3.207:29099",
+    "addr": "192.168.3.71:29099",
     "db": "recapture",
     "coll": "bidding",
     "size": 5,
@@ -19,21 +19,21 @@
     "password": ""
   },
   "luaspiderdb": {
-    "addr": "192.168.3.207:29099",
+    "addr": "192.168.3.71:29099",
     "db": "spider",
     "size": 5,
     "username": "",
     "password": ""
   },
   "bideditor": {
-    "addr": "192.168.3.207:29099",
+    "addr": "192.168.3.71:29099",
     "db": "editor",
     "size": 5,
     "username": "",
     "password": ""
   },
   "bidding": {
-    "addr": "192.168.3.207:29099",
+    "addr": "192.168.3.71:29099",
     "db": "qfw",
     "size": 5,
     "username": "",
@@ -53,6 +53,8 @@
       "stype": "index"
     }
   ],
+  "threadbasenum": 50,
+  "threadupperlimit": 10,
   "msgname": "爬虫采集平台7100",
   "msgserveraddr": "spdata.jianyu360.com:801",
   "msgserveraddrfile": "spdata.jianyu360.com:802",

+ 438 - 74
src/front/data.go

@@ -11,6 +11,7 @@ import (
 	"strings"
 	"sync"
 	. "task"
+	"time"
 	. "udptask"
 	"util"
 )
@@ -29,8 +30,111 @@ var fileIndexMap = map[string]bool{
 	"type":        true,
 	"publishdept": true,
 }
-var publishtimeReg = regexp.MustCompile("\\d{4}-\\d{2}-\\d{2}")
-var fields = map[string]interface{}{"state": 1, "spidercode": 1, "site": 1, "channel": 1, "title": 1, "href": 1}
+var publishtimeReg1 = regexp.MustCompile("\\d{4}-\\d{2}-\\d{2}")
+var publishtimeReg2 = regexp.MustCompile("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")
+
+type DataRequest struct {
+	From      string `json:"from"`
+	Repeat    string `json:"repeat"`
+	Level     string `json:"level"`
+	Search    string `json:"search"`
+	Starttime int64  `json:"starttime"`
+}
+
+func (f *Front) ImportTask() {
+	defer qu.Catch()
+	msg := ""
+	ok := false
+	coll := f.GetString("coll")             //数据表
+	createtask := f.GetString("createtask") //是否生成任务
+	msgTmp := CheckTask(coll)               //校验任务
+	if createtask == "1" && msgTmp != "" {  //如果存在coll表未执行任务,不能新建任务
+		msg = msgTmp
+	} else {
+		if RunningTask[coll] { //判断是否有执行中的任务在使用coll表
+			msg = "表:" + coll + "已有任务正在运行,请稍后导入任务"
+		} else {
+			isClear := false
+			importstype := f.GetString("importstype") //导入方
+			if importstype == "0" {                   //导入方式为清除时,判断coll表有没有执行完的任务,但是数据未推送
+				if util.Mgo.Count("task", map[string]interface{}{"s_coll": coll, "i_state": 2, "issend": false}) > 0 {
+					msg = "表:" + coll + "有历史数据未推送"
+					goto L
+				} else { //清理表
+					isClear = true
+					if !util.MgoDT.Del(coll, nil) {
+						msg = "表:" + coll + "清理失败"
+						goto L
+					}
+				}
+			}
+			isbidding := f.GetString("isbidding") //是否是bidding
+			requeststr := f.GetString("requeststr")
+			dr := &DataRequest{}
+			qu.Debug(requeststr)
+			if json.Unmarshal([]byte(requeststr), dr) != nil {
+				msg = "检索内容格式化错误"
+				goto L
+			}
+			flows := f.GetString("select4") //处理流程
+			if isbidding == "1" {
+				//清理相关表
+				if isClear {
+					if !util.MgoDT.Del("bidding_copy", nil) { //清理bidding_cp表
+						msg = "表:bidding_cp清理失败"
+						goto L
+					}
+					if flows != "" { //有数据处理流程,清理extract抽取表
+						if !util.MgoDT.Del("extract", nil) {
+							msg = "表:extract清理失败"
+							goto L
+						}
+					}
+				}
+			}
+			//根据检索条件检索异常数据,导入coll表
+			importOk, querynum, okNum := importWarnErrData(coll, dr, isbidding == "1")
+			if importOk { //导入数据成功
+				msg = "共检索数据量:" + fmt.Sprint(querynum) + "条,导入成功:" + fmt.Sprint(okNum) + "条"
+				if createtask == "1" { //创建任务
+					db := f.GetString("db")                   //数据库
+					checkfields := f.GetString("checkfields") //校验字段
+					name := f.GetString("name")               //任务名称
+					flowsArr := []string{}
+					if flows != "" {
+						for _, flow := range strings.Split(flows, ",") {
+							flowsArr = append(flowsArr, flow)
+						}
+					}
+					user := f.GetSession("user").(map[string]interface{})
+					save := map[string]interface{}{
+						"s_name":        name,
+						"s_db":          db,
+						"s_coll":        coll,
+						"s_checkfields": checkfields,
+						"isbidding":     isbidding == "1",
+						"flows":         flowsArr,
+						"l_createtime":  time.Now().Unix(),
+						"s_createuser":  user["name"],
+						"i_state":       0,
+						"delete":        false,
+						"issend":        false,
+					}
+					if util.Mgo.Save("task", save) != "" {
+						ok = true
+					}
+				} else {
+					ok = true
+				}
+			} else {
+				msg = "检索数据量为0"
+			}
+		}
+	}
+L:
+	qu.Debug("导入任务:", ok, msg)
+	f.ServeJson(map[string]interface{}{"msg": msg, "ok": ok})
+}
 
 func (f *Front) PrepareBidding() {
 	defer qu.Catch()
@@ -86,7 +190,8 @@ func (f *Front) PrepareBidding() {
 				arr = [][]map[string]interface{}{}
 			}
 			if len(save) > 500 {
-				util.MgoDT.SaveBulk(util.DataColl, save...)
+				//util.MgoDT.SaveBulk(util.DataColl, save...)
+				util.MgoDT.SaveBulk("bidding", save...)
 				save = []map[string]interface{}{}
 			}
 			lock.Unlock()
@@ -102,7 +207,8 @@ func (f *Front) PrepareBidding() {
 		arr = [][]map[string]interface{}{}
 	}
 	if len(save) > 0 {
-		util.MgoDT.SaveBulk(util.DataColl, save...)
+		//util.MgoDT.SaveBulk(util.DataColl, save...)
+		util.MgoDT.SaveBulk("bidding", save...)
 		save = []map[string]interface{}{}
 	}
 	msg := "bidding_copy表共" + fmt.Sprint(count) + "条数据,成功拉取对应bidding信息" + fmt.Sprint(oknum) + "条"
@@ -144,77 +250,93 @@ func (f *Front) ViewBidding() {
 
 func (f *Front) ImportData() {
 	defer qu.Catch()
-	dataFile, _, err := f.GetFile("xlsx")
 	msgArr := []string{}
 	ok := true
 	coll := ""
 	save := []map[string]interface{}{}
-	if err == nil {
-		binary, _ := ioutil.ReadAll(dataFile)
-		xls, _ := xlsx.OpenBinary(binary)
-		sheet := xls.Sheets[0]
-		coll = sheet.Name      //sheetName当做表名
-		if RunningTask[coll] { //正在处理任务的表禁止导入数据
-			ok = false
-			msgArr = append(msgArr, coll+"表已被占用!")
-			goto END
-		}
-		fieldsTmp := map[string]int{} //记录字段对应的位置
-		for i, row := range sheet.Rows {
-			if i == 0 { //得到字段属性
-				for j, cell := range row.Cells {
-					if fileIndexMap[cell.Value] { //去除无效字段
-						fieldsTmp[cell.Value] = j
+	cleardata := f.GetString("cleardata")
+	qu.Debug(cleardata)
+	mf, err := f.GetFiles()
+	if err == nil && len(mf) == 1 {
+		dataFile, err := mf[0].Open()
+		if err == nil {
+			binary, _ := ioutil.ReadAll(dataFile)
+			xls, _ := xlsx.OpenBinary(binary)
+			sheet := xls.Sheets[0]
+			coll = sheet.Name      //sheetName当做表名
+			if RunningTask[coll] { //正在处理任务的表禁止导入数据
+				ok = false
+				msgArr = append(msgArr, coll+"表正在执行任务中!")
+				goto END
+			}
+			fieldsTmp := map[string]int{} //记录字段对应的位置
+			for i, row := range sheet.Rows {
+				if i == 0 { //得到字段属性
+					for j, cell := range row.Cells {
+						if fileIndexMap[cell.Value] { //去除无效字段
+							fieldsTmp[cell.Value] = j
+						}
 					}
-				}
-			} else { //生成数据
-				result := map[string]interface{}{}
-				cells := row.Cells
-				cellsLen := len(cells)
-				for field, index := range fieldsTmp {
-					if cellsLen >= index+1 {
-						cell := cells[index]
-						//字段处理
-						if field == "comeintime" {
-							comeintime, _ := cell.Int64()
-							result[field] = comeintime
-						} else if field == "publishtime" {
-							publishtime := cell.Value
-							if publishtime == "0" || publishtime == "" {
-								result[field] = "0"
-							} else if publishtimeReg.MatchString(publishtime) { //2022-10-15 23:49:49
-								result[field] = publishtime
-							} else if cell.NumFmt == "m/d/yy h:mm" {
-								t, _ := cell.GetTime(false)
-								result[field] = t.Format(qu.Date_Full_Layout)
-							} else { //其他类型视为异常
-								ok = false
-								msgArr = append(msgArr, "第"+fmt.Sprint(i+1)+"行publishtime字段异常")
-								goto END
+				} else { //生成数据
+					result := map[string]interface{}{}
+					cells := row.Cells
+					cellsLen := len(cells)
+					for field, index := range fieldsTmp {
+						if cellsLen >= index+1 {
+							cell := cells[index]
+							//字段处理
+							if field == "comeintime" {
+								comeintime, _ := cell.Int64()
+								result[field] = comeintime
+							} else if field == "publishtime" {
+								publishtime := cell.Value
+								if cell.NumFmt == "m/d/yy h:mm" {
+									t, _ := cell.GetTime(false)
+									result[field] = t.Format(qu.Date_Full_Layout)
+								} else if publishtimeReg2.MatchString(publishtime) { //2022-10-15 23:49:49
+									result[field] = publishtime
+								} else if publishtimeReg1.MatchString(publishtime) { //2022-10-15
+									result[field] = publishtime + " 00:00:00"
+								} else if publishtime == "0" || publishtime == "" {
+									result[field] = "0"
+								} else { //其他类型视为异常
+									ok = false
+									msgArr = append(msgArr, "第"+fmt.Sprint(i+1)+"行publishtime字段异常")
+									goto END
+								}
+							} else { //其它字段
+								result[field] = cell.Value
 							}
-						} else { //其它字段
-							result[field] = cell.Value
 						}
 					}
+					//必要字段缺失校验
+					noFields := checkField(result)
+					if len(noFields) == 0 {
+						result["state"] = 0
+						result["times"] = 0
+						save = append(save, result)
+					} else {
+						ok = false
+						msgArr = append(msgArr, "第"+fmt.Sprint(i+1)+"行"+strings.Join(noFields, ",")+"字段不存在")
+					}
 				}
-				//必要字段缺失校验
-				noFields := checkField(result)
-				if len(noFields) == 0 {
-					result["state"] = 0
-					result["times"] = 0
-					save = append(save, result)
-				} else {
-					ok = false
-					msgArr = append(msgArr, "第"+fmt.Sprint(i+1)+"行"+strings.Join(noFields, ",")+"字段不存在")
-				}
-
 			}
+		} else {
+			qu.Debug("数据导入失败:", err)
+			msgArr = append(msgArr, "数据导入失败!")
 		}
+	} else {
+		qu.Debug("数据导入失败:", err)
+		msgArr = append(msgArr, "数据导入失败!")
 	}
 END:
 	if ok { //保存数据
 		if len(save) > 0 && coll != "" && !strings.Contains(coll, "Sheet") {
-			util.MgoDT.SaveBulk(coll, save...)
+			if cleardata == "是" && util.MgoDT.Del(coll, nil) { //清理coll表
+				util.MgoDT.SaveBulk(coll, save...)
+			} else {
+				util.MgoDT.SaveBulk(coll, save...)
+			}
 		} else {
 			ok = false
 			msgArr = append(msgArr, "存储表异常")
@@ -224,6 +346,90 @@ END:
 	f.ServeJson(map[string]interface{}{"ok": ok, "msg": msgArr})
 }
 
+/*
+//func (f *Front) ImportData() {
+//	defer qu.Catch()
+//	dataFile, _, err := f.GetFile("xlsx")
+//	msgArr := []string{}
+//	ok := true
+//	coll := ""
+//	save := []map[string]interface{}{}
+//	if err == nil {
+//		binary, _ := ioutil.ReadAll(dataFile)
+//		xls, _ := xlsx.OpenBinary(binary)
+//		sheet := xls.Sheets[0]
+//		coll = sheet.Name      //sheetName当做表名
+//		if RunningTask[coll] { //正在处理任务的表禁止导入数据
+//			ok = false
+//			msgArr = append(msgArr, coll+"表已被占用!")
+//			goto END
+//		}
+//		fieldsTmp := map[string]int{} //记录字段对应的位置
+//		for i, row := range sheet.Rows {
+//			if i == 0 { //得到字段属性
+//				for j, cell := range row.Cells {
+//					if fileIndexMap[cell.Value] { //去除无效字段
+//						fieldsTmp[cell.Value] = j
+//					}
+//				}
+//			} else { //生成数据
+//				result := map[string]interface{}{}
+//				cells := row.Cells
+//				cellsLen := len(cells)
+//				for field, index := range fieldsTmp {
+//					if cellsLen >= index+1 {
+//						cell := cells[index]
+//						//字段处理
+//						if field == "comeintime" {
+//							comeintime, _ := cell.Int64()
+//							result[field] = comeintime
+//						} else if field == "publishtime" {
+//							publishtime := cell.Value
+//							if publishtime == "0" || publishtime == "" {
+//								result[field] = "0"
+//							} else if publishtimeReg.MatchString(publishtime) { //2022-10-15 23:49:49
+//								result[field] = publishtime
+//							} else if cell.NumFmt == "m/d/yy h:mm" {
+//								t, _ := cell.GetTime(false)
+//								result[field] = t.Format(qu.Date_Full_Layout)
+//							} else { //其他类型视为异常
+//								ok = false
+//								msgArr = append(msgArr, "第"+fmt.Sprint(i+1)+"行publishtime字段异常")
+//								goto END
+//							}
+//						} else { //其它字段
+//							result[field] = cell.Value
+//						}
+//					}
+//				}
+//				//必要字段缺失校验
+//				noFields := checkField(result)
+//				if len(noFields) == 0 {
+//					result["state"] = 0
+//					result["times"] = 0
+//					save = append(save, result)
+//				} else {
+//					ok = false
+//					msgArr = append(msgArr, "第"+fmt.Sprint(i+1)+"行"+strings.Join(noFields, ",")+"字段不存在")
+//				}
+//
+//			}
+//		}
+//	}
+//END:
+//	if ok { //保存数据
+//		if len(save) > 0 && coll != "" && !strings.Contains(coll, "Sheet") {
+//			util.MgoDT.SaveBulk(coll, save...)
+//		} else {
+//			ok = false
+//			msgArr = append(msgArr, "存储表异常")
+//		}
+//	}
+//	save = []map[string]interface{}{}
+//	f.ServeJson(map[string]interface{}{"ok": ok, "msg": msgArr})
+//}
+*/
+
 func (f *Front) DataList() {
 	defer qu.Catch()
 	coll := f.GetString("coll")
@@ -247,6 +453,7 @@ func (f *Front) DataList() {
 			}
 		}
 		qu.Debug("query:", query)
+		fields := map[string]interface{}{"state": 1, "spidercode": 1, "site": 1, "channel": 1, "title": 1, "href": 1}
 		task, _ := util.MgoDT.Find(coll, query, map[string]interface{}{"_id": 1}, fields, false, start, limit)
 		count := util.MgoDT.Count(coll, query)
 		f.ServeJson(map[string]interface{}{
@@ -294,18 +501,26 @@ func (f *Front) DataSend() {
 	taskid := f.GetString("taskid")
 	task, _ := util.Mgo.FindById("task", taskid, nil)
 	if len(*task) > 0 {
-		flows := (*task)["flows"].([]interface{})
-		t := &Task{
-			ID:        taskid,
-			DB:        qu.ObjToString((*task)["s_db"]),
-			Name:      qu.ObjToString((*task)["s_name"]),
-			Coll:      qu.ObjToString((*task)["s_coll"]),
-			Flows:     qu.ObjArrToStringArr(flows),
-			IsBidding: (*task)["isbidding"].(bool),
+		coll := qu.ObjToString((*task)["s_coll"])
+		if util.MgoDT.Count(coll, map[string]interface{}{"state": 1}) > 0 { //有要被推送的数据
+			flows := (*task)["flows"].([]interface{})
+			t := &Task{
+				ID:        taskid,
+				DB:        qu.ObjToString((*task)["s_db"]),
+				Name:      qu.ObjToString((*task)["s_name"]),
+				Coll:      coll,
+				Flows:     qu.ObjArrToStringArr(flows),
+				IsBidding: (*task)["isbidding"].(bool),
+			}
+			t.SendData()
+			ok = true
+		} else {
+			msg = "无数据需要被推送"
 		}
-		t.SendData()
-		ok = true
+		//更新任务,数据已推送
+		util.Mgo.UpdateById("task", taskid, map[string]interface{}{"$set": map[string]interface{}{"issend": true}})
 	}
+	qu.Debug("任务推送结果:", taskid, " ", ok, " ", msg)
 	f.ServeJson(map[string]interface{}{"rep": ok, "msg": msg})
 }
 
@@ -373,10 +588,9 @@ func (f *Front) DataUpdate() {
 					result[k] = v
 				}
 			}
-			qu.Debug(result)
 			if mustFiledNum > 0 { //保存服务推送有效数据
 				flag, id, coll := SaveObj(4002, "title", result)
-				updateMap["state"] = 1 //添加数据下载成功标记
+				updateMap["state"] = 2 //添加数据推送给成功标记
 				updateMap["sendflag"] = flag
 				updateMap["biddingid"] = id
 				updateMap["biddingcoll"] = coll
@@ -413,10 +627,160 @@ func (f *Front) DataDelete() {
 	f.ServeJson(map[string]interface{}{"msg": msg, "ok": ok})
 }
 
+func importWarnErrData(coll string, dr *DataRequest, isbidding bool) (ok bool, querynum, oknum int) {
+	defer qu.Catch()
+	qu.Debug("开始导入数据:", coll)
+	defer func() {
+		qu.Debug("导入数据完毕:", coll)
+	}()
+	//1、检索数据
+	query := map[string]interface{}{}
+	if dr.From != "-1" { //来源
+		query["from"] = dr.From
+	}
+	if dr.Repeat != "-1" { //是否重复
+		query["repeat"] = dr.Repeat == "1"
+	}
+	query["level"] = qu.IntAll(dr.Level) //无论biding还是非bidding数据,导入任务时,类型都不能为全部,所以不用判断
+	if dr.Starttime > 0 {                //时间
+		query["comeintime"] = map[string]interface{}{
+			"$gte": dr.Starttime,
+			"$lt":  dr.Starttime + 86400,
+		}
+	}
+	if dr.Search != "" { //搜索条件
+		query["$or"] = []interface{}{
+			map[string]interface{}{"site": map[string]interface{}{"$regex": dr.Search}},
+			map[string]interface{}{"spidercode": map[string]interface{}{"$regex": dr.Search}},
+			map[string]interface{}{"title": map[string]interface{}{"$regex": dr.Search}},
+		}
+	}
+	qu.Debug("导入任务query:", query)
+	querynum = util.MgoS.Count("spider_warn_err", query)
+	if querynum == 0 {
+		return
+	}
+	if isbidding { //如果是bidding数据,需保存到bidding_cp表一份数据
+		coll = "bidding_copy"
+	}
+	sess := util.MgoS.GetMgoConn()
+	defer util.MgoDT.DestoryMongoConn(sess)
+	ch := make(chan bool, 5)
+	wg := &sync.WaitGroup{}
+	lock := &sync.Mutex{}
+	fields := map[string]interface{}{
+		"data": 1,
+	}
+	it := sess.DB(util.MgoS.DbName).C("spider_warn_err").Find(&query).Select(&fields).Iter()
+	n := 0
+	saveColl := [][]map[string]interface{}{}
+	saveBidding := [][]map[string]interface{}{}
+	//oknum := 0 //记录biding数据从线上拉取的数量
+	for tmp := make(map[string]interface{}); it.Next(tmp); n++ {
+		ch <- true
+		wg.Add(1)
+		go func(tmp map[string]interface{}) {
+			defer func() {
+				<-ch
+				wg.Done()
+			}()
+			update := []map[string]interface{}{}
+			update = append(update, map[string]interface{}{"_id": tmp["_id"]})
+			set := map[string]interface{}{}
+			if data, ok := tmp["data"].(map[string]interface{}); ok { //必要字段
+				for _, field := range util.ImportDataFieldsCheck {
+					if data[field] == nil { //必要字段不存在,视为异常数据
+						return
+					}
+					if field == "publishtime" { //
+						if pt, ok := data[field].(int64); ok {
+							set[field] = qu.FormatDateByInt64(&pt, qu.Date_Full_Layout)
+						} else if pt, ok := data[field].(float64); ok {
+							ptInt64 := int64(pt)
+							set[field] = qu.FormatDateByInt64(&ptInt64, qu.Date_Full_Layout)
+						} else if pt, ok := data[field].(string); ok {
+							if publishtimeReg2.MatchString(pt) { //2022-10-15 23:49:49
+								set[field] = pt
+							} else if publishtimeReg1.MatchString(pt) { //2022-10-15
+								set[field] = pt + " 00:00:00"
+							} else {
+								set[field] = pt
+							}
+						} else {
+							qu.Debug("spider_warn_err发布时间异常:", tmp["_id"])
+							set[field] = "0"
+						}
+					} else {
+						set[field] = data[field]
+					}
+				}
+			}
+			state := 0 //标记是否找到对应的bidding数据
+			if isbidding {
+				//根据title、spidercode、href查询线上bidding信息
+				title := qu.ObjToString(set["title"])
+				spidercode := qu.ObjToString(set["spidercode"])
+				href := qu.ObjToString(set["href"])
+				list, _ := util.MgoB.Find("bidding", map[string]interface{}{"title": title}, nil, nil, false, -1, -1)
+				for _, l := range *list {
+					if qu.ObjToString(l["href"]) == href && qu.ObjToString(l["spidercode"]) == spidercode {
+						state = 1
+						lock.Lock()
+						oknum++
+						l["state"] = 0
+						saveBidding = append(saveBidding, []map[string]interface{}{
+							map[string]interface{}{
+								"_id": l["_id"],
+							},
+							map[string]interface{}{
+								"$set": l,
+							},
+						})
+						lock.Unlock()
+						break
+					}
+				}
+			}
+			set["state"] = state
+			set["times"] = 0
+			update = append(update, map[string]interface{}{"$set": set})
+			lock.Lock()
+			if !isbidding { //非bidding数据导入的数据量
+				oknum++
+			}
+			saveColl = append(saveColl, update)
+			if len(saveColl) > 50 {
+				util.MgoDT.UpSertBulk(coll, saveColl...)
+				saveColl = [][]map[string]interface{}{}
+			}
+			if len(saveBidding) > 50 {
+				util.MgoDT.UpSertBulk("bidding", saveBidding...)
+				saveBidding = [][]map[string]interface{}{}
+			}
+			lock.Unlock()
+		}(tmp)
+		if n%100 == 0 {
+			qu.Debug("current:", n)
+		}
+		tmp = map[string]interface{}{}
+	}
+	wg.Wait()
+	if len(saveColl) > 0 {
+		util.MgoDT.UpSertBulk(coll, saveColl...)
+		saveColl = [][]map[string]interface{}{}
+	}
+	if len(saveBidding) > 0 {
+		util.MgoDT.UpSertBulk("bidding", saveBidding...)
+		saveBidding = [][]map[string]interface{}{}
+	}
+	ok = true
+	return
+}
+
 func checkField(result map[string]interface{}) (arr []string) {
 	defer qu.Catch()
-	for _, f := range []string{"href", "title", "site", "channel", "area", "spidercode", "publishtime"} {
-		if qu.ObjToString(result[f]) == "" {
+	for _, f := range util.ImportDataFieldsCheck {
+		if result[f] == nil {
 			arr = append(arr, f)
 		}
 	}

+ 1 - 0
src/front/front.go

@@ -58,6 +58,7 @@ type Front struct {
 	importData     xweb.Mapper `xweb:"/front/data/importdata"`     //数据导入
 	prepareBidding xweb.Mapper `xweb:"/front/data/preparebidding"` //基于基本信息,检索bidding表对应数据
 	viewBidding    xweb.Mapper `xweb:"/front/data/viewbidding"`    //展示拉取bidding的结果
+	importTask     xweb.Mapper `xweb:"/front/data/importtask"`     //导入任务
 
 	//lua
 	warnList     xweb.Mapper `xweb:"/front/lua/warnlist"`     //spider_warn异常数据

+ 9 - 3
src/front/lua.go

@@ -26,13 +26,14 @@ func (f *Front) WarnList() {
 		defer qu.Catch()
 		repeat, _ := f.GetInteger("repeat")
 		from := f.GetString("from")
+		level, _ := f.GetInteger("level")
 		start, _ := f.GetInteger("start")
 		limit, _ := f.GetInteger("length")
 		draw, _ := f.GetInteger("draw")
 		startTime, _ := f.GetInt("starttime")
 		searchStr := f.GetString("search[value]")
 		search := strings.TrimSpace(searchStr)
-		qu.Debug(startTime, start, limit, draw)
+		qu.Debug("time:", startTime, " search:", search, " repeat:", repeat, " from:", from, " level:", level, start, limit, draw)
 		sort := `{"%s":%d}`
 		orderIndex := f.GetString("order[0][column]")
 		orderName := f.GetString(fmt.Sprintf("columns[%s][data]", orderIndex))
@@ -44,6 +45,9 @@ func (f *Front) WarnList() {
 		query := map[string]interface{}{
 			"ok": false,
 		}
+		if level != -1 {
+			query["level"] = level
+		}
 		if repeat != -1 {
 			query["repeat"] = repeat == 1
 		}
@@ -80,6 +84,8 @@ func (f *Front) WarnList() {
 			"recordsTotal":    count,
 		})
 	} else {
+		f.T["datadb"] = DataBb
+		f.T["dataflows"] = FlowsArr
 		f.Render("lua/warnlist.html", &f.T)
 	}
 }
@@ -125,8 +131,8 @@ func (f *Front) UploadFile() {
 	} else {
 		fileMap := make(map[string]*multipart.File)
 		for _, hf := range mf {
-			f, _ := hf.Open()
-			fileMap[hf.Filename] = &f
+			file, _ := hf.Open()
+			fileMap[hf.Filename] = &file
 		}
 		var fileArr []map[string]interface{}
 		if err := json.Unmarshal([]byte(files), &fileArr); err != nil {

+ 29 - 15
src/front/task.go

@@ -54,19 +54,7 @@ func (f *Front) TaskSave() {
 	coll := f.GetString("coll")
 	ok := false
 	msg := ""
-	if !RunningTask[coll] { //正在执行中的任务表
-		if coll == DataColl && !MgoDT.Del("extract", nil) { //如果是bidding数据,清理extract抽取表,bidding表手动清理
-			msg = "extract表清理失败"
-			goto L
-		}
-		//if MgoDT.Count(coll, nil) == 0 { //先导数据再建任务
-		//	msg = "表:" + coll + "无数据,请先导入数据再创建任务"
-		//	goto L
-		//}
-		user := f.GetSession("user").(map[string]interface{})
-		id := f.GetString("id")
-		name := f.GetString("name")
-		checkfields := f.GetString("checkfields")
+	if msg = CheckTask(coll); msg == "" { //正在执行中的任务表
 		isbidding := f.GetString("isbidding")
 		flows := f.GetString("flows")
 		flowsArr := []string{}
@@ -76,6 +64,24 @@ func (f *Front) TaskSave() {
 				flowsArr = append(flowsArr, flow)
 			}
 		}
+		if isbidding == "是" && len(flowsArr) > 0 { //如果是bidding数据并且走数据流程,清理extract抽取表
+			if !MgoDT.Del("extract", nil) {
+				msg = "extract表清理失败"
+				goto L
+			}
+		}
+		//if coll == DataColl && !MgoDT.Del("extract", nil) { //如果是bidding数据,清理extract抽取表,bidding表手动清理
+		//	msg = "extract表清理失败"
+		//	goto L
+		//}
+		//if MgoDT.Count(coll, nil) == 0 { //先导数据再建任务
+		//	msg = "表:" + coll + "无数据,请先导入数据再创建任务"
+		//	goto L
+		//}
+		user := f.GetSession("user").(map[string]interface{})
+		id := f.GetString("id")
+		name := f.GetString("name")
+		checkfields := f.GetString("checkfields")
 		qu.Debug(id, name, coll, isbidding, flows)
 		query := map[string]interface{}{}
 		set := map[string]interface{}{}
@@ -97,8 +103,6 @@ func (f *Front) TaskSave() {
 			set["issend"] = false
 		}
 		ok = Mgo.Update("task", query, map[string]interface{}{"$set": set}, true, false)
-	} else {
-		msg = "表:" + coll + "已被占用"
 	}
 L:
 	f.ServeJson(map[string]interface{}{"rep": ok, "msg": msg})
@@ -209,3 +213,13 @@ func CheckCodeState(coll string) (errCode []string) {
 	}
 	return
 }
+
+//校验任务是否可创建
+func CheckTask(coll string) (msg string) {
+	if Mgo.Count("task", map[string]interface{}{"delete": false, "s_coll": coll, "i_state": 0}) > 0 { //存在coll表未执行任务,不能新建任务
+		msg = "已存在" + coll + "表未执行任务,无法重复新建任务"
+	} else if RunningTask[coll] { //存在coll表正在执行的任务
+		msg = "已存在" + coll + "表正在执行的任务,无法重复新建任务"
+	}
+	return
+}

+ 1 - 1
src/spider/handler.go

@@ -12,7 +12,7 @@ import (
 func NewSpider(code, luafile string) (*Spider, string) {
 	defer mu.Catch()
 	spider := &Spider{}
-	err := spider.LoadScript(&spider.Name, &spider.Channel, &spider.MUserName, code, luafile, true, true)
+	err := spider.LoadScript(&spider.Name, &spider.Channel, &spider.MUserName, code, luafile)
 	if err != "" {
 		return nil, err
 	}

+ 1 - 1
src/spider/script.go

@@ -59,7 +59,7 @@ type Script struct {
 
 var ErrFid = "a6879f0a8570256aa21fb978e6dabb50429a30dfacff697cf0b898abbc5c262e" //限制访问的附件
 //加载文件
-func (s *Script) LoadScript(site, channel, user *string, code, script_file string, newstate bool, thread bool) string {
+func (s *Script) LoadScript(site, channel, user *string, code, script_file string) string {
 	defer mu.Catch()
 	s.SCode = code
 	s.ScriptFile = script_file

+ 109 - 54
src/task/task.go

@@ -20,14 +20,14 @@ var RunningTask = map[string]bool{} //记录正在执行的任务所用的表
 var TaskLock = &sync.Mutex{}
 
 type Task struct {
-	ID              string
-	Name            string
-	DB              string
-	Coll            string
-	IsBidding       bool
-	Flows           []string
-	SpiderScriptMap map[string]*spider.Spider
-	CheckFields     map[string]bool
+	ID              string                    //任务id
+	Name            string                    //任务名称
+	DB              string                    //操作库
+	Coll            string                    //操作表
+	IsBidding       bool                      //操作表是否为bidding数据
+	Flows           []string                  //流程
+	SpiderScriptMap map[string]*spider.Spider //
+	CheckFields     map[string]bool           //校验字段
 }
 
 func (t *Task) StartTask() {
@@ -79,6 +79,7 @@ func (t *Task) InitLuas() {
 			lua, _ := MgoE.FindOne("luaconfig", map[string]interface{}{"code": code})
 			script := spider.GetScriptByTmp(*lua)
 			sp, errstr := spider.NewSpider(code, script)
+			sp.IsMainThread = true
 			if errstr == "" && sp != nil && sp.Code != "nil" { //脚本加载成功
 				lock.Lock()
 				t.SpiderScriptMap[code] = sp
@@ -94,46 +95,72 @@ func (t *Task) InitLuas() {
 //开始下载数据
 func (t *Task) StartJob() {
 	defer qu.Catch()
-	//更新任务状态,i_state=2
 	defer func() {
 		t.SpiderScriptMap = map[string]*spider.Spider{} //手动重置
-		MgoDT.UpdateById(t.Coll, t.ID, map[string]interface{}{"$set": map[string]interface{}{"i_state": 2}})
 	}()
 	logger.Debug(t.Name, t.ID, t.Coll, "开始重采数据...")
 	wg := &sync.WaitGroup{}
-	spch := make(chan bool, sputil.Config.SpiderChan)
+	ch := make(chan bool, sputil.Config.SpiderChan)
 	for code, sp := range t.SpiderScriptMap {
 		wg.Add(1)
-		spch <- true
+		ch <- true
 		go func(spidercode string, sp *spider.Spider) {
 			defer func() {
-				logger.Info(t.Name, "	", code, "	执行完毕...")
-				<-spch
+				logger.Info(t.Name, " ", spidercode, "	执行完毕...")
+				<-ch
 				sp.L.Close()
 				wg.Done()
 			}()
-			sess := MgoDT.GetMgoConn()
-			defer MgoDT.DestoryMongoConn(sess)
-			//每个爬虫加载需要下载的数据
-			q := map[string]interface{}{ //查询未下载成功的数据
-				"spidercode": spidercode,
-				"state":      0,
-				//"state": map[string]interface{}{
-				//	"$ne": 1,
-				//},
-			}
-			fields := map[string]interface{}{
-				"href":        1,
-				"title":       1,
-				"publishtime": 1,
-				"jsondata":    1,
-				"times":       1,
+			t.download(sp)
+		}(code, sp)
+	}
+	wg.Wait()
+	logger.Info(t.Name, t.ID, t.Coll, "重采完毕...")
+}
+
+func (t *Task) download(sp *spider.Spider) {
+	//每个爬虫加载需要下载的数据
+	q := map[string]interface{}{ //查询未下载成功的数据
+		"spidercode": sp.Code,
+		"state":      0,
+		//"state": map[string]interface{}{
+		//	"$ne": 1,
+		//},
+	}
+	fields := map[string]interface{}{
+		"href":        1,
+		"title":       1,
+		"publishtime": 1,
+		"jsondata":    1,
+		"times":       1,
+	}
+	for {
+		countNum := MgoDT.Count(t.Coll, q) //统计需下载数据个数
+		if countNum > 0 {
+			//多线程
+			threadNum := countNum / sputil.Config.ThreadBaseNum //线程数
+			if threadNum > sputil.Config.ThreadUpperLimit {     //设置单个爬虫线程上限
+				threadNum = sputil.Config.ThreadUpperLimit
 			}
-			for {
-				list, _ := MgoDT.Find(t.Coll, q, nil, fields, false, 0, 100)
-				if list != nil && len(*list) > 0 {
-					updateArr := [][]map[string]interface{}{}
-					for _, l := range *list {
+			logger.Info("Thread Info:	Code:", sp.SCode, "	count:", countNum, "	thread num:", threadNum)
+			list, _ := MgoDT.Find(t.Coll, q, nil, fields, false, 0, 200)
+			if list != nil && len(*list) > 0 {
+				spChan := make(chan *spider.Spider, threadNum+1) //初始化线程通道(+1表示基本的线程数)
+				if threadNum > 1 {
+					NewSpiderByScript(threadNum, sp, spChan) //初始化多个sp
+				}
+				spChan <- sp //主线程sp放入通道
+				spWg := &sync.WaitGroup{}
+				spLock := &sync.Mutex{}
+				updateArr := [][]map[string]interface{}{}
+				for _, l := range *list {
+					spTmp := <-spChan //通道中取出sp对象
+					spWg.Add(1)
+					go func(l map[string]interface{}, spt *spider.Spider) {
+						defer func() {
+							spChan <- spt //处理完数据sp对象放回通道中
+							spWg.Done()
+						}()
 						//_id := tmp["_id"]
 						update := []map[string]interface{}{}
 						data := map[string]interface{}{}
@@ -158,7 +185,7 @@ func (t *Task) StartJob() {
 						data["href"] = l["href"]
 						var err interface{}
 						//下载详情页
-						tmp, err = sp.DownloadDetailPage(data, tmp)
+						tmp, err = spt.DownloadDetailPage(data, tmp)
 						//删除多余字段
 						//delete(result, "exit")
 						//delete(result, "checkpublishtime")
@@ -171,8 +198,10 @@ func (t *Task) StartJob() {
 							set := map[string]interface{}{"$set": ss}
 							update = append(update, query)
 							update = append(update, set)
+							spLock.Lock()
 							updateArr = append(updateArr, update)
-							continue
+							spLock.Unlock()
+							return
 						}
 						//正文、附件分析,下载异常数据重新下载
 						if AnalysisProjectInfo(tmp) {
@@ -184,8 +213,10 @@ func (t *Task) StartJob() {
 							set := map[string]interface{}{"$set": ss}
 							update = append(update, query)
 							update = append(update, set)
+							spLock.Lock()
 							updateArr = append(updateArr, update)
-							continue
+							spLock.Unlock()
+							return
 						}
 						l_np_publishtime := qu.Int64All(tmp["l_np_publishtime"])
 						if l_np_publishtime > time.Now().Unix() || l_np_publishtime == 0 { //防止发布时间超前
@@ -201,22 +232,31 @@ func (t *Task) StartJob() {
 						//下载成功
 						update = append(update, query)
 						update = append(update, map[string]interface{}{"$set": result})
+						spLock.Lock()
 						updateArr = append(updateArr, update)
+						spLock.Unlock()
 						//MgoDT.UpdateById(t.Coll, _id, map[string]interface{}{"$set": map[string]interface{}{"result": result}})
+					}(l, spTmp)
+				}
+				spWg.Wait()
+				if len(updateArr) > 0 {
+					MgoDT.UpdateBulk(t.Coll, updateArr...)
+					updateArr = [][]map[string]interface{}{}
+				}
+				close(spChan) //关闭通道
+				//释放sp对象(保留主线程sp,IsMainThread=true)
+				for spTmp := range spChan {
+					if spTmp != nil && !spTmp.IsMainThread {
+						spTmp.L.Close()
 					}
-					if len(updateArr) > 0 {
-						MgoDT.UpdateBulk(t.Coll, updateArr...)
-						updateArr = [][]map[string]interface{}{}
-					}
-				} else {
-					break
 				}
+				//重载主线程sp
+				//sp.LoadScript(&sp.Name, &sp.Channel, &sp.MUserName, sp.Code, sp.ScriptFile)
 			}
-
-		}(code, sp)
+		} else {
+			break
+		}
 	}
-	wg.Wait()
-	logger.Info(t.Name, t.ID, t.Coll, "重采完毕...")
 }
 
 //字段校验
@@ -274,8 +314,6 @@ func (t *Task) SendData() {
 	} else { //2、非bidding数据推送
 		t.SendNotBiddingData()
 	}
-	//更新任务,数据已推送
-	Mgo.UpdateById("task", t.ID, map[string]interface{}{"$set": map[string]interface{}{"issend": true}})
 }
 
 //非bidding数据推送保存服务
@@ -306,14 +344,15 @@ func (t *Task) SendNotBiddingData() {
 			delete(tmp, "_id")
 			tmp["dataging"] = 0 //补充dataging字段
 			//tmp["T"] = "bidding"
-			ok, id, coll := SaveObj(4002, "title", tmp)
+			ok, saveid, savecoll := SaveObj(4002, "title", tmp)
 			update := []map[string]interface{}{
 				map[string]interface{}{"_id": id},
 				map[string]interface{}{
 					"$set": map[string]interface{}{
 						"sendflag":    ok,
-						"biddingid":   id,
-						"biddingcoll": coll,
+						"biddingid":   saveid,
+						"biddingcoll": savecoll,
+						"state":       2,
 					},
 				},
 			}
@@ -339,7 +378,7 @@ func (t *Task) SendBiddingData() {
 	defer qu.Catch()
 	lteid := mongodb.BsonIdToSId(primitive.NewObjectID())
 	if len(t.Flows) > 0 { //进入数据处理流程
-		SendUdp(t.Coll, GTEID, lteid, "extract", FlowsMap["抽取"].Addr, FlowsMap["抽取"].Port) //直接抽取
+		SendUdp(t.Coll, GTEID, lteid, "extract", FlowsMap["抽取"].Addr, FlowsMap["抽取"].Port) //直接抽取
 	} else {
 		UpdateBiddingData(GTEID, mongodb.BsonIdToSId(primitive.NewObjectID())) //更新线上bidding表
 	}
@@ -403,3 +442,19 @@ func SaveObj(event int, checkAtrr string, data map[string]interface{}) (flagstr,
 	}
 	return
 }
+
+//初始化sp对象
+func NewSpiderByScript(num int, sp *spider.Spider, spChan chan *spider.Spider) {
+	for i := 1; i <= num; i++ {
+		spTmp, errstr := spider.NewSpider(sp.Code, sp.ScriptFile)
+		if errstr == "" && spTmp != nil { //脚本加载成功
+			spTmp.UserName = sp.UserName
+			spTmp.UserEmail = sp.UserEmail
+			spTmp.MUserName = sp.MUserName
+			spTmp.MUserEmail = sp.MUserEmail
+			spChan <- spTmp
+		} else {
+			spChan <- nil
+		}
+	}
+}

+ 20 - 3
src/udptask/udptask.go

@@ -84,14 +84,17 @@ func UpdateBiddingData(gtid, lteid string) {
 		"_d":          0,
 		"publishdept": 0,
 	}
-	count := util.MgoDT.Count(util.DataColl, query)
+	//count := util.MgoDT.Count(util.DataColl, query)
+	count := util.MgoDT.Count("bidding", query)
 	logger.Info("更新数据ID段:", query, count)
-	it := sess.DB(util.DataBb).C(util.DataColl).Find(&query).Select(&fields).Iter()
+	//it := sess.DB(util.DataBb).C(util.DataColl).Find(&query).Select(&fields).Iter()
+	it := sess.DB(util.DataBb).C("bidding").Find(&query).Select(&fields).Iter()
 	n := 0
 	ch := make(chan bool, 2)
 	wg := &sync.WaitGroup{}
 	lock := &sync.Mutex{}
 	arr := [][]map[string]interface{}{}
+	arrTmp := [][]map[string]interface{}{}
 	for tmp := make(map[string]interface{}); it.Next(&tmp); n++ {
 		wg.Add(1)
 		ch <- true
@@ -107,11 +110,21 @@ func UpdateBiddingData(gtid, lteid string) {
 				},
 			}
 			lock.Lock()
-			arr = append(arr, update)
+			arr = append(arr, update)                         //线上bidding表
+			arrTmp = append(arrTmp, []map[string]interface{}{ //任务表
+				map[string]interface{}{"_id": tmp["_id"]},
+				map[string]interface{}{
+					"$set": map[string]interface{}{"state": 2},
+				},
+			})
 			if len(arr) > 50 {
 				util.MgoB.UpdateBulk("bidding", arr...)
 				arr = [][]map[string]interface{}{}
 			}
+			if len(arrTmp) > 50 {
+				util.MgoDT.UpdateBulk("bidding", arrTmp...)
+				arrTmp = [][]map[string]interface{}{}
+			}
 			lock.Unlock()
 		}(tmp)
 		tmp = map[string]interface{}{}
@@ -121,6 +134,10 @@ func UpdateBiddingData(gtid, lteid string) {
 		util.MgoB.UpdateBulk("bidding", arr...)
 		arr = [][]map[string]interface{}{}
 	}
+	if len(arrTmp) > 0 {
+		util.MgoDT.UpdateBulk("bidding", arrTmp...)
+		arrTmp = [][]map[string]interface{}{}
+	}
 }
 
 //发送udp的时候一个key参数

+ 3 - 2
src/util/config.go

@@ -16,7 +16,7 @@ var (
 	MgoB     *mongodb.MongodbSim //bidding库
 	MgoS     *mongodb.MongodbSim //lua spider库
 	DataBb   string              //数据存储库
-	DataColl string              //数据存储表
+	DataColl string              //数据存储表(特定bidding表)
 	FlowsArr []string            //数据处理流程
 	FlowsMap map[string]*Flow    //数据处理流程对应udp端口
 )
@@ -40,7 +40,8 @@ func InitMgoPool() {
 	Mgo.InitPool()
 	//重采数据库
 	DataBb = Config.DataDB.Db
-	DataColl = Config.DataDB.Coll
+	//DataColl = Config.DataDB.Coll
+	DataColl = "bidding"
 	MgoDT = &mongodb.MongodbSim{
 		MongodbAddr: Config.DataDB.Addr,
 		DbName:      DataBb,

+ 2 - 0
src/util/util.go

@@ -33,6 +33,8 @@ var Fields = map[string]interface{}{
 	//"type":        1,
 }
 
+var ImportDataFieldsCheck = []string{"href", "title", "site", "channel", "area", "city", "district", "spidercode", "publishtime"}
+
 const GTEID = "5a862f0640d2d9bbe88e3cec"
 
 //处理因前后端交互,字段类型转换

+ 9 - 3
src/web/res/js/com.js

@@ -75,10 +75,16 @@ com.serializeArray=function(id){
 	$("#"+id+" [name]").each(function(){
 		var name=$(this).prop("name");
 		var value=$(this).prop("value");
-		if($(this).get(0).tagName=="TEXTAREA" && $(this).attr("id")){
-			if($(this).attr("id").indexOf("s_luascript")>-1){
-				value=editor_1.getValue()
+		if($(this).get(0).tagName=="TEXTAREA" && $(this).attr("id")) {
+			if ($(this).attr("id").indexOf("s_luascript") > -1) {
+				value = editor_1.getValue()
 			}
+		}else if ($(this).attr("selectoption") == "all"){//select下所有option的值都要
+			var arr = [];
+			$(this).find("option").each(function (){
+				arr.push($(this).val());
+			})
+			value = arr.join(",");
 		}else{
 			value=$(this).prop("value");
 			value=value?value:"";

+ 54 - 4
src/web/templates/com/header.html

@@ -129,10 +129,29 @@
 	</div><!-- /.modal -->
 </div>
 
-<style>
-
-
-</style>
+	<style>
+		#selectclear2 select {
+			width:190px;
+			height:167px;
+			padding:5px;
+		}
+		#selectclear2{
+			display: flex;
+			flex-direction: row;
+		}
+		#selectclear2 .move{
+			display: flex;
+			flex-direction: column;
+			margin: 20px 25px
+		}
+		#selectclear2 .move button{
+			margin: 1px 0px;
+			padding: 4px 6px;
+		}
+		#selectclear2 .doublebox {
+			text-align:center;
+		}
+	</style>
 <!-- /.modal -->
 <script>
 function t_save(){
@@ -160,4 +179,35 @@ showLoading = function (text){
 hideLoading = function (){
 	$('#loading').modal('hide');
 }
+
+$(function () {
+	//右移
+	$("#selectclear2 #right2").click(function(){
+		$("#select3 option:selected").appendTo("#select4");
+	});
+	//左移
+	$("#selectclear2 #left2").click(function(){
+		$("#select4 option:selected").appendTo("#select3");
+	});
+	$("#selectclear2 #up2,#selectclear2 #down2").click(function() {
+		var $opt = $("#select4 option:selected:first");
+		if (!$opt.length){
+			return;
+		}
+		if (this.id == "up2"){
+			$opt.prev().before($opt);
+		}else{
+			$opt.next().after($opt);
+		}
+	});
+	//双击右移
+	$("#selectclear2 #select3").dblclick(function(){
+		$("#selectclear2 #select3 option:selected").appendTo("#select4");
+	});
+	//双击左移
+	$("#selectclear2 #select4").dblclick(function(){
+		$("#selectclear2 #select4 option:selected").appendTo("#select3");
+	});
+})
+
 </script>

+ 260 - 64
src/web/templates/lua/warnlist.html

@@ -10,7 +10,7 @@
         <h1>
             <small>
                 <button type="button" class="btn btn-primary" data-toggle="modal" onclick="batchprocess(2)">批量删除</button>
-<!--                <button type="button" class="btn btn-primary" data-toggle="modal" onclick="batchprocess(4)">批量发布</button>-->
+                <button type="button" class="btn btn-success" data-toggle="modal" onclick="importtaskshow()">导入任务</button>
             </small>
         </h1>
         <ol class="breadcrumb">
@@ -68,6 +68,99 @@
     </section>
 </div>
 
+<div class="modal fade" id="task_modal">
+    <div class="modal-dialog">
+        <form id="task_form" class="form-horizontal" role="form">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">任务详情</h4>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="name" class="col-sm-2 control-label">任务名称:</label>
+                        <div class="col-sm-10">
+                            <input id="name" name="name" disabled type="text" class="form-control">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="db" class="col-sm-2 control-label">数据库:</label>
+                        <div class="col-sm-10">
+                            <input id="db" name="db" disabled type="text" class="form-control" value="{{.T.datadb}}">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="coll" class="col-sm-2 control-label">数据表:</label>
+                        <div class="col-sm-10">
+                            <input id="coll" name="coll" disabled type="text" class="form-control" value="warn">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="checkfields" class="col-sm-2 control-label">校验字段:</label>
+                        <div class="col-sm-10">
+                            <input id="checkfields" name="checkfields" type="text" class="form-control"  placeholder="请输入重采校验字段 例:title,detail(多字段逗号分割)">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="isbidding" class="col-sm-2 control-label">Bid数据:</label>
+                        <div class="col-sm-10">
+                            <select id="isbidding" name="isbidding" class="form-control">
+                                <option value="-1">--请选择--</option>
+                                <option value="1">是</option>
+                                <option value="0">否</option>
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="importstype" class="col-sm-2 control-label">导入方式:</label>
+                        <div class="col-sm-10">
+                            <select id="importstype" name="importstype" class="form-control">
+                                <option value="-1">--请选择--</option>
+                                <option value="0">清除</option>
+                                <option value="1">保留</option>
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="createtask" class="col-sm-2 control-label">生成任务:</label>
+                        <div class="col-sm-10">
+                            <select id="createtask" name="createtask" class="form-control">
+                                <option value="-1">--请选择--</option>
+                                <option value="1">是</option>
+                                <option value="0">否</option>
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group" id="selectclear">
+                        <label for="flows" class="col-sm-2 control-label">处理流程:</label>
+                        <div class="col-sm-10" id="selectclear2">
+                            <div class="doublebox">
+                                <select multiple="multiple" id="select3" style="overflow-x: scroll;"></select>
+                            </div>
+                            <div class="move">
+                                <button type="button" id="up2" class="btn btn-primary">上移</button>
+                                <button type="button" id="right2" class="btn btn-primary">右移</button>
+                                <button type="button" id="left2" class="btn btn-primary">左移</button>
+                                <button type="button" id="down2" class="btn btn-primary">下移</button>
+                            </div>
+                            <div class="doublebox">
+                                <select multiple="multiple" id="select4" name="select4" selectoption="all" style="overflow-x: scroll;"></select>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-primary" onclick="importtask()">保存</button>
+                </div>
+            </div>
+            <!-- /.modal-content -->
+        </form>
+    </div>
+    <!-- /.modal-dialog -->
+</div>
+
 <!-- footer -->
 {{include "com/footer.html"}}
 
@@ -96,14 +189,12 @@
             "autoWidth":false,
             "bLengthChange":true,//支持分页数选择
             "columns": [
-                { "data": "_id",render:function(val,a,row){
+                {"data": "_id",render:function(val,a,row){
             				return "<input type='checkbox' value='"+val+"' />"
             			}},
-                {
-                    "data": "title", render: function (val, a, row) {
+                {"data": "title", render: function (val, a, row) {
                         return val="<a href='"+row.href+"' title='"+row.title+"' target='_blank'>"+val+"</a>"
-                    }
-                },
+                }},
                 {"data": "spidercode"},
                 {"data": "site"},
                 {"data": "level", render: function (val, a, row) {
@@ -122,82 +213,110 @@
                     }},
                 {"data": "from"},
                 {"data": "info"},
-                {
-                  "data": "_id", render: function (val, a, row) {
+                {"data": "_id", render: function (val, a, row) {
                       return "<a href='/front/lua/warnedit?id="+val+"&num=1'><i class='fa fa-fw fa-edit text-yellow'></i></a>";
-                  }
-                }
+                }}
             ],
             "fnServerParams": function (e) {
-              if($('#starttime').length !=0){
-                var st = $('#starttime').datepicker('getDate')
-                if (st != null) {
-                  var s = st.toLocaleDateString()
-                  var sc = Date.parse(new Date(s).toString())/1000
-                  e.starttime = sc
+                if($('#starttime').length !=0){
+                    var st = $('#starttime').datepicker('getDate')
+                    if (st != null) {
+                        var s = st.toLocaleDateString()
+                        var sc = Date.parse(new Date(s).toString())/1000
+                        e.starttime = sc
+                    }
+                }else{
+                    var nst = Date.parse(new Date().toLocaleDateString())/1000;
+                    e.starttime = nst
                 }
-              }else{
-                var nst = Date.parse(new Date().toLocaleDateString())/1000;
-                e.starttime = nst
-              }
-              //repeat
-              var repeat = $("#repeat").val();
-              if(repeat){
-                  e.repeat = repeat;
-              }else{
-                  e.repeat= -1;
-              }
-              //来源
+                //异常类型
+                var level = $("#level").val();
+                if(level){
+                    e.level = level;
+                }else{
+                    e.level= '-1';
+                }
+                //repeat
+                var repeat = $("#repeat").val();
+                if(repeat){
+                    e.repeat = repeat;
+                }else{
+                    e.repeat= '-1';
+                }
+                //来源
                 var from = $("#from").val();
                 if(from){
                     e.from = from;
                 }else{
-                    e.from= -1;
+                    e.from= '-1';
                 }
             }
         });
         ttable.on('init.dt', function () {
-          var errStype = "<div style='margin-top: -4px'>"+
-            "<span class='input-group date date-picker' id='starttime' data-provide='datepicker'>"+
-                "<input type='text' class='form-control form-filter input-sm' readonly name='starttime' placeholder='开始日期' />"+
-                 "<span class='input-group-addon'>"+
-                    "<i class='fa fa-calendar'></i>"+
-                  "</span>"+
-            "</span>"+
-         "</div>&nbsp;"
-          
-          var selectRepeat="<div class='form-group' style='margin-top: -4px'><label for='name'>是否重复:</label>"+
-              "<select id='repeat' onchange='checkclick(this.value)' class='form-control input-sm'>"+
-              "<option value='-1'>全部</option>"+
-              "<option value='1'>是</option>"+
-              "<option value='0'>否</option>"+
-              "</select></div>"
-          var selectFrom="<div class='form-group' style='margin-top: -4px'><label for='name'>来源:</label>"+
-              "<select id='from' onchange='checkclick(this.value)' class='form-control input-sm'>"+
-              "<option value='-1'>全部</option>"+
-              "<option value='list'>list</option>"+
-              "<option value='warn'>warn</option>"+
-              "</select></div>"
-          $("#spiderwarn_filter").prepend(errStype);
-          $("#spiderwarn_filter").prepend("&nbsp;");
-          $("#spiderwarn_filter").prepend(selectRepeat);
-          $("#spiderwarn_filter").prepend("&nbsp;&nbsp");
-          $("#spiderwarn_filter").prepend(selectFrom);
-          $("#spiderwarn_length").parent().css("width", "10%")
-          $("#spiderwarn_filter").parent().css("width", "90%")
-          $("#spiderwarn_filter").css({"display": "flex","text-align": "right","align-items": "center","justify-content": "flex-end"})
+            var selectLevel="<div class='form-group' style='margin-top: -4px'><label for='name'>类型:</label>"+
+                "<select id='level' onchange='checkclick(this.value)' class='form-control input-sm'>"+
+                "<option value='-1'>全部</option>"+
+                "<option value='1'>警告</option>"+
+                "<option value='2'>错误</option>"+
+                "</select></div>"
+            var selectTime = "<div style='margin-top: -4px'>"+
+                "<span class='input-group date date-picker' id='starttime' data-provide='datepicker'>"+
+                    "<input type='text' class='form-control form-filter input-sm' readonly name='starttime' placeholder='开始日期' />"+
+                     "<span class='input-group-addon'>"+
+                        "<i class='fa fa-calendar'></i>"+
+                      "</span>"+
+                "</span>"+
+            "</div>&nbsp;"
+            var selectRepeat="<div class='form-group' style='margin-top: -4px'><label for='name'>是否重复:</label>"+
+                "<select id='repeat' onchange='checkclick(this.value)' class='form-control input-sm'>"+
+                "<option value='-1'>全部</option>"+
+                "<option value='1'>是</option>"+
+                "<option value='0'>否</option>"+
+                "</select></div>"
+            var selectFrom="<div class='form-group' style='margin-top: -4px'><label for='name'>来源:</label>"+
+                "<select id='from' onchange='checkclick(this.value)' class='form-control input-sm'>"+
+                "<option value='-1'>全部</option>"+
+                "<option value='list'>list</option>"+
+                "<option value='warn'>warn</option>"+
+                "</select></div>"
+            $("#spiderwarn_filter").prepend(selectTime);
+            $("#spiderwarn_filter").prepend("&nbsp;");
+            $("#spiderwarn_filter").prepend(selectLevel);
+            $("#spiderwarn_filter").prepend("&nbsp;");
+            $("#spiderwarn_filter").prepend(selectRepeat);
+            $("#spiderwarn_filter").prepend("&nbsp;&nbsp");
+            $("#spiderwarn_filter").prepend(selectFrom);
+            $("#spiderwarn_length").parent().css("width", "10%")
+            $("#spiderwarn_filter").parent().css("width", "90%")
+            $("#spiderwarn_filter").css({"display": "flex","text-align": "right","align-items": "center","justify-content": "flex-end"})
 
-          $('.date-picker').datepicker({
+            $('.date-picker').datepicker({
               language: 'zh-CN',
               autoclose: true,
               clearBtn: true, //清除按钮
               todayBtn: false, //今日按钮
               format: "yyyy-mm-dd"
-          });
-          $('#starttime').datepicker('setDate',new Date().toLocaleDateString());//设置初始时间
-          $('#starttime').datepicker().on('changeDate', function (e) {
-              ttable.ajax.reload();
-          });
+            });
+            $('#starttime').datepicker('setDate',new Date().toLocaleDateString());//设置初始时间
+            $('#starttime').datepicker().on('changeDate', function (e) {
+                ttable.ajax.reload();
+            });
+        })
+        //发送到服务器的数据先进行处理
+        ttable.on('preXhr.dt', function ( e, settings, data ) {
+            var request = {};
+            var search = data.search.value;//搜索框值
+            var from = data.from;//来源
+            var repeat = data.repeat;//是否重复
+            var level = data.level;//类型
+            var starttime = data.starttime;//时间
+            request["search"] = search;
+            request["from"] = from;
+            request["repeat"] = repeat;
+            request["level"] = level;
+            request["starttime"] = starttime;
+            com.setCookie("request",JSON.stringify(request));
+            // console.log("1",com.getCookie("request"))
         })
     });
     //批量删除
@@ -243,4 +362,81 @@
     			$("#spiderwarn td input[type=checkbox]").prop("checked",false);
     		}
     	}
+        
+    function importtaskshow() {
+        if (ttable.context[0].aoData.length == 0){//判断当前table的数据data
+            alert("检索无数据,禁止导入任务!")
+            return;
+        }
+        var t = new Date();
+        $("#select3").empty();
+        $("#select4").empty();
+        $("#name").val(t.toLocaleString()+"异常数据处理任务");
+        {{range $index, $flows := .T.dataflows}}
+        $("#select3").append("<option value='"+{{$flows}}+"'>"+{{$flows}}+"</option>");
+        {{end}}
+        $("#task_modal").modal("show");
+    }
+
+    //导入任务
+    function importtask() {
+        var requeststr = com.getCookie("request");
+        var request = JSON.parse(requeststr);
+        var isbidding = $("#isbidding").val();
+        var importstype = $("#importstype").val();
+        var createtask = $("#createtask").val();
+        var checkfields = $("#checkfields").val();
+        if (isbidding == "1" ){
+            if (request.level != "1"){
+                alert('bidding数据只能选择"警告"类型数据!');
+                return;
+            }else if (checkfields == ""){
+                alert("校验字段不能为空!");
+                return;
+            }
+        }else if (isbidding == "0" ) {
+            if (request.level != "2") {
+                alert('非bidding数据只能选择"错误"类型数据!');
+                return;
+            }
+        }else if (isbidding == "-1"){
+            alert('"Bid数据"选项不能为空!')
+            return;
+        }
+        if (importstype == "-1"){
+            alert('"导入方式"选项不能为空!')
+            return;
+        }
+        if (createtask == "-1"){
+            alert('"生成任务"选项不能为空!');
+            return;
+        }
+        var formdataMap = com.serializeArray("task_form");
+        formdataMap["requeststr"]= requeststr;
+        console.log(formdataMap)
+        $("#task_modal").modal("hide");
+        showLoading("正在准备数据...");
+        $.ajax({
+            url:"/front/data/importtask",
+            method:"post",
+            data:formdataMap,
+            success:function(r){
+                hideLoading();
+                showMsg(r.msg, function () {
+
+                });
+            }
+        })
+    }
+
+    $("#isbidding").on('change', function () {
+        var val = $(this).val();
+        if (val == "0"){//不是bidding数据不选数据处理流程,走保存服务;不生成任务
+            $("#selectclear").css('display','none');
+            $("#coll").val('warn');
+        }else{
+            $("#selectclear").css('display','block');
+            $("#coll").val('bidding');
+        }
+    })
 </script>

+ 25 - 52
src/web/templates/role/role_edit.html

@@ -4,34 +4,34 @@
 <!-- Left side column. 权限菜单 -->
 {{include "menu/menu.html"}}
 
-<head>
-    <style>
+<!--<head>-->
+<!--    <style>-->
 
-        #selectclear2 select {
-            width:190px;
-            height:167px;
-            padding:5px;
-        }
-        #selectclear2{
-            display: flex;
-            flex-direction: row;
-        }
-        #selectclear2 .move{
-            display: flex;
-            flex-direction: column;
-            margin: 20px 25px
-        }
-        #selectclear2 .move button{
-            margin: 1px 0px;
-            padding: 4px 6px;
-        }
-        #selectclear2 .doublebox {
-            text-align:center;
-        }
+<!--        #selectclear2 select {-->
+<!--            width:190px;-->
+<!--            height:167px;-->
+<!--            padding:5px;-->
+<!--        }-->
+<!--        #selectclear2{-->
+<!--            display: flex;-->
+<!--            flex-direction: row;-->
+<!--        }-->
+<!--        #selectclear2 .move{-->
+<!--            display: flex;-->
+<!--            flex-direction: column;-->
+<!--            margin: 20px 25px-->
+<!--        }-->
+<!--        #selectclear2 .move button{-->
+<!--            margin: 1px 0px;-->
+<!--            padding: 4px 6px;-->
+<!--        }-->
+<!--        #selectclear2 .doublebox {-->
+<!--            text-align:center;-->
+<!--        }-->
 
 
-    </style>
-</head>
+<!--    </style>-->
+<!--</head>-->
 
 <!-- Content Wrapper. Contains page content -->
 <div class="content-wrapper">
@@ -250,31 +250,4 @@
         })
         $("#modal-info").modal("show");
     }
-
-    $("#selectclear2 #right2").click(function(){
-        $("#select3 option:selected").appendTo("#select4");
-    });
-    //左移
-    $("#selectclear2 #left2").click(function(){
-        $("#select4 option:selected").appendTo("#select3");
-    });
-    $("#selectclear2 #up2,#selectclear2 #down2").click(function() {
-        var $opt = $("#select4 option:selected:first");
-        if (!$opt.length){
-            return;
-        }
-        if (this.id == "up2"){
-            $opt.prev().before($opt);
-        }else{
-            $opt.next().after($opt);
-        }
-    });
-    //双击右移
-    $("#selectclear2 #select3").dblclick(function(){
-        $("#selectclear2 #select3 option:selected").appendTo("#select4");
-    });
-    //双击左移
-    $("#selectclear2 #select4").dblclick(function(){
-        $("#selectclear2 #select4 option:selected").appendTo("#select3");
-    });
 </script>

+ 4 - 1
src/web/templates/task/datalist.html

@@ -87,6 +87,8 @@
                             state = "成功";
                         }else if (val == -1) {
                             state = "失败";
+                        }else if (val == 2){
+                            state = "已推送";
                         }
                         return state
                     }},
@@ -110,7 +112,8 @@
             var dataState="<option value='-2'>全部</option>"+
                 "<option value='0'>未采</option>"+
                 "<option value='1'>成功</option>"+
-                "<option value='-1'>失败</option>";
+                "<option value='-1'>失败</option>"+
+                "<option value='2'>已推送</option>";
             var selectState="<div class='form-group'><label for='name'>状态:</label>"+
                 "<select id='data_state' onchange='checkclick(this.value)' class='form-control input-sm'>"+
                 dataState+

+ 1 - 1
src/web/templates/task/dataview.html

@@ -42,7 +42,7 @@
             <ul class="nav nav-tabs edit-step">
                 </br>
                 <!--非bidding数据且下载成功及state==1的数据,不允许再更新发送保存服务-->
-                {{if or (eq .T.datacoll .T.coll) (and (ne .T.datacoll .T.coll) (ne .T.data.state 1))}}
+                {{if or (eq .T.datacoll .T.coll) (and (ne .T.datacoll .T.coll) )}}
                 <button class="btn btn-primary btn-sm" style="float: right;margin-top: 7px;margin-right: 10px" onclick="saveRepair()"><i class="fa fa-fw fa-file-text fa-lg"></i>更新推送</button>
                 {{end}}
                 </br></br></br>

+ 127 - 66
src/web/templates/task/task.html

@@ -35,14 +35,14 @@
         <h1>
             <small>
                 <button type="button" class="btn btn-success" data-toggle="modal" onclick="add()">新建任务</button>
-                <button type="button" class="btn btn-warning" data-toggle="modal" onclick="importdata()">导入数据</button>
+                <button type="button" class="btn btn-warning" data-toggle="modal" onclick="importdatashow()">导入数据</button>
                 <button type="button" class="btn btn-primary" data-toggle="modal" onclick="preparebidding()">准备bidding</button>
                 <button type="button" class="btn btn-primary" data-toggle="modal" onclick="window.open('/front/data/viewbidding/')">bidding信息</button>
-                <iframe srcdoc="
-                    <form id='uploadform' method='post' enctype='multipart/form-data' action='/front/data/importdata'>
-                        <input type='file' name='xlsx' />
-                    </form>" height=0 scrolling=no class="hide"  id="fileframe">
-                </iframe>
+<!--                <iframe srcdoc="-->
+<!--                    <form id='uploadform' method='post' enctype='multipart/form-data' action='/front/data/importdata'>-->
+<!--                        <input type='file' name='xlsx' />-->
+<!--                    </form>" height=0 scrolling=no class="hide"  id="fileframe">-->
+<!--                </iframe>-->
             </small>
         </h1>
         <ol class="breadcrumb">
@@ -81,6 +81,50 @@
     </section>
 </div>
 
+<!--数据导入-->
+<div class="modal fade" id="importdata" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+                <h4>
+                    <span class="fa fa-upload" id="code-assign" aria-hidden="true"></span>
+                    <span class="info">data</span>
+                </h4>
+
+            </div>
+            <div class="modal-body" style="max-height: 70vh;overflow-y: scroll;">
+                <form class="form-horizontal" role="form">
+                    <div class="group-item">
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">清理数据:</label>
+                            <div class="col-sm-2">
+                                <select id="cleardata" class="form-control">
+                                    <option value="否">否</option>
+                                    <option value="是">是</option>
+                                </select>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">本地文件:</label>
+                            <div class="col-sm-5">
+                                <input type="file" name="file" class="ffile" id="uploadfile">
+                            </div>
+                            <div style="float: right;margin-right: 100px">
+                                <input type="button" class="btn btn-default" data-dismiss="modal" value="取消">
+                                <input type="button" class="btn btn-info" value="导入" onclick="uploadFile()">
+                            </div>
+                        </div>
+                    </div>
+                </form>
+                <!--</div>	-->
+            </div>
+        </div>
+    </div>
+</div>
+
 <div class="modal fade" id="task_modal">
     <div class="modal-dialog">
         <form id="task_form" class="form-horizontal" role="form">
@@ -309,6 +353,7 @@
                         ttable.ajax.reload();
                     } else {
                         showTip(r.msg, 3000, function () {});
+                        ttable.ajax.reload();
                     }
                 }
             })
@@ -377,7 +422,7 @@
         $("#checkfields").val(fields);
         if (isbidding == "true"){
             $("#isbidding").val("是")
-            $("#selectclear").css('display','inline-block')
+            $("#selectclear").css('display','block')
         }else{
             $("#isbidding").val("否")
             $("#selectclear").css('display','none')
@@ -424,47 +469,90 @@
 
     $("#isbidding").on('change', function () {
         var val = $(this).val()
-        console.log(val)
         if (val == "否"){//不是bidding数据不选数据处理流程,走保存服务
-            $("#selectclear").css('display','none')
+            $("#selectclear").css('display','none');
+            $("#coll").val("notbidding");
         }else{
-            $("#selectclear").css('display','inline-block')
+            $("#selectclear").css('display','block');
+            $("#coll").val("bidding");
         }
     })
 
-    function importdata(){
-        var f=$("#fileframe").contents().find("input");
-        f.get(0).click();
-        f.change(function(){
-            var val=$(this).val()?$(this).val():"";
-            if(val.indexOf(".xlsx")<0){
-                showMsg("文件格式非法", function() {});
-            }else{
-                $(this).parent().submit();
-                showLoading("正在导入数据...")
-                var ret=setInterval(function(){
-                    var f=$(window.frames[0].document).find("form");
-                    hideLoading();
-                    if(f.length==0){
-                         var b=$(window.frames[0].document).find("body").html();
-                         showMsg(b, function() {});
-                         $(window.frames[0].document).find("body").append("<form id='uploadform' method='post' enctype='multipart/form-data' action='/front/data/importdata'><input type='file' name='xlsx' /></form>");
-                        // var r=window.confirm("导入完毕,是否查看错误信息");
-                        // if(r){
-                        //     $("#errmsg").removeClass("hide").append(b);
-                        // }
-
-                    }else{
-                        showMsg("数据导入失败", function() {});
-                    }
-                    clearInterval(ret);
-                    ttable.ajax.reload();
-                },5000)
-
+    function importdatashow() {
+        $("#importdata").modal("show");
+    }
+    //导入数据
+    var uploadFileReg = new RegExp("(.xlsx|.xls)$");
+    function uploadFile() {
+        var fData = new FormData();
+        var file = $("#uploadfile")[0].files[0];
+        if (file === undefined) {
+            alert("请选择本地文件!");
+            return;
+        }
+        var fname = file.name;
+        if (!uploadFileReg.test(fname.toLowerCase())){
+            alert("文件类型不对!");
+            return;
+        }
+        fData.append("file", file,fname)
+        fData.append("cleardata",$("#cleardata").val())
+        $('#importdata').modal('hide');
+        showLoading("正在导入数据,请稍候...")
+        $.ajax({
+            url: "/front/data/importdata",
+            type: 'POST',
+            data: fData,
+            cache: false,
+            processData: false,
+            contentType: false,
+            success: function (r) {
+                hideLoading()
+                if (r&&r.ok) {
+                    showTip("数据导入成功",2000,function (r){
+                       reload();
+                    });
+                    window.location.reload();
+                } else {
+                    showMsg(r.msg);
+                }
             }
         })
     }
 
+    // function importdata(){
+    //     var f=$("#fileframe").contents().find("input");
+    //     f.get(0).click();
+    //     f.change(function(){
+    //         var val=$(this).val()?$(this).val():"";
+    //         if(val.indexOf(".xlsx")<0){
+    //             showMsg("文件格式非法", function() {});
+    //         }else{
+    //             $(this).parent().submit();
+    //             showLoading("正在导入数据...")
+    //             var ret=setInterval(function(){
+    //                 var f=$(window.frames[0].document).find("form");
+    //                 hideLoading();
+    //                 if(f.length==0){
+    //                      var b=$(window.frames[0].document).find("body").html();
+    //                      showMsg(b, function() {});
+    //                      $(window.frames[0].document).find("body").append("<form id='uploadform' method='post' enctype='multipart/form-data' action='/front/data/importdata'><input type='file' name='xlsx' /></form>");
+    //                     // var r=window.confirm("导入完毕,是否查看错误信息");
+    //                     // if(r){
+    //                     //     $("#errmsg").removeClass("hide").append(b);
+    //                     // }
+    //
+    //                 }else{
+    //                     showMsg("数据导入失败", function() {});
+    //                 }
+    //                 clearInterval(ret);
+    //                 ttable.ajax.reload();
+    //             },5000)
+    //
+    //         }
+    //     })
+    // }
+
     function preparebidding() {
         showConfirm("确认根据bidding_copy表信息获取对应bidding数据?", function() {
             showLoading("正在准备数据...");
@@ -487,31 +575,4 @@
             })
         })
     }
-    //右移
-    $("#selectclear2 #right2").click(function(){
-        $("#select3 option:selected").appendTo("#select4");
-    });
-    //左移
-    $("#selectclear2 #left2").click(function(){
-        $("#select4 option:selected").appendTo("#select3");
-    });
-    $("#selectclear2 #up2,#selectclear2 #down2").click(function() {
-        var $opt = $("#select4 option:selected:first");
-        if (!$opt.length){
-            return;
-        }
-        if (this.id == "up2"){
-            $opt.prev().before($opt);
-        }else{
-            $opt.next().after($opt);
-        }
-    });
-    //双击右移
-    $("#selectclear2 #select3").dblclick(function(){
-        $("#selectclear2 #select3 option:selected").appendTo("#select4");
-    });
-    //双击左移
-    $("#selectclear2 #select4").dblclick(function(){
-        $("#selectclear2 #select4 option:selected").appendTo("#select3");
-    });
 </script>