| @@ -6,11 +6,12 @@ package models | |||
| import ( | |||
| "bytes" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "fmt" | |||
| "io" | |||
| "path" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/obs" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| api "code.gitea.io/gitea/modules/structs" | |||
| @@ -253,9 +254,33 @@ func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) { | |||
| if remove { | |||
| for i, a := range attachments { | |||
| if err := storage.Attachments.Delete(a.RelativePath()); err != nil { | |||
| return i, err | |||
| if a.Type == TypeCloudBrainOne { | |||
| if err := storage.Attachments.Delete(a.RelativePath()); err != nil { | |||
| return i, err | |||
| } | |||
| } | |||
| if a.Type == TypeCloudBrainTwo { | |||
| input := &obs.DeleteObjectInput{} | |||
| input.Bucket = setting.Bucket | |||
| input.Key = setting.BasePath + path.Join(a.UUID[0:1], a.UUID[1:2], a.UUID, a.Name) | |||
| log.Info("delete obs file:" + input.Key) | |||
| output, err := storage.ObsCli.DeleteObject(input) | |||
| if err == nil { | |||
| fmt.Printf("RequestId:%s\n", output.RequestId) | |||
| } else if obsError, ok := err.(obs.ObsError); ok { | |||
| fmt.Printf("Code:%s\n", obsError.Code) | |||
| fmt.Printf("Message:%s\n", obsError.Message) | |||
| } | |||
| } | |||
| //rf := path.Join(a.UUID[0:1], a.UUID[1:2]) | |||
| /* | |||
| files, err := repo.GetDatasetDirs(a.UUID, "") | |||
| if err != nil { | |||
| log.Info("No files in attachment dirs.") | |||
| } | |||
| log.Info("files=" + files) | |||
| */ | |||
| } | |||
| } | |||
| return int(cnt), nil | |||
| @@ -1,6 +1,9 @@ | |||
| package models | |||
| import ( | |||
| "fmt" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "xorm.io/xorm" | |||
| ) | |||
| @@ -87,6 +90,27 @@ func InsertFileChunk(fileChunk *FileChunk) (_ *FileChunk, err error) { | |||
| return fileChunk, nil | |||
| } | |||
| func DeleteFileChunkById(uuid string) (*FileChunk, error) { | |||
| return deleteFileChunkById(x, uuid) | |||
| } | |||
| func deleteFileChunkById(e Engine, uuid string) (*FileChunk, error) { | |||
| fileChunk := new(FileChunk) | |||
| if has, err := e.Where("uuid = ?", uuid).Get(fileChunk); err != nil { | |||
| return nil, err | |||
| } else if !has { | |||
| return nil, ErrFileChunkNotExist{"", uuid} | |||
| } | |||
| err := deleteFileChunk(e, fileChunk) | |||
| log.Info("delete the filechunk,id=" + fmt.Sprint(fileChunk.ID)) | |||
| if err != nil { | |||
| return nil, err | |||
| } else { | |||
| return fileChunk, nil | |||
| } | |||
| } | |||
| // UpdateFileChunk updates the given file_chunk in database | |||
| func UpdateFileChunk(fileChunk *FileChunk) error { | |||
| return updateFileChunk(x, fileChunk) | |||
| @@ -0,0 +1,27 @@ | |||
| package labelmsg | |||
| import ( | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| redigo "github.com/gomodule/redigo/redis" | |||
| ) | |||
| var pool *redigo.Pool | |||
| func Init() { | |||
| redisBroker := setting.Broker | |||
| pool_size := 20 | |||
| log.Info("start to connect redis.") | |||
| pool = redigo.NewPool(func() (redigo.Conn, error) { | |||
| c, err := redigo.DialURL(redisBroker) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| return c, nil | |||
| }, pool_size) | |||
| } | |||
| func Get() redigo.Conn { | |||
| return pool.Get() | |||
| } | |||
| @@ -0,0 +1,61 @@ | |||
| package labelmsg | |||
| import ( | |||
| "code.gitea.io/gitea/modules/log" | |||
| ) | |||
| // 方法名 | |||
| const ( | |||
| LabelTaskName = "LabelRedisQueue" | |||
| LabelDatasetDeleteQueue = "LabelDatasetDeleteQueue" | |||
| DecompressOBSTaskName = "LabelDecompressOBSQueue" | |||
| ) | |||
| func SendAddAttachToLabelSys(attach string) error { | |||
| redisclient := Get() | |||
| //记得销毁本次链连接 | |||
| defer redisclient.Close() | |||
| _, err := redisclient.Do("Publish", LabelTaskName, attach) | |||
| if err != nil { | |||
| log.Critical("redis Publish failed.") | |||
| } | |||
| log.Info("LabelRedisQueue(%s) success", attach) | |||
| return nil | |||
| } | |||
| func SendDeleteAttachToLabelSys(attach string) error { | |||
| redisclient := Get() | |||
| //记得销毁本次链连接 | |||
| defer redisclient.Close() | |||
| _, err := redisclient.Do("Publish", LabelDatasetDeleteQueue, attach) | |||
| if err != nil { | |||
| log.Critical("redis Publish failed.") | |||
| } | |||
| log.Info("LabelDatasetDeleteQueue(%s) success", attach) | |||
| return nil | |||
| } | |||
| func SendDecompressAttachToLabelOBS(attach string) error { | |||
| redisclient := Get() | |||
| //记得销毁本次链连接 | |||
| defer redisclient.Close() | |||
| _, err := redisclient.Do("Publish", DecompressOBSTaskName, attach) | |||
| if err != nil { | |||
| log.Critical("redis Publish failed.") | |||
| } | |||
| log.Info("LabelDecompressOBSQueue(%s) success", attach) | |||
| return nil | |||
| } | |||
| @@ -648,6 +648,7 @@ dir = directory | |||
| back = back | |||
| copy_url=copy download url | |||
| directory=check directory of the datasets | |||
| create_label_task=create label task | |||
| visibility = visibility | |||
| visibility_description = Only the owner or the organization members if they have rights, will be able to see it. | |||
| visibility_helper = Make Dataset Private | |||
| @@ -650,6 +650,7 @@ back=返回 | |||
| copy_url=复制下载链接 | |||
| copy_md5=复制文件MD5 | |||
| directory=查看数据集目录结构 | |||
| create_label_task=创建标注任务 | |||
| visibility=可见性 | |||
| visibility_description=只有组织所有人或拥有权利的组织成员才能看到。 | |||
| visibility_helper=将数据集设为私有 | |||
| @@ -0,0 +1,117 @@ | |||
| .yhh-data-table-frame{ | |||
| color:inherit;font-family:inherit;font-size:14px;font-weight:normal; | |||
| border:0;margin:0;padding:0;background-color:#FFFFFF; | |||
| } | |||
| /*table样式*/ | |||
| .yhh-data-table-frame>table.yhh-data-table{ | |||
| width:100%;border-collapse:collapse;border-spacing:0;empty-cells:show; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table td, | |||
| .yhh-data-table-frame>table.yhh-data-table th{ | |||
| vertical-align:middle;text-align:left;border:1px solid #DDDDDD; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a td, | |||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a th{ | |||
| border:0; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a tr{ | |||
| border-bottom:1px solid #DDDDDD; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table td{ | |||
| background-color:#FFFFFF;color:inherit; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table th, | |||
| .yhh-data-table-frame>table.yhh-data-table thead td, | |||
| .yhh-data-table-frame>table.yhh-data-table tfoot td{ | |||
| background-color:#DDDDDD;color:inherit;font-weight:bold; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a th, | |||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a thead td, | |||
| .yhh-data-table-frame>table.yhh-data-table.dataTable-theme-a tfoot td{ | |||
| background-color:#FFFFFF; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table tbody th, | |||
| .yhh-data-table-frame>table.yhh-data-table tbody td{ | |||
| padding:10px 10px; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table thead th, | |||
| .yhh-data-table-frame>table.yhh-data-table thead td, | |||
| .yhh-data-table-frame>table.yhh-data-table tfoot th, | |||
| .yhh-data-table-frame>table.yhh-data-table tfoot td{ | |||
| padding:10px 10px; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table tr.odd td{} | |||
| .yhh-data-table-frame>table.yhh-data-table tr.even td{background-color:#F6F6F6;} | |||
| .yhh-data-table-frame>table.yhh-data-table tr.hover-row td{ | |||
| background-color:#F0F8FF;color:#00BFFF; | |||
| } | |||
| .yhh-data-table-frame>table.yhh-data-table tr.selected-row td{ | |||
| background-color:#E6E6FA; | |||
| } | |||
| /*table上下功能行公共样式*/ | |||
| .yhh-data-table-frame>.data-table-top-box, | |||
| .yhh-data-table-frame>.data-table-bottom-box{ | |||
| position:relative; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box, | |||
| .yhh-data-table-frame>.data-table-bottom-box, | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box, | |||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box, | |||
| .yhh-data-table-frame>.data-table-bottom-box>.paginate-box{ | |||
| height:35px; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box, | |||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box, | |||
| .yhh-data-table-frame>.data-table-bottom-box>.paginate-box{ | |||
| line-height:35px;position:absolute; | |||
| } | |||
| /*改变每页显示数目功能样式*/ | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box{ | |||
| top:0;right:2px;padding-right:50px;z-index:8; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box>.per-length-select{ | |||
| position:absolute;top:1.5px;right:0;width:50px;margin:0; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box, | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list{ | |||
| border:1px solid #DDDDDD;border-radius:0; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box{ | |||
| height:30px;line-height:30px;cursor:pointer;background-color:#F0F8FF; | |||
| position:relative;padding-right:13px;padding-left:8px; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dt.sel-choosen-box.expand{ | |||
| border-radius:0; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list.expand{ | |||
| border-radius:0;border-top:0;margin:0; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box i.sel-icon{ | |||
| height:30px;line-height:30px;position:absolute;top:0;right:2px;color:#AAAAAA; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box dd.sel-list{ | |||
| z-index:10;max-height:200px;height:auto; | |||
| border-radius:0;border-top:0; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option{ | |||
| display:block;border-bottom:1px solid #CCCCCC;line-height:normal; | |||
| background-color:#FFFFFF;padding:6.5px 0;padding-left:8px;cursor:pointer; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option:hover{ | |||
| background-color:#DDE4FE; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option:active{ | |||
| background-color:#DA70D6; | |||
| } | |||
| .yhh-data-table-frame>.data-table-top-box>.per-length-box .sel-option.last-option{ | |||
| border-bottom:0; | |||
| } | |||
| /*显示数据信息功能样式*/ | |||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box{ | |||
| top:0;left:2px; | |||
| } | |||
| .yhh-data-table-frame>.data-table-bottom-box>.info-box .info-num{color:#F5A523;padding:0 5px;} | |||
| /*翻页按钮功能样式*/ | |||
| .yhh-data-table-frame>.data-table-bottom-box>.paginate-box{ | |||
| top:3px;right:0;overflow:hidden; | |||
| } | |||
| @@ -0,0 +1,741 @@ | |||
| var img=new Image(); | |||
| var ip = getIp(); | |||
| var token = getCookie("_csrf"); | |||
| canvas = document.getElementById("myCanvas"); | |||
| context = canvas.getContext("2d"); | |||
| // canvas.width = document.getElementById("myCanvas").offsetWidth; | |||
| // canvas.height = document.getElementById("myCanvas").offsetWidth/1280*720; | |||
| canvas.width = document.getElementById("win_canvas").offsetWidth; | |||
| canvas.height = document.getElementById("win_canvas").offsetHeight; | |||
| var color_dict = {"car":"#0099CC", "person":"#FF99CC","point":"#00cc00","pointselected":"red"}; | |||
| var color_person = {"0":"#13c90c","1":"#fc0707","2":"#FF99CC","3":"#fceb07"}; | |||
| var rects=[]; | |||
| var masks=[]; | |||
| var pointShapes =[]; | |||
| var fileindex =0; | |||
| var lastindex=false; | |||
| var labeltastresult; | |||
| var pageSize = 12; | |||
| var tableData; | |||
| var tablePageData; | |||
| var dataset_id = $('#hide_uuidid').val(); | |||
| var dbdatasetid = dataset_id; | |||
| var textContent; | |||
| var labelInfo; | |||
| page(0,pageSize); | |||
| function getCookie(name) | |||
| { | |||
| var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); | |||
| if(arr=document.cookie.match(reg)) | |||
| return unescape(arr[2]); | |||
| else | |||
| return null; | |||
| } | |||
| function list(current,pageSize){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/gitea-dateset-item-page", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| data:{ | |||
| 'datasetId':dbdatasetid, | |||
| 'startPage':current, | |||
| 'pageSize':pageSize}, | |||
| async:false, | |||
| success:function(json){ | |||
| tablePageData = json; | |||
| tableData = json.data; | |||
| labeltastresult = tableData; | |||
| fileindex=0; | |||
| if(lastindex){ | |||
| fileindex = pageSize - 1; | |||
| } | |||
| }, | |||
| error:function(response) { | |||
| } | |||
| }); | |||
| } | |||
| function getTextContent(uuid,filename){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/getgiteatext", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"text", | |||
| data:{ | |||
| 'uuid':uuid, | |||
| 'filename':filename | |||
| }, | |||
| async:false, | |||
| success:function(json){ | |||
| textContent = json; | |||
| }, | |||
| error:function(response) { | |||
| } | |||
| }); | |||
| } | |||
| /* | |||
| function previewDataSetFile(uuid,filename){ | |||
| console.log('uuid=' + uuid + " filename=" + filename); | |||
| loadimg(uuid,filename); | |||
| } | |||
| function loadimg(uuid,filename){ | |||
| img.src = ip + "/getgiteaimage?uuid=" + uuid + "&filename=" + filename; | |||
| var fname = filename.substring(filename.lastIndexOf('/') + 1); | |||
| $("#filename").text(fname); | |||
| } | |||
| */ | |||
| function loadimg(){ | |||
| var length = labeltastresult[fileindex].pic_image_field.length; | |||
| if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".json" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".xml" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".txt" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".csv" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".md" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".py" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".sh"){ | |||
| //文本 | |||
| canvas.style.display="none"; | |||
| document.getElementById("textcontent").style.display="block"; | |||
| getTextContent(dataset_id,labeltastresult[fileindex].pic_image_field); | |||
| $('#textcontent').height(canvas.height-40) | |||
| $("#textcontent").text(textContent); | |||
| }else{ | |||
| if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".jpeg" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".jpg" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".bmp" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".gif" | |||
| || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".png"){ | |||
| canvas.style.display="block"; | |||
| document.getElementById("textcontent").style.display="none"; | |||
| img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; | |||
| }else{ | |||
| canvas.style.display="none"; | |||
| document.getElementById("textcontent").style.display="block"; | |||
| $('#textcontent').height(canvas.height) | |||
| $("#textcontent").text("暂不支持预览"); | |||
| } | |||
| } | |||
| var fname = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/') + 1); | |||
| $("#filename").text(fname); | |||
| } | |||
| img.onload = function(){ | |||
| canvas.width = document.getElementById("win_canvas").offsetWidth; | |||
| canvas.height = document.getElementById("win_canvas").offsetHeight-40; | |||
| //调整画布大小 | |||
| // if ((img.width/img.height)<(canvas.width/canvas.height)){ | |||
| // canvas.width=canvas.height * img.width / img.height; | |||
| // } | |||
| // else{ | |||
| // canvas.height=canvas.width * img.height / img.width; | |||
| // } | |||
| drawimage(); | |||
| } | |||
| function isEmpty(str){ | |||
| if(typeof str == "undefined" || str == null || str == ""){ | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| function drawimage() { | |||
| parse_labelinfo(labeltastresult[fileindex].label_info); | |||
| // 清除画布,准备绘制 | |||
| context.clearRect(0, 0, canvas.width, canvas.heigth); | |||
| // modal_context.cleararc | |||
| context.drawImage(img,0,0,img.width,img.height,0,0,canvas.width, canvas.height); | |||
| for(var i=0; i<rects.length; i++) { | |||
| var rect = rects[i]; | |||
| rectxywh = new Array(4); | |||
| rectxywh_tmp = rect.getXYWH(); | |||
| rectxywh[0] = rectxywh_tmp[0] / canvas.width * canvas.width; | |||
| rectxywh[1] = rectxywh_tmp[1] / canvas.height * canvas.height; | |||
| rectxywh[2] = rectxywh_tmp[2] / canvas.width * canvas.width; | |||
| rectxywh[3] = rectxywh_tmp[3] / canvas.height * canvas.height; | |||
| // 绘制矩形 | |||
| context.lineWidth = 3; | |||
| if(rect.type == "person"){ | |||
| context.strokeStyle = color_person[ i % 4]; | |||
| }else{ | |||
| context.strokeStyle=color_dict[rect.type]; | |||
| } | |||
| context.strokeRect(rectxywh[0],rectxywh[1],rectxywh[2],rectxywh[3]); | |||
| context.font = "15px Georgia"; | |||
| context.fillStyle= context.strokeStyle; | |||
| context.fillText(rect.type, rectxywh[0],rectxywh[1]-5); | |||
| for(var j=0; j<4; j++){ | |||
| var p_tmp = rect.points[j]; | |||
| var p = new point(0,0); | |||
| p.x = p_tmp.x/ canvas.width * canvas.width;; | |||
| p.y = p_tmp.y / canvas.height * canvas.height; | |||
| context.fillStyle = color_dict["point"]; | |||
| context.fillRect(p.x-2,p.y-2,4,4); | |||
| } | |||
| } | |||
| for (var i=0; i<masks.length; i++){ | |||
| context.strokeStyle="purple" | |||
| var mask =masks[i]; | |||
| context.lineWidth = 2; | |||
| for (var j=1; j<mask.points.length; j++){ | |||
| context.beginPath(); | |||
| context.moveTo(mask.points[j-1].x, mask.points[j-1].y); | |||
| context.lineTo(mask.points[j].x,mask.points[j].y); | |||
| context.stroke(); | |||
| // modal_context.closePath(); | |||
| } | |||
| context.moveTo(mask.points[mask.points.length-1].x,mask.points[mask.points.length-1].y); | |||
| context.lineTo(mask.points[0].x,mask.points[0].y); | |||
| context.stroke(); | |||
| context.closePath(); | |||
| for (var j=0; j<mask.points.length; j++){ | |||
| var p = mask.points[j] | |||
| context.fillStyle = color_dict["point"]; | |||
| context.fillRect(p.x-2,p.y-2,4,4); | |||
| } | |||
| } | |||
| } | |||
| function parse_labelinfo(labelinfo){ | |||
| rects.length = 0; | |||
| masks.length = 0; | |||
| pointShapes.length = 0; | |||
| if(!isEmpty(labelinfo)){ | |||
| var label_arr = JSON.parse(labelinfo); | |||
| for(var i=0;i<label_arr.length;i++){ | |||
| if(!isEmpty(label_arr[i].mask)){ | |||
| cls=label_arr[i].class_name; | |||
| var tmpMask = new maskar(getCanvasLocationX(label_arr[i].mask[0]),getCanvasLocationY(label_arr[i].mask[1]),cls); | |||
| for(var j = 2; j < label_arr[i].mask.length; j+=2){ | |||
| tmpMask.points.push(new point(getCanvasLocationX(label_arr[i].mask[j]),getCanvasLocationY(label_arr[i].mask[j+1]))); | |||
| } | |||
| if(!isEmpty(label_arr[i].id)){ | |||
| tmpMask.id= label_arr[i].id; | |||
| } | |||
| if(!isEmpty(label_arr[i].blurred)){ | |||
| tmpMask.blurred = label_arr[i].blurred; | |||
| } | |||
| if(!isEmpty(label_arr[i].goodIllumination)){ | |||
| tmpMask.goodIllumination = label_arr[i].goodIllumination; | |||
| } | |||
| if(!isEmpty(label_arr[i].frontview)){ | |||
| tmpMask.frontview = label_arr[i].frontview; | |||
| } | |||
| tmpMask.finish = true; | |||
| masks.push(tmpMask); | |||
| }else if(!isEmpty(label_arr[i].box)){ | |||
| x1 = getCanvasLocationX(label_arr[i].box[0]); | |||
| y1 = getCanvasLocationY(label_arr[i].box[1]); | |||
| x2 = getCanvasLocationX(label_arr[i].box[2]); | |||
| y2 = getCanvasLocationY(label_arr[i].box[3]); | |||
| cls=label_arr[i].class_name; | |||
| score = label_arr[i].score; | |||
| rect = new rectar(x1,y1,x2,y2,cls,score); | |||
| if(!isEmpty(label_arr[i].id)){ | |||
| rect.id= label_arr[i].id; | |||
| } | |||
| if(!isEmpty(label_arr[i].blurred)){ | |||
| rect.blurred = label_arr[i].blurred; | |||
| } | |||
| if(!isEmpty(label_arr[i].goodIllumination)){ | |||
| rect.goodIllumination = label_arr[i].goodIllumination; | |||
| } | |||
| if(!isEmpty(label_arr[i].frontview)){ | |||
| rect.frontview = label_arr[i].frontview; | |||
| } | |||
| rects.push(rect); | |||
| }else if(!isEmpty(label_arr[i].keypoints)){ | |||
| cls=label_arr[i].class_name; | |||
| score = label_arr[i].score; | |||
| var pointShapeObj = new pointShape(getCanvasLocationX(label_arr[i].keypoints[0]),getCanvasLocationY(label_arr[i].keypoints[1]),cls,score); | |||
| pointShapes.push(pointShapeObj); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| function point(x,y){ | |||
| this.x = x; | |||
| this.y = y; | |||
| this.isSelected = false; | |||
| }; | |||
| function pointShape(x,y,type,score=1.0){ | |||
| this.x = x; | |||
| this.y = y; | |||
| this.isSelected = false; | |||
| this.type = type; | |||
| this.score = score; | |||
| this.id =""; //标识 | |||
| this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的 | |||
| this.goodIllumination = false; //照明 | |||
| this.frontview = false;//正面图 | |||
| } | |||
| function rectar(x1,y1,x2,y2, type, score=1.0){ | |||
| // this.x = x; | |||
| // this.y = y; | |||
| // this.width = width; | |||
| // this.height = height; | |||
| this.type = type; | |||
| this.score = score; | |||
| //0--1, | |||
| //| | | |||
| //2--3 | |||
| this.points = [new point(x1,y1), new point(x1, y2),new point(x2, y1),new point(x2, y2)]; | |||
| this.getXYWH = function(){ | |||
| var x_min=Math.min(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||
| var x_max=Math.max(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||
| var y_min=Math.min(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||
| var y_max=Math.max(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||
| return [x_min,y_min,x_max-x_min,y_max-y_min]; | |||
| } | |||
| this.getX1Y1X2Y2 = function(){ | |||
| var x_min=Math.min(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||
| var x_max=Math.max(this.points[0].x,this.points[1].x,this.points[2].x,this.points[3].x); | |||
| var y_min=Math.min(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||
| var y_max=Math.max(this.points[0].y,this.points[1].y,this.points[2].y,this.points[3].y); | |||
| return [x_min,y_min,x_max,y_max]; | |||
| } | |||
| this.getdiapid = function(pid){//获取对角点 | |||
| var twooverlapped,fouroverlapped; | |||
| for (var i=0;i<4;i++){ | |||
| if ((this.points[pid].x!=this.points[i].x)&&(this.points[pid].y!=this.points[i].y)){ | |||
| return i; | |||
| } | |||
| if ((this.points[pid].x!=this.points[i].x)||(this.points[pid].y!=this.points[i].y)){ | |||
| twooverlapped=i; | |||
| } | |||
| if (i!=pid) fouroverlapped=i; | |||
| } | |||
| if (twooverlapped) | |||
| return twooverlapped; | |||
| return fouroverlapped; | |||
| } | |||
| this.mouseonpoint = false; | |||
| this.mouseonrect = false; | |||
| this.isSelected = false; | |||
| this.id =""; //标识 | |||
| this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的 | |||
| this.goodIllumination = true; //照明 | |||
| this.frontview = true;//正面图 | |||
| }; | |||
| function maskar(x0,y0,type){ | |||
| this.type = type; | |||
| this.points = [new point(x0,y0)]; | |||
| this.finish = false; | |||
| this.mouseonpoint = false; | |||
| this.mouseonmask = false; | |||
| this.isSelected = false; | |||
| this.getX1Y1 = function(){return [this.points[0].x,this.points[0].y]} | |||
| this.getBound = function(){ | |||
| mlen = this.points.length; | |||
| var minX = 999999999, minY = 999999999, maxX = -1, maxY = -1; | |||
| for (var i = 0; i < mlen; i ++){ | |||
| if(minX > this.points[i].x){ | |||
| minX = this.points[i].x; | |||
| } | |||
| if(maxX < this.points[i].x){ | |||
| maxX = this.points[i].x; | |||
| } | |||
| if(minY > this.points[i].y){ | |||
| minY = this.points[i].y; | |||
| } | |||
| if(maxY < this.points[i].y){ | |||
| maxY = this.points[i].y; | |||
| } | |||
| } | |||
| return [minX, minY, maxX, maxY]; | |||
| } | |||
| this.id =""; //标识 | |||
| this.blurred=false;//模糊不清的; 记不清的; 难以区分的; 模棱两可的 | |||
| this.goodIllumination = true; //照明 | |||
| this.frontview = true;//正面图 | |||
| } | |||
| function getCanvasLocationX(num){ | |||
| return Math.round(num * canvas.width/parseInt(img.width)); | |||
| } | |||
| function getCanvasLocationY(num){ | |||
| return Math.round(num * canvas.height/parseInt(img.height)); | |||
| } | |||
| function page(current,pageSize){ | |||
| list(current,pageSize); | |||
| getLabelInfo(dataset_id); | |||
| showlabelflist(); | |||
| showfilelist(); | |||
| breadFiles(); | |||
| loadimg(); | |||
| setPage(tablePageData,pageSize); | |||
| } | |||
| function nextPage(){ | |||
| var current = $('#displayPage1').text(); | |||
| page(current,pageSize); | |||
| } | |||
| function prePage(){ | |||
| var current =$('#displayPage1').text(); | |||
| if(current > 1){ | |||
| page(current - 2,pageSize); | |||
| } | |||
| } | |||
| function goPage(){ | |||
| var goNum = $('#goNum').val(); | |||
| var pageTotal = $("#totalNum").text(); | |||
| var pageNum = parseInt(pageTotal/pageSize); | |||
| if(pageTotal%pageSize!=0){ | |||
| pageNum += 1; | |||
| }else { | |||
| pageNum = pageNum; | |||
| } | |||
| if (goNum<=0){ | |||
| alert("请输入大于0的数值"); | |||
| } | |||
| else if(goNum<=pageNum){ | |||
| page(goNum - 1,pageSize); | |||
| } | |||
| else{ | |||
| alert("不能超出总页码!"); | |||
| } | |||
| } | |||
| $("#goNum").keydown(function (e) { | |||
| if (e.keyCode == 13) { | |||
| goPage(); | |||
| } | |||
| }); | |||
| function setPage(pageData,pageSize){ | |||
| if (isEmpty(pageData)){ | |||
| return; | |||
| } | |||
| var startIndex = pageData.current * pageSize; | |||
| if(pageData.total > 0){ | |||
| startIndex = startIndex + 1; | |||
| } | |||
| if(startIndex < 10){ | |||
| $('#startIndex').text(" " + (startIndex)); | |||
| }else{ | |||
| $('#startIndex').text(startIndex); | |||
| } | |||
| var endIndex = pageData.current * pageSize + pageData.data.length; | |||
| if(endIndex < 10){ | |||
| $('#endIndex').text(" " + (endIndex)); | |||
| }else{ | |||
| $('#endIndex').text(endIndex); | |||
| } | |||
| $('#totalNum').text(pageData.total); | |||
| $('#displayPage1').text(pageData.current + 1); | |||
| if(pageData.current == 0){ | |||
| $('#prePage').removeAttr("href"); | |||
| $('#prePage').attr('style','color:#f5f5f6;'); | |||
| } | |||
| else{ | |||
| $('#prePage').attr("href","javascript:prePage()"); | |||
| $('#prePage').attr('style','color:#000;'); | |||
| } | |||
| if((pageData.current + 1) * pageSize >= pageData.total){ | |||
| $('#nextPage').removeAttr("href"); | |||
| $('#nextPage').attr('style','color:#f5f5f6;') | |||
| } | |||
| else{ | |||
| $('#nextPage').attr("href","javascript:nextPage()"); | |||
| $('#nextPage').attr('style','color:#000;'); | |||
| } | |||
| var pageTotal = pageData.total; | |||
| var pageNum = parseInt(pageTotal/pageSize); | |||
| if(pageTotal%pageSize!=0){ | |||
| pageNum += 1; | |||
| }else { | |||
| pageNum = pageNum; | |||
| } | |||
| $("#totalPageNum").text(pageNum); | |||
| } | |||
| function clickfilelist(index){ | |||
| fileindex=index; | |||
| loadimg(); | |||
| //drawimage(); | |||
| breadFiles() | |||
| showfilelist(); | |||
| } | |||
| function clickNext(){ | |||
| if(fileindex<tableData.length-1) { | |||
| next(); | |||
| }else{ | |||
| if((tablePageData.current + 1) * pageSize >= tablePageData.total){ | |||
| return; | |||
| } | |||
| nextPage(); | |||
| } | |||
| } | |||
| function next(){ | |||
| if(fileindex<tableData.length-1) {fileindex=fileindex+1;} | |||
| loadimg(); | |||
| //drawimage(); | |||
| breadFiles() | |||
| showfilelist(); | |||
| } | |||
| function clickLast(){ | |||
| if(fileindex == 0){ | |||
| prePage(); | |||
| }else{ | |||
| last(); | |||
| } | |||
| } | |||
| function last(){ | |||
| if(fileindex>0) {fileindex=fileindex-1;} | |||
| loadimg(); | |||
| //drawimage(); | |||
| breadFiles(); | |||
| showfilelist(); | |||
| } | |||
| // function showfilelist(){ | |||
| // var htmlstr=""; | |||
| // for (var i=0;i<labeltastresult.length;i++){ | |||
| // var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | |||
| // var lablebg=" style=\"cursor:pointer\""; | |||
| // if (i==fileindex){lablebg=" style=\"background:#eee;color:#5a5a5a;cursor:pointer;\"";} | |||
| // htmlstr = htmlstr+"<tr onclick=\"clickfilelist("+i+");\""+ lablebg+"><td>"+ fname+ "</td></tr>"; | |||
| // }; | |||
| // document.getElementById("filelist").innerHTML=htmlstr; | |||
| // } | |||
| function showfilelist(){ | |||
| var filename_title = $('a.section:first').text() | |||
| filename_title = filename_title.split('.')[0] | |||
| var htmlstr = ''; | |||
| // htmlstr += '<div class="ui list">'; | |||
| htmlstr += '<div class="item" style="padding:1.2em;border-bottom:0">' | |||
| htmlstr += '<i class="caret down icon"></i>' | |||
| htmlstr += '<div class="content" style="background:#fff">' | |||
| htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 600;">'+filename_title+'</div>' | |||
| htmlstr += '<div class="list" style="padding:1.2em">' | |||
| for (var i=0;i<labeltastresult.length;i++){ | |||
| var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); | |||
| console.log(labeltastresult[i]) | |||
| if(labeltastresult[i].pic_image_field.length > 70){ | |||
| var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); | |||
| console.log(tmpIndex) | |||
| if(tmpIndex != -1){ | |||
| fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); | |||
| } | |||
| } | |||
| htmlstr += '<div class="item" onclick=\"clickfilelist('+i+');\" style="border-bottom:0;padding-bottom:0.9em;cursor:pointer">' | |||
| htmlstr += '<div class="content" style="background:#fff;padding:0;">' | |||
| if(i==fileindex){ | |||
| htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 100;color:#0366d6">'+fname+'</div>' | |||
| } | |||
| else{ | |||
| htmlstr += '<div class="header" style="color: rgba(0,0,0,.8);font-size: 12px;font-weight: 100;">'+fname+'</div>' | |||
| } | |||
| htmlstr += '</div>' | |||
| htmlstr += '</div>' | |||
| }; | |||
| htmlstr += '</div>' | |||
| htmlstr += '</div>' | |||
| htmlstr += '</div>' | |||
| document.getElementById("filelist").innerHTML=htmlstr; | |||
| } | |||
| function breadFiles(){ | |||
| // for (var i=0;i<labeltastresult.length;i++){ | |||
| // var fname_full_path="" | |||
| // if(labeltastresult[i].pic_image_field.length > 70){ | |||
| // var tmp_index = labeltastresult[i].pic_image_field.indexOf("/",70); | |||
| // if(tmp_index != -1){ | |||
| // fname_full_path = labeltastresult[i].pic_image_field.substring(tmp_index + 1); | |||
| // } | |||
| // var fname_path = fname_full_path.split('/') | |||
| // html_breadFile += '<div class="section">'+fname_full_path+'.zip'+'</div>' | |||
| // for(var i=1;i<fname_path.length;i++){ | |||
| // html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||
| // html_breadFile += '<div class="section">'+fname_path[i]+'</div>' | |||
| // } | |||
| // } | |||
| // else{ | |||
| // } | |||
| // } | |||
| var fname_full_path="" | |||
| var filename_title = $('a.section:first').text() | |||
| filename_title = filename_title.split('.')[0] | |||
| var tmp_index = tableData[fileindex].pic_image_field.indexOf("/",70); | |||
| if(tmp_index != -1){ | |||
| fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); | |||
| } | |||
| var fname_path = fname_full_path.split('/') | |||
| console.log(fname_path) | |||
| // var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) | |||
| var html_breadFile = '' | |||
| // var source_name = filename_title+'.zip' | |||
| // html_breadFile += '<div class="section">'+source_name+'</div>' | |||
| // html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||
| html_breadFile += '<div class="section">'+filename_title+'</div>' | |||
| html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||
| for (var i=0;i<fname_path.length;i++){ | |||
| html_breadFile += '<div class="section">'+fname_path[i]+'</div>' | |||
| html_breadFile += '<div class="divider" style="opacity:0.8"> / </div>' | |||
| } | |||
| document.getElementById("breadFile").innerHTML=html_breadFile | |||
| } | |||
| function showlabelflist(){ | |||
| if(!isEmpty(labelInfo)){ | |||
| var resLabelInfo = JSON.parse(labelInfo) | |||
| var textInfo = resLabelInfo["type"] | |||
| var html_labelFile = '' | |||
| for (var i=0;i<textInfo.length;i++){ | |||
| html_labelFile += `<span style="display:block;width:70%;margin:0.6em 15%;padding-left:1.5em;padding-top:0.4em;padding-bottom:0.4em;font-size:12px;" class="labelInfo">${textInfo[i]}</span>` | |||
| } | |||
| document.getElementById("labellist").innerHTML=html_labelFile | |||
| setColor() | |||
| } | |||
| else{ | |||
| return | |||
| } | |||
| } | |||
| function setColor(){ | |||
| var el_span = document.querySelectorAll("span.labelInfo") | |||
| for (var i=0;i<el_span.length;i++){ | |||
| var colorinfo = ~~(Math.random()*(1<<24)) | |||
| var colorinfo1 = '#'+(colorinfo).toString(16) | |||
| var colorinfo2 = '#'+(colorinfo+100).toString(16) | |||
| el_span[i].style.backgroundColor = colorinfo1 | |||
| el_span[i].style.borderLeft = '6px solid'+ colorinfo2 | |||
| } | |||
| } | |||
| function getLabelInfo(uuid){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/getlabelinfo", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"text", | |||
| data:{ | |||
| 'uuid':uuid | |||
| }, | |||
| async:false, | |||
| success:function(json){ | |||
| labelInfo = json; | |||
| }, | |||
| error:function(response) { | |||
| } | |||
| }); | |||
| } | |||
| @@ -0,0 +1,273 @@ | |||
| function getIp(){ | |||
| //return "http://192.168.62.129:8000"; | |||
| //return "http://192.168.62.129"; | |||
| return "http://192.168.62.129:8010"; | |||
| //return "http://111.231.109.64:8000"; | |||
| } | |||
| function isEmpty(str){ | |||
| if(typeof str == "undefined" || str == null || str == ""){ | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| function redirect(response){ | |||
| if("REDIRECT" == response.getResponseHeader("REDIRECT")){ //若HEADER中含有REDIRECT说明后端想重定向, | |||
| var win = window; | |||
| while(win != win.top){ | |||
| win = win.top; | |||
| } | |||
| win.location.href = getIp() +"/login.html";//使用win.location.href去实现重定向到登录页面 | |||
| } | |||
| } | |||
| function setCookie(name,value) | |||
| { | |||
| var Days = 7; | |||
| var exp = new Date(); | |||
| exp.setTime(exp.getTime() + Days*24*60*60*1000); | |||
| document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); | |||
| } | |||
| //读取cookies | |||
| function getCookie(name) | |||
| { | |||
| var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); | |||
| if(arr=document.cookie.match(reg)) | |||
| return unescape(arr[2]); | |||
| else | |||
| return null; | |||
| } | |||
| function delCookie(name) | |||
| { | |||
| var exp = new Date(); | |||
| exp.setTime(exp.getTime() - 1); | |||
| var cval=getCookie(name); | |||
| if(cval!=null) | |||
| document.cookie= name + "="+cval+";expires="+exp.toGMTString(); | |||
| } | |||
| //检查是否都符合 注册 要求 | |||
| function check_reg() | |||
| { | |||
| if(check_email(document.getElementById('email')) && check_web(document.getElementById('web'))) | |||
| { | |||
| return true; | |||
| }else{ | |||
| return false; | |||
| } | |||
| } | |||
| //检查密码长度不能少于6 | |||
| function check_len(thisObj){ | |||
| if(thisObj.value.length==0) | |||
| { | |||
| document.getElementById('show_pass').innerHTML="密码不能为空"; | |||
| return false; | |||
| }else{ | |||
| if (thisObj.value.length<6) | |||
| { | |||
| document.getElementById('show_pass').innerHTML="密码长度不少于6"; | |||
| return false; | |||
| } | |||
| document.getElementById('show_pass').innerHTML=""; | |||
| return true; | |||
| } | |||
| } | |||
| //检查俩次密码输入是否一致 | |||
| function check_pass(thisObj){ | |||
| var psw=document.getElementById('pass'); | |||
| if(psw.value.length==0) | |||
| { | |||
| document.getElementById('show_pass').innerHTML="密码不能为空"; | |||
| return false; | |||
| }else{ | |||
| document.getElementById('show_pass').innerHTML=""; | |||
| if (thisObj.value!=psw.value) | |||
| { | |||
| document.getElementById('show_repass').innerHTML="两次密码输入不正确"; | |||
| return false; | |||
| } | |||
| document.getElementById('show_repass').innerHTML=""; | |||
| return true; | |||
| } | |||
| } | |||
| //检查email是否正确 | |||
| function check_email(thisObj){ | |||
| var reg=/^([a-zA-Z\d][a-zA-Z0-9_]+@[a-zA-Z\d]+(\.[a-zA-Z\d]+)+)$/gi; | |||
| var rzt=thisObj.value.match(reg); | |||
| if(thisObj.value.length==0){ | |||
| document.getElementById('show_e').innerHTML="Email不能为空"; | |||
| return false; | |||
| }else{ | |||
| if (rzt==null) | |||
| { | |||
| document.getElementById('show_e').innerHTML="Email地址不正确"; | |||
| return false; | |||
| } | |||
| document.getElementById('show_e').innerHTML=""; | |||
| return true; | |||
| } | |||
| } | |||
| //检查web是否正确 | |||
| function check_web(thisObj){ | |||
| //var reg=/^\w+([\.\-]\w)*$/; | |||
| //var rzt=thisObj.value.match(reg); | |||
| if(thisObj.value.length==0){ | |||
| document.getElementById('show_web').innerHTML="主页不能为空"; | |||
| return false; | |||
| }else{ | |||
| /*if (rzt==null) | |||
| { | |||
| document.getElementById('show_web').innerHTML="主页地址不正确"; | |||
| return false; | |||
| } */ | |||
| var strRegex = "^((https|http|ftp|rtsp|mms)?://)" | |||
| + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@ | |||
| + "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184 | |||
| + "|" // 允许IP和DOMAIN(域名) | |||
| + "([0-9a-z_!~*'()-]+\.)*" // 域名- www. | |||
| + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名 | |||
| + "[a-z]{2,6})" // first level domain- .com or .museum | |||
| + "(:[0-9]{1,4})?" // 端口- :80 | |||
| + "((/?)|" // a slash isn't required if there is no file name | |||
| + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$"; | |||
| var re=new RegExp(strRegex); | |||
| if(!re.test(thisObj.value)) | |||
| { | |||
| document.getElementById('show_web').innerHTML="主页地址不正确"; | |||
| return false; | |||
| } | |||
| document.getElementById('show_web').innerHTML=""; | |||
| return true; | |||
| } | |||
| } | |||
| function isRightLatitude(lat){ | |||
| var latreg = /^(\-|\+)?([0-8]?\d{1}\.\d{0,6}|90\.0{0,6}|[0-8]?\d{1}|90)$/; | |||
| if(!latreg.test(lat)){ | |||
| return false; | |||
| //console.log("纬度整数部分为0-90,小数部分为0到6位!"); | |||
| } | |||
| return true; | |||
| } | |||
| function isRightLongitude(longitude){ | |||
| var longrg = /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,6})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/; | |||
| if(!longrg.test(longitude)){ | |||
| return false; | |||
| //console.log("经度整数部分为0-180,小数部分为0到6位!"); | |||
| } | |||
| return true; | |||
| } | |||
| function isRightDateTime_dot(time){ | |||
| //2020-05-20 14:20:20 | |||
| if(time.length != 19){ | |||
| return false; | |||
| } | |||
| return strDateTime(time); | |||
| } | |||
| function strDateTime(str) | |||
| { | |||
| var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/; | |||
| var r = str.match(reg); | |||
| if(r==null){ | |||
| return false; | |||
| } | |||
| var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]); | |||
| return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]); | |||
| } | |||
| function isRightDateTime_yyyyMMddHHmmss(time){ | |||
| //20200520142020 | |||
| if(time.length != 14){ | |||
| return false; | |||
| } | |||
| var year = time.substring(0,4); | |||
| var month = time.substring(4,6); | |||
| var day = time.substring(6,8); | |||
| var hour = time.substring(8,10); | |||
| var minute = time.substring(10,12); | |||
| var second = time.substring(12,14); | |||
| console.log("year=" + year + " month=" + month + "day=" + day); | |||
| var d= new Date(year,month-1,day,hour,minute,second); | |||
| return (d.getFullYear()==year && (d.getMonth()+1)== month&& d.getDate()== day && d.getHours()==hour && d.getMinutes()==minute && d.getSeconds()==second); | |||
| } | |||
| function isDateString(strDate){ | |||
| var strSeparator = "-"; //日期分隔符 | |||
| var strDateArray; | |||
| var intYear; | |||
| var intMonth; | |||
| var intDay; | |||
| var boolLeapYear; | |||
| var ErrorMsg = ""; //出错信息 | |||
| strDateArray = strDate.split(strSeparator); | |||
| //没有判断长度,其实2008-8-8也是合理的//strDate.length != 10 || | |||
| if(strDateArray.length != 3) { | |||
| ErrorMsg += "日期格式必须为: yyyy-MM-dd"; | |||
| return ErrorMsg; | |||
| } | |||
| intYear = parseInt(strDateArray[0],10); | |||
| intMonth = parseInt(strDateArray[1],10); | |||
| intDay = parseInt(strDateArray[2],10); | |||
| if(isNaN(intYear)||isNaN(intMonth)||isNaN(intDay)) { | |||
| ErrorMsg += "日期格式错误: 年月日必须为纯数字"; | |||
| return ErrorMsg; | |||
| } | |||
| if(intMonth>12 || intMonth<1) { | |||
| ErrorMsg += "日期格式错误: 月份必须介于1和12之间"; | |||
| return ErrorMsg; | |||
| } | |||
| if((intMonth==1||intMonth==3||intMonth==5||intMonth==7 | |||
| ||intMonth==8||intMonth==10||intMonth==12) | |||
| &&(intDay>31||intDay<1)) { | |||
| ErrorMsg += "日期格式错误: 大月的天数必须介于1到31之间"; | |||
| return ErrorMsg; | |||
| } | |||
| if((intMonth==4||intMonth==6||intMonth==9||intMonth==11) | |||
| &&(intDay>30||intDay<1)) { | |||
| ErrorMsg += "日期格式错误: 小月的天数必须介于1到31之间"; | |||
| return ErrorMsg; | |||
| } | |||
| if(intMonth==2){ | |||
| if(intDay < 1) { | |||
| ErrorMsg += "日期格式错误: 日期必须大于或等于1"; | |||
| return ErrorMsg; | |||
| } | |||
| boolLeapYear = false; | |||
| if((intYear%100) == 0){ | |||
| if((intYear%400) == 0) | |||
| boolLeapYear = true; | |||
| } | |||
| else{ | |||
| if((intYear % 4) == 0) | |||
| boolLeapYear = true; | |||
| } | |||
| if(boolLeapYear){ | |||
| if(intDay > 29) { | |||
| ErrorMsg += "日期格式错误: 闰年的2月份天数不能超过29"; | |||
| return ErrorMsg; | |||
| } | |||
| } else { | |||
| if(intDay > 28) { | |||
| ErrorMsg += "日期格式错误: 非闰年的2月份天数不能超过28"; | |||
| return ErrorMsg; | |||
| } | |||
| } | |||
| } | |||
| return ErrorMsg; | |||
| } | |||
| @@ -0,0 +1,739 @@ | |||
| /*! | |||
| * Author: Abdullah A Almsaeed | |||
| * Date: 4 Jan 2014 | |||
| * Description: | |||
| * This file should be included in all pages | |||
| !**/ | |||
| /* | |||
| * Global variables. If you change any of these vars, don't forget | |||
| * to change the values in the less files! | |||
| */ | |||
| var left_side_width = 220; //Sidebar width in pixels | |||
| $(function() { | |||
| "use strict"; | |||
| //Enable sidebar toggle | |||
| $("[data-toggle='offcanvas']").click(function(e) { | |||
| e.preventDefault(); | |||
| //If window is small enough, enable sidebar push menu | |||
| if ($(window).width() <= 992) { | |||
| $('.row-offcanvas').toggleClass('active'); | |||
| $('.left-side').removeClass("collapse-left"); | |||
| $(".right-side").removeClass("strech"); | |||
| $('.row-offcanvas').toggleClass("relative"); | |||
| } else { | |||
| //Else, enable content streching | |||
| $('.left-side').toggleClass("collapse-left"); | |||
| $(".right-side").toggleClass("strech"); | |||
| } | |||
| }); | |||
| //Add hover support for touch devices | |||
| $('.btn').bind('touchstart', function() { | |||
| $(this).addClass('hover'); | |||
| }).bind('touchend', function() { | |||
| $(this).removeClass('hover'); | |||
| }); | |||
| //Activate tooltips | |||
| $("[data-toggle='tooltip']").tooltip(); | |||
| /* | |||
| * Add collapse and remove events to boxes | |||
| */ | |||
| $("[data-widget='collapse']").click(function() { | |||
| //Find the box parent | |||
| var box = $(this).parents(".box").first(); | |||
| //Find the body and the footer | |||
| var bf = box.find(".box-body, .box-footer"); | |||
| if (!box.hasClass("collapsed-box")) { | |||
| box.addClass("collapsed-box"); | |||
| //Convert minus into plus | |||
| $(this).children(".fa-minus").removeClass("fa-minus").addClass("fa-plus"); | |||
| bf.slideUp(); | |||
| } else { | |||
| box.removeClass("collapsed-box"); | |||
| //Convert plus into minus | |||
| $(this).children(".fa-plus").removeClass("fa-plus").addClass("fa-minus"); | |||
| bf.slideDown(); | |||
| } | |||
| }); | |||
| /* | |||
| * ADD SLIMSCROLL TO THE TOP NAV DROPDOWNS | |||
| * --------------------------------------- | |||
| */ | |||
| $(".navbar .menu").slimscroll({ | |||
| height: "200px", | |||
| alwaysVisible: false, | |||
| size: "3px" | |||
| }).css("width", "100%"); | |||
| /* | |||
| * INITIALIZE BUTTON TOGGLE | |||
| * ------------------------ | |||
| */ | |||
| $('.btn-group[data-toggle="btn-toggle"]').each(function() { | |||
| var group = $(this); | |||
| $(this).find(".btn").click(function(e) { | |||
| group.find(".btn.active").removeClass("active"); | |||
| $(this).addClass("active"); | |||
| e.preventDefault(); | |||
| }); | |||
| }); | |||
| $("[data-widget='remove']").click(function() { | |||
| //Find the box parent | |||
| var box = $(this).parents(".box").first(); | |||
| box.slideUp(); | |||
| }); | |||
| /* Sidebar tree view */ | |||
| $(".sidebar .treeview").tree(); | |||
| /* | |||
| * Make sure that the sidebar is streched full height | |||
| * --------------------------------------------- | |||
| * We are gonna assign a min-height value every time the | |||
| * wrapper gets resized and upon page load. We will use | |||
| * Ben Alman's method for detecting the resize event. | |||
| * | |||
| **/ | |||
| function _fix() { | |||
| //Get window height and the wrapper height | |||
| var height = $(window).height() - $("body > .header").height() - ($("body > .footer").outerHeight() || 0); | |||
| $(".wrapper").css("min-height", height + "px"); | |||
| var content = $(".wrapper").height(); | |||
| //If the wrapper height is greater than the window | |||
| if (content > height){ | |||
| //then set sidebar height to the wrapper | |||
| $(".left-side, html, body").css("min-height", content + "px"); | |||
| $(".pull-height, html, body").css("min-height", content + "px"); | |||
| } | |||
| else { | |||
| //Otherwise, set the sidebar to the height of the window | |||
| $(".left-side, html, body").css("min-height", height + "px"); | |||
| $(".pull-height, html, body").css("min-height", content + "px"); | |||
| } | |||
| } | |||
| //Fire upon load | |||
| _fix(); | |||
| //Fire when wrapper is resized | |||
| $(".wrapper").resize(function() { | |||
| _fix(); | |||
| fix_sidebar(); | |||
| }); | |||
| //Fix the fixed layout sidebar scroll bug | |||
| fix_sidebar(); | |||
| /* | |||
| * We are gonna initialize all checkbox and radio inputs to | |||
| * iCheck plugin in. | |||
| * You can find the documentation at http://fronteed.com/iCheck/ | |||
| */ | |||
| // $("input[type='checkbox']:not(.simple), input[type='radio']:not(.simple)").iCheck({ | |||
| // checkboxClass: 'icheckbox_minimal', | |||
| // radioClass: 'iradio_minimal' | |||
| // }); | |||
| }); | |||
| function fix_sidebar() { | |||
| //Make sure the body tag has the .fixed class | |||
| if (!$("body").hasClass("fixed")) { | |||
| return; | |||
| } | |||
| //Add slimscroll | |||
| $(".sidebar").slimscroll({ | |||
| height: ($(window).height() - $(".header").height()) + "px", | |||
| color: "rgba(0,0,0,0.2)" | |||
| }); | |||
| } | |||
| /* | |||
| * BOX REFRESH BUTTON | |||
| * ------------------ | |||
| * This is a custom plugin to use with the compenet BOX. It allows you to add | |||
| * a refresh button to the box. It converts the box's state to a loading state. | |||
| * | |||
| * USAGE: | |||
| * $("#box-widget").boxRefresh( options ); | |||
| * */ | |||
| (function($) { | |||
| "use strict"; | |||
| $.fn.boxRefresh = function(options) { | |||
| // Render options | |||
| var settings = $.extend({ | |||
| //Refressh button selector | |||
| trigger: ".refresh-btn", | |||
| //File source to be loaded (e.g: ajax/src.php) | |||
| source: "", | |||
| //Callbacks | |||
| onLoadStart: function(box) { | |||
| }, //Right after the button has been clicked | |||
| onLoadDone: function(box) { | |||
| } //When the source has been loaded | |||
| }, options); | |||
| //The overlay | |||
| var overlay = $('<div class="overlay"></div><div class="loading-img"></div>'); | |||
| return this.each(function() { | |||
| //if a source is specified | |||
| if (settings.source === "") { | |||
| if (console) { | |||
| console.log("Please specify a source first - boxRefresh()"); | |||
| } | |||
| return; | |||
| } | |||
| //the box | |||
| var box = $(this); | |||
| //the button | |||
| var rBtn = box.find(settings.trigger).first(); | |||
| //On trigger click | |||
| rBtn.click(function(e) { | |||
| e.preventDefault(); | |||
| //Add loading overlay | |||
| start(box); | |||
| //Perform ajax call | |||
| box.find(".box-body").load(settings.source, function() { | |||
| done(box); | |||
| }); | |||
| }); | |||
| }); | |||
| function start(box) { | |||
| //Add overlay and loading img | |||
| box.append(overlay); | |||
| settings.onLoadStart.call(box); | |||
| } | |||
| function done(box) { | |||
| //Remove overlay and loading img | |||
| box.find(overlay).remove(); | |||
| settings.onLoadDone.call(box); | |||
| } | |||
| }; | |||
| })(jQuery); | |||
| /* | |||
| * SIDEBAR MENU | |||
| * ------------ | |||
| * This is a custom plugin for the sidebar menu. It provides a tree view. | |||
| * | |||
| * Usage: | |||
| * $(".sidebar).tree(); | |||
| * | |||
| * Note: This plugin does not accept any options. Instead, it only requires a class | |||
| * added to the element that contains a sub-menu. | |||
| * | |||
| * When used with the sidebar, for example, it would look something like this: | |||
| * <ul class='sidebar-menu'> | |||
| * <li class="treeview active"> | |||
| * <a href="#>Menu</a> | |||
| * <ul class='treeview-menu'> | |||
| * <li class='active'><a href=#>Level 1</a></li> | |||
| * </ul> | |||
| * </li> | |||
| * </ul> | |||
| * | |||
| * Add .active class to <li> elements if you want the menu to be open automatically | |||
| * on page load. See above for an example. | |||
| */ | |||
| (function($) { | |||
| "use strict"; | |||
| $.fn.tree = function() { | |||
| return this.each(function() { | |||
| var btn = $(this).children("a").first(); | |||
| var menu = $(this).children(".treeview-menu").first(); | |||
| var isActive = $(this).hasClass('active'); | |||
| //initialize already active menus | |||
| if (isActive) { | |||
| menu.show(); | |||
| btn.children(".fa-angle-left").first().removeClass("fa-angle-left").addClass("fa-angle-down"); | |||
| } | |||
| //Slide open or close the menu on link click | |||
| btn.click(function(e) { | |||
| e.preventDefault(); | |||
| if (isActive) { | |||
| //Slide up to close menu | |||
| menu.slideUp(); | |||
| isActive = false; | |||
| btn.children(".fa-angle-down").first().removeClass("fa-angle-down").addClass("fa-angle-left"); | |||
| btn.parent("li").removeClass("active"); | |||
| } else { | |||
| //Slide down to open menu | |||
| menu.slideDown(); | |||
| isActive = true; | |||
| btn.children(".fa-angle-left").first().removeClass("fa-angle-left").addClass("fa-angle-down"); | |||
| btn.parent("li").addClass("active"); | |||
| } | |||
| }); | |||
| /* Add margins to submenu elements to give it a tree look */ | |||
| menu.find("li > a").each(function() { | |||
| var pad = parseInt($(this).css("margin-left")) + 10; | |||
| $(this).css({"margin-left": pad + "px"}); | |||
| }); | |||
| }); | |||
| }; | |||
| }(jQuery)); | |||
| /* | |||
| * TODO LIST CUSTOM PLUGIN | |||
| * ----------------------- | |||
| * This plugin depends on iCheck plugin for checkbox and radio inputs | |||
| */ | |||
| (function($) { | |||
| "use strict"; | |||
| $.fn.todolist = function(options) { | |||
| // Render options | |||
| var settings = $.extend({ | |||
| //When the user checks the input | |||
| onCheck: function(ele) { | |||
| }, | |||
| //When the user unchecks the input | |||
| onUncheck: function(ele) { | |||
| } | |||
| }, options); | |||
| return this.each(function() { | |||
| $('input', this).on('ifChecked', function(event) { | |||
| var ele = $(this).parents("li").first(); | |||
| ele.toggleClass("done"); | |||
| settings.onCheck.call(ele); | |||
| }); | |||
| $('input', this).on('ifUnchecked', function(event) { | |||
| var ele = $(this).parents("li").first(); | |||
| ele.toggleClass("done"); | |||
| settings.onUncheck.call(ele); | |||
| }); | |||
| }); | |||
| }; | |||
| }(jQuery)); | |||
| /* CENTER ELEMENTS */ | |||
| (function($) { | |||
| "use strict"; | |||
| jQuery.fn.center = function(parent) { | |||
| if (parent) { | |||
| parent = this.parent(); | |||
| } else { | |||
| parent = window; | |||
| } | |||
| this.css({ | |||
| "position": "absolute", | |||
| "top": ((($(parent).height() - this.outerHeight()) / 2) + $(parent).scrollTop() + "px"), | |||
| "left": ((($(parent).width() - this.outerWidth()) / 2) + $(parent).scrollLeft() + "px") | |||
| }); | |||
| return this; | |||
| } | |||
| }(jQuery)); | |||
| /* | |||
| * jQuery resize event - v1.1 - 3/14/2010 | |||
| * http://benalman.com/projects/jquery-resize-plugin/ | |||
| * | |||
| * Copyright (c) 2010 "Cowboy" Ben Alman | |||
| * Dual licensed under the MIT and GPL licenses. | |||
| * http://benalman.com/about/license/ | |||
| */ | |||
| (function($, h, c) { | |||
| var a = $([]), e = $.resize = $.extend($.resize, {}), i, k = "setTimeout", j = "resize", d = j + "-special-event", b = "delay", f = "throttleWindow"; | |||
| e[b] = 250; | |||
| e[f] = true; | |||
| $.event.special[j] = {setup: function() { | |||
| if (!e[f] && this[k]) { | |||
| return false; | |||
| } | |||
| var l = $(this); | |||
| a = a.add(l); | |||
| $.data(this, d, {w: l.width(), h: l.height()}); | |||
| if (a.length === 1) { | |||
| g(); | |||
| } | |||
| }, teardown: function() { | |||
| if (!e[f] && this[k]) { | |||
| return false | |||
| } | |||
| var l = $(this); | |||
| a = a.not(l); | |||
| l.removeData(d); | |||
| if (!a.length) { | |||
| clearTimeout(i); | |||
| } | |||
| }, add: function(l) { | |||
| if (!e[f] && this[k]) { | |||
| return false | |||
| } | |||
| var n; | |||
| function m(s, o, p) { | |||
| var q = $(this), r = $.data(this, d); | |||
| r.w = o !== c ? o : q.width(); | |||
| r.h = p !== c ? p : q.height(); | |||
| n.apply(this, arguments) | |||
| } | |||
| if ($.isFunction(l)) { | |||
| n = l; | |||
| return m | |||
| } else { | |||
| n = l.handler; | |||
| l.handler = m | |||
| } | |||
| }}; | |||
| function g() { | |||
| i = h[k](function() { | |||
| a.each(function() { | |||
| var n = $(this), m = n.width(), l = n.height(), o = $.data(this, d); | |||
| if (m !== o.w || l !== o.h) { | |||
| n.trigger(j, [o.w = m, o.h = l]) | |||
| } | |||
| }); | |||
| g() | |||
| }, e[b]) | |||
| }} | |||
| )(jQuery, this); | |||
| /*! | |||
| * SlimScroll https://github.com/rochal/jQuery-slimScroll | |||
| * ======================================================= | |||
| * | |||
| * Copyright (c) 2011 Piotr Rochala (http://rocha.la) Dual licensed under the MIT | |||
| */ | |||
| (function(f) { | |||
| jQuery.fn.extend({slimScroll: function(h) { | |||
| var a = f.extend({width: "auto", height: "100%", size: "7px", color: "#000", position: "right", distance: "1px", start: "top", opacity: 0.4, alwaysVisible: !0, disableFadeOut: !1, railVisible: !1, railColor: "#333", railOpacity: 0.2, railDraggable: !0, railClass: "slimScrollRail", barClass: "slimScrollBar", wrapperClass: "slimScrollDiv", allowPageScroll: !1, wheelStep: 20, touchScrollStep: 200, borderRadius: "5px", railBorderRadius: "5px"}, h); | |||
| this.each(function() { | |||
| function r(d) { | |||
| if (s) { | |||
| d = d || | |||
| window.event; | |||
| var c = 0; | |||
| d.wheelDelta && (c = -d.wheelDelta / 120); | |||
| d.detail && (c = d.detail / 3); | |||
| f(d.target || d.srcTarget || d.srcElement).closest("." + a.wrapperClass).is(b.parent()) && m(c, !0); | |||
| d.preventDefault && !k && d.preventDefault(); | |||
| k || (d.returnValue = !1) | |||
| } | |||
| } | |||
| function m(d, f, h) { | |||
| k = !1; | |||
| var e = d, g = b.outerHeight() - c.outerHeight(); | |||
| f && (e = parseInt(c.css("top")) + d * parseInt(a.wheelStep) / 100 * c.outerHeight(), e = Math.min(Math.max(e, 0), g), e = 0 < d ? Math.ceil(e) : Math.floor(e), c.css({top: e + "px"})); | |||
| l = parseInt(c.css("top")) / (b.outerHeight() - c.outerHeight()); | |||
| e = l * (b[0].scrollHeight - b.outerHeight()); | |||
| h && (e = d, d = e / b[0].scrollHeight * b.outerHeight(), d = Math.min(Math.max(d, 0), g), c.css({top: d + "px"})); | |||
| b.scrollTop(e); | |||
| b.trigger("slimscrolling", ~~e); | |||
| v(); | |||
| p() | |||
| } | |||
| function C() { | |||
| window.addEventListener ? (this.addEventListener("DOMMouseScroll", r, !1), this.addEventListener("mousewheel", r, !1), this.addEventListener("MozMousePixelScroll", r, !1)) : document.attachEvent("onmousewheel", r) | |||
| } | |||
| function w() { | |||
| u = Math.max(b.outerHeight() / b[0].scrollHeight * b.outerHeight(), D); | |||
| c.css({height: u + "px"}); | |||
| var a = u == b.outerHeight() ? "none" : "block"; | |||
| c.css({display: a}) | |||
| } | |||
| function v() { | |||
| w(); | |||
| clearTimeout(A); | |||
| l == ~~l ? (k = a.allowPageScroll, B != l && b.trigger("slimscroll", 0 == ~~l ? "top" : "bottom")) : k = !1; | |||
| B = l; | |||
| u >= b.outerHeight() ? k = !0 : (c.stop(!0, !0).fadeIn("fast"), a.railVisible && g.stop(!0, !0).fadeIn("fast")) | |||
| } | |||
| function p() { | |||
| a.alwaysVisible || (A = setTimeout(function() { | |||
| a.disableFadeOut && s || (x || y) || (c.fadeOut("slow"), g.fadeOut("slow")) | |||
| }, 1E3)) | |||
| } | |||
| var s, x, y, A, z, u, l, B, D = 30, k = !1, b = f(this); | |||
| if (b.parent().hasClass(a.wrapperClass)) { | |||
| var n = b.scrollTop(), | |||
| c = b.parent().find("." + a.barClass), g = b.parent().find("." + a.railClass); | |||
| w(); | |||
| if (f.isPlainObject(h)) { | |||
| if ("height"in h && "auto" == h.height) { | |||
| b.parent().css("height", "auto"); | |||
| b.css("height", "auto"); | |||
| var q = b.parent().parent().height(); | |||
| b.parent().css("height", q); | |||
| b.css("height", q) | |||
| } | |||
| if ("scrollTo"in h) | |||
| n = parseInt(a.scrollTo); | |||
| else if ("scrollBy"in h) | |||
| n += parseInt(a.scrollBy); | |||
| else if ("destroy"in h) { | |||
| c.remove(); | |||
| g.remove(); | |||
| b.unwrap(); | |||
| return | |||
| } | |||
| m(n, !1, !0) | |||
| } | |||
| } else { | |||
| a.height = "auto" == a.height ? b.parent().height() : a.height; | |||
| n = f("<div></div>").addClass(a.wrapperClass).css({position: "relative", | |||
| overflow: "hidden", width: a.width, height: a.height}); | |||
| b.css({overflow: "hidden", width: a.width, height: a.height}); | |||
| var g = f("<div></div>").addClass(a.railClass).css({width: a.size, height: "100%", position: "absolute", top: 0, display: a.alwaysVisible && a.railVisible ? "block" : "none", "border-radius": a.railBorderRadius, background: a.railColor, opacity: a.railOpacity, zIndex: 90}), c = f("<div></div>").addClass(a.barClass).css({background: a.color, width: a.size, position: "absolute", top: 0, opacity: a.opacity, display: a.alwaysVisible ? | |||
| "block" : "none", "border-radius": a.borderRadius, BorderRadius: a.borderRadius, MozBorderRadius: a.borderRadius, WebkitBorderRadius: a.borderRadius, zIndex: 99}), q = "right" == a.position ? {right: a.distance} : {left: a.distance}; | |||
| g.css(q); | |||
| c.css(q); | |||
| b.wrap(n); | |||
| b.parent().append(c); | |||
| b.parent().append(g); | |||
| a.railDraggable && c.bind("mousedown", function(a) { | |||
| var b = f(document); | |||
| y = !0; | |||
| t = parseFloat(c.css("top")); | |||
| pageY = a.pageY; | |||
| b.bind("mousemove.slimscroll", function(a) { | |||
| currTop = t + a.pageY - pageY; | |||
| c.css("top", currTop); | |||
| m(0, c.position().top, !1) | |||
| }); | |||
| b.bind("mouseup.slimscroll", function(a) { | |||
| y = !1; | |||
| p(); | |||
| b.unbind(".slimscroll") | |||
| }); | |||
| return!1 | |||
| }).bind("selectstart.slimscroll", function(a) { | |||
| a.stopPropagation(); | |||
| a.preventDefault(); | |||
| return!1 | |||
| }); | |||
| g.hover(function() { | |||
| v() | |||
| }, function() { | |||
| p() | |||
| }); | |||
| c.hover(function() { | |||
| x = !0 | |||
| }, function() { | |||
| x = !1 | |||
| }); | |||
| b.hover(function() { | |||
| s = !0; | |||
| v(); | |||
| p() | |||
| }, function() { | |||
| s = !1; | |||
| p() | |||
| }); | |||
| b.bind("touchstart", function(a, b) { | |||
| a.originalEvent.touches.length && (z = a.originalEvent.touches[0].pageY) | |||
| }); | |||
| b.bind("touchmove", function(b) { | |||
| k || b.originalEvent.preventDefault(); | |||
| b.originalEvent.touches.length && | |||
| (m((z - b.originalEvent.touches[0].pageY) / a.touchScrollStep, !0), z = b.originalEvent.touches[0].pageY) | |||
| }); | |||
| w(); | |||
| "bottom" === a.start ? (c.css({top: b.outerHeight() - c.outerHeight()}), m(0, !0)) : "top" !== a.start && (m(f(a.start).position().top, null, !0), a.alwaysVisible || c.hide()); | |||
| C() | |||
| } | |||
| }); | |||
| return this | |||
| }}); | |||
| jQuery.fn.extend({slimscroll: jQuery.fn.slimScroll}) | |||
| })(jQuery); | |||
| /*! iCheck v1.0.1 by Damir Sultanov, http://git.io/arlzeA, MIT Licensed */ | |||
| (function(h) { | |||
| function F(a, b, d) { | |||
| var c = a[0], e = /er/.test(d) ? m : /bl/.test(d) ? s : l, f = d == H ? {checked: c[l], disabled: c[s], indeterminate: "true" == a.attr(m) || "false" == a.attr(w)} : c[e]; | |||
| if (/^(ch|di|in)/.test(d) && !f) | |||
| D(a, e); | |||
| else if (/^(un|en|de)/.test(d) && f) | |||
| t(a, e); | |||
| else if (d == H) | |||
| for (e in f) | |||
| f[e] ? D(a, e, !0) : t(a, e, !0); | |||
| else if (!b || "toggle" == d) { | |||
| if (!b) | |||
| a[p]("ifClicked"); | |||
| f ? c[n] !== u && t(a, e) : D(a, e) | |||
| } | |||
| } | |||
| function D(a, b, d) { | |||
| var c = a[0], e = a.parent(), f = b == l, A = b == m, B = b == s, K = A ? w : f ? E : "enabled", p = k(a, K + x(c[n])), N = k(a, b + x(c[n])); | |||
| if (!0 !== c[b]) { | |||
| if (!d && | |||
| b == l && c[n] == u && c.name) { | |||
| var C = a.closest("form"), r = 'input[name="' + c.name + '"]', r = C.length ? C.find(r) : h(r); | |||
| r.each(function() { | |||
| this !== c && h(this).data(q) && t(h(this), b) | |||
| }) | |||
| } | |||
| A ? (c[b] = !0, c[l] && t(a, l, "force")) : (d || (c[b] = !0), f && c[m] && t(a, m, !1)); | |||
| L(a, f, b, d) | |||
| } | |||
| c[s] && k(a, y, !0) && e.find("." + I).css(y, "default"); | |||
| e[v](N || k(a, b) || ""); | |||
| B ? e.attr("aria-disabled", "true") : e.attr("aria-checked", A ? "mixed" : "true"); | |||
| e[z](p || k(a, K) || "") | |||
| } | |||
| function t(a, b, d) { | |||
| var c = a[0], e = a.parent(), f = b == l, h = b == m, q = b == s, p = h ? w : f ? E : "enabled", t = k(a, p + x(c[n])), | |||
| u = k(a, b + x(c[n])); | |||
| if (!1 !== c[b]) { | |||
| if (h || !d || "force" == d) | |||
| c[b] = !1; | |||
| L(a, f, p, d) | |||
| } | |||
| !c[s] && k(a, y, !0) && e.find("." + I).css(y, "pointer"); | |||
| e[z](u || k(a, b) || ""); | |||
| q ? e.attr("aria-disabled", "false") : e.attr("aria-checked", "false"); | |||
| e[v](t || k(a, p) || "") | |||
| } | |||
| function M(a, b) { | |||
| if (a.data(q)) { | |||
| a.parent().html(a.attr("style", a.data(q).s || "")); | |||
| if (b) | |||
| a[p](b); | |||
| a.off(".i").unwrap(); | |||
| h(G + '[for="' + a[0].id + '"]').add(a.closest(G)).off(".i") | |||
| } | |||
| } | |||
| function k(a, b, d) { | |||
| if (a.data(q)) | |||
| return a.data(q).o[b + (d ? "" : "Class")] | |||
| } | |||
| function x(a) { | |||
| return a.charAt(0).toUpperCase() + | |||
| a.slice(1) | |||
| } | |||
| function L(a, b, d, c) { | |||
| if (!c) { | |||
| if (b) | |||
| a[p]("ifToggled"); | |||
| a[p]("ifChanged")[p]("if" + x(d)) | |||
| } | |||
| } | |||
| var q = "iCheck", I = q + "-helper", u = "radio", l = "checked", E = "un" + l, s = "disabled", w = "determinate", m = "in" + w, H = "update", n = "type", v = "addClass", z = "removeClass", p = "trigger", G = "label", y = "cursor", J = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent); | |||
| h.fn[q] = function(a, b) { | |||
| var d = 'input[type="checkbox"], input[type="' + u + '"]', c = h(), e = function(a) { | |||
| a.each(function() { | |||
| var a = h(this); | |||
| c = a.is(d) ? | |||
| c.add(a) : c.add(a.find(d)) | |||
| }) | |||
| }; | |||
| if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a)) | |||
| return a = a.toLowerCase(), e(this), c.each(function() { | |||
| var c = h(this); | |||
| "destroy" == a ? M(c, "ifDestroyed") : F(c, !0, a); | |||
| h.isFunction(b) && b() | |||
| }); | |||
| if ("object" != typeof a && a) | |||
| return this; | |||
| var f = h.extend({checkedClass: l, disabledClass: s, indeterminateClass: m, labelHover: !0, aria: !1}, a), k = f.handle, B = f.hoverClass || "hover", x = f.focusClass || "focus", w = f.activeClass || "active", y = !!f.labelHover, C = f.labelHoverClass || | |||
| "hover", r = ("" + f.increaseArea).replace("%", "") | 0; | |||
| if ("checkbox" == k || k == u) | |||
| d = 'input[type="' + k + '"]'; | |||
| -50 > r && (r = -50); | |||
| e(this); | |||
| return c.each(function() { | |||
| var a = h(this); | |||
| M(a); | |||
| var c = this, b = c.id, e = -r + "%", d = 100 + 2 * r + "%", d = {position: "absolute", top: e, left: e, display: "block", width: d, height: d, margin: 0, padding: 0, background: "#fff", border: 0, opacity: 0}, e = J ? {position: "absolute", visibility: "hidden"} : r ? d : {position: "absolute", opacity: 0}, k = "checkbox" == c[n] ? f.checkboxClass || "icheckbox" : f.radioClass || "i" + u, m = h(G + '[for="' + b + '"]').add(a.closest(G)), | |||
| A = !!f.aria, E = q + "-" + Math.random().toString(36).replace("0.", ""), g = '<div class="' + k + '" ' + (A ? 'role="' + c[n] + '" ' : ""); | |||
| m.length && A && m.each(function() { | |||
| g += 'aria-labelledby="'; | |||
| this.id ? g += this.id : (this.id = E, g += E); | |||
| g += '"' | |||
| }); | |||
| g = a.wrap(g + "/>")[p]("ifCreated").parent().append(f.insert); | |||
| d = h('<ins class="' + I + '"/>').css(d).appendTo(g); | |||
| a.data(q, {o: f, s: a.attr("style")}).css(e); | |||
| f.inheritClass && g[v](c.className || ""); | |||
| f.inheritID && b && g.attr("id", q + "-" + b); | |||
| "static" == g.css("position") && g.css("position", "relative"); | |||
| F(a, !0, H); | |||
| if (m.length) | |||
| m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i", function(b) { | |||
| var d = b[n], e = h(this); | |||
| if (!c[s]) { | |||
| if ("click" == d) { | |||
| if (h(b.target).is("a")) | |||
| return; | |||
| F(a, !1, !0) | |||
| } else | |||
| y && (/ut|nd/.test(d) ? (g[z](B), e[z](C)) : (g[v](B), e[v](C))); | |||
| if (J) | |||
| b.stopPropagation(); | |||
| else | |||
| return!1 | |||
| } | |||
| }); | |||
| a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i", function(b) { | |||
| var d = b[n]; | |||
| b = b.keyCode; | |||
| if ("click" == d) | |||
| return!1; | |||
| if ("keydown" == d && 32 == b) | |||
| return c[n] == u && c[l] || (c[l] ? t(a, l) : D(a, l)), !1; | |||
| if ("keyup" == d && c[n] == u) | |||
| !c[l] && D(a, l); | |||
| else if (/us|ur/.test(d)) | |||
| g["blur" == | |||
| d ? z : v](x) | |||
| }); | |||
| d.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i", function(b) { | |||
| var d = b[n], e = /wn|up/.test(d) ? w : B; | |||
| if (!c[s]) { | |||
| if ("click" == d) | |||
| F(a, !1, !0); | |||
| else { | |||
| if (/wn|er|in/.test(d)) | |||
| g[v](e); | |||
| else | |||
| g[z](e + " " + w); | |||
| if (m.length && y && e == B) | |||
| m[/ut|nd/.test(d) ? z : v](C) | |||
| } | |||
| if (J) | |||
| b.stopPropagation(); | |||
| else | |||
| return!1 | |||
| } | |||
| }) | |||
| }) | |||
| } | |||
| })(window.jQuery || window.Zepto); | |||
| @@ -0,0 +1,221 @@ | |||
| /*! | |||
| * jQuery Mousewheel 3.1.13 | |||
| * | |||
| * Copyright jQuery Foundation and other contributors | |||
| * Released under the MIT license | |||
| * http://jquery.org/license | |||
| */ | |||
| (function (factory) { | |||
| if ( typeof define === 'function' && define.amd ) { | |||
| // AMD. Register as an anonymous module. | |||
| define(['jquery'], factory); | |||
| } else if (typeof exports === 'object') { | |||
| // Node/CommonJS style for Browserify | |||
| module.exports = factory; | |||
| } else { | |||
| // Browser globals | |||
| factory(jQuery); | |||
| } | |||
| }(function ($) { | |||
| var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], | |||
| toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? | |||
| ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], | |||
| slice = Array.prototype.slice, | |||
| nullLowestDeltaTimeout, lowestDelta; | |||
| if ( $.event.fixHooks ) { | |||
| for ( var i = toFix.length; i; ) { | |||
| $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; | |||
| } | |||
| } | |||
| var special = $.event.special.mousewheel = { | |||
| version: '3.1.12', | |||
| setup: function() { | |||
| if ( this.addEventListener ) { | |||
| for ( var i = toBind.length; i; ) { | |||
| this.addEventListener( toBind[--i], handler, false ); | |||
| } | |||
| } else { | |||
| this.onmousewheel = handler; | |||
| } | |||
| // Store the line height and page height for this particular element | |||
| $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); | |||
| $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); | |||
| }, | |||
| teardown: function() { | |||
| if ( this.removeEventListener ) { | |||
| for ( var i = toBind.length; i; ) { | |||
| this.removeEventListener( toBind[--i], handler, false ); | |||
| } | |||
| } else { | |||
| this.onmousewheel = null; | |||
| } | |||
| // Clean up the data we added to the element | |||
| $.removeData(this, 'mousewheel-line-height'); | |||
| $.removeData(this, 'mousewheel-page-height'); | |||
| }, | |||
| getLineHeight: function(elem) { | |||
| var $elem = $(elem), | |||
| $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); | |||
| if (!$parent.length) { | |||
| $parent = $('body'); | |||
| } | |||
| return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16; | |||
| }, | |||
| getPageHeight: function(elem) { | |||
| return $(elem).height(); | |||
| }, | |||
| settings: { | |||
| adjustOldDeltas: true, // see shouldAdjustOldDeltas() below | |||
| normalizeOffset: true // calls getBoundingClientRect for each event | |||
| } | |||
| }; | |||
| $.fn.extend({ | |||
| mousewheel: function(fn) { | |||
| return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); | |||
| }, | |||
| unmousewheel: function(fn) { | |||
| return this.unbind('mousewheel', fn); | |||
| } | |||
| }); | |||
| function handler(event) { | |||
| var orgEvent = event || window.event, | |||
| args = slice.call(arguments, 1), | |||
| delta = 0, | |||
| deltaX = 0, | |||
| deltaY = 0, | |||
| absDelta = 0, | |||
| offsetX = 0, | |||
| offsetY = 0; | |||
| event = $.event.fix(orgEvent); | |||
| event.type = 'mousewheel'; | |||
| // Old school scrollwheel delta | |||
| if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; } | |||
| if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; } | |||
| if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } | |||
| if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } | |||
| // Firefox < 17 horizontal scrolling related to DOMMouseScroll event | |||
| if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { | |||
| deltaX = deltaY * -1; | |||
| deltaY = 0; | |||
| } | |||
| // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy | |||
| delta = deltaY === 0 ? deltaX : deltaY; | |||
| // New school wheel delta (wheel event) | |||
| if ( 'deltaY' in orgEvent ) { | |||
| deltaY = orgEvent.deltaY * -1; | |||
| delta = deltaY; | |||
| } | |||
| if ( 'deltaX' in orgEvent ) { | |||
| deltaX = orgEvent.deltaX; | |||
| if ( deltaY === 0 ) { delta = deltaX * -1; } | |||
| } | |||
| // No change actually happened, no reason to go any further | |||
| if ( deltaY === 0 && deltaX === 0 ) { return; } | |||
| // Need to convert lines and pages to pixels if we aren't already in pixels | |||
| // There are three delta modes: | |||
| // * deltaMode 0 is by pixels, nothing to do | |||
| // * deltaMode 1 is by lines | |||
| // * deltaMode 2 is by pages | |||
| if ( orgEvent.deltaMode === 1 ) { | |||
| var lineHeight = $.data(this, 'mousewheel-line-height'); | |||
| delta *= lineHeight; | |||
| deltaY *= lineHeight; | |||
| deltaX *= lineHeight; | |||
| } else if ( orgEvent.deltaMode === 2 ) { | |||
| var pageHeight = $.data(this, 'mousewheel-page-height'); | |||
| delta *= pageHeight; | |||
| deltaY *= pageHeight; | |||
| deltaX *= pageHeight; | |||
| } | |||
| // Store lowest absolute delta to normalize the delta values | |||
| absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); | |||
| if ( !lowestDelta || absDelta < lowestDelta ) { | |||
| lowestDelta = absDelta; | |||
| // Adjust older deltas if necessary | |||
| if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { | |||
| lowestDelta /= 40; | |||
| } | |||
| } | |||
| // Adjust older deltas if necessary | |||
| if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { | |||
| // Divide all the things by 40! | |||
| delta /= 40; | |||
| deltaX /= 40; | |||
| deltaY /= 40; | |||
| } | |||
| // Get a whole, normalized value for the deltas | |||
| delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta); | |||
| deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); | |||
| deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); | |||
| // Normalise offsetX and offsetY properties | |||
| if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { | |||
| var boundingRect = this.getBoundingClientRect(); | |||
| offsetX = event.clientX - boundingRect.left; | |||
| offsetY = event.clientY - boundingRect.top; | |||
| } | |||
| // Add information to the event object | |||
| event.deltaX = deltaX; | |||
| event.deltaY = deltaY; | |||
| event.deltaFactor = lowestDelta; | |||
| event.offsetX = offsetX; | |||
| event.offsetY = offsetY; | |||
| // Go ahead and set deltaMode to 0 since we converted to pixels | |||
| // Although this is a little odd since we overwrite the deltaX/Y | |||
| // properties with normalized deltas. | |||
| event.deltaMode = 0; | |||
| // Add event and delta to the front of the arguments | |||
| args.unshift(event, delta, deltaX, deltaY); | |||
| // Clearout lowestDelta after sometime to better | |||
| // handle multiple device types that give different | |||
| // a different lowestDelta | |||
| // Ex: trackpad = 3 and mouse wheel = 120 | |||
| if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } | |||
| nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); | |||
| return ($.event.dispatch || $.event.handle).apply(this, args); | |||
| } | |||
| function nullLowestDelta() { | |||
| lowestDelta = null; | |||
| } | |||
| function shouldAdjustOldDeltas(orgEvent, absDelta) { | |||
| // If this is an older event and the delta is divisable by 120, | |||
| // then we are assuming that the browser is treating this as an | |||
| // older mouse wheel event and that we should divide the deltas | |||
| // by 40 to try and get a more usable deltaFactor. | |||
| // Side note, this actually impacts the reported scroll distance | |||
| // in older browsers and can cause scrolling to be slower than native. | |||
| // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. | |||
| return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; | |||
| } | |||
| })); | |||
| @@ -0,0 +1,962 @@ | |||
| var token; | |||
| if(isEmpty(token)){ | |||
| var meta = $("meta[name=_uid]"); | |||
| if(!isEmpty(meta)){ | |||
| token = meta.attr("content"); | |||
| console.log("token is uid:" + token); | |||
| } | |||
| } | |||
| var authorMeta = $("meta[name=author]"); | |||
| var userName; | |||
| if(!isEmpty(authorMeta)){ | |||
| userName = authorMeta.attr("content"); | |||
| console.log("user name=" + userName); | |||
| } | |||
| var userType; | |||
| if(isEmpty(userType)){ | |||
| userType =1; | |||
| } | |||
| var ip = getIp(); | |||
| var pageSize = 10; | |||
| var tableData; | |||
| var tablePageData; | |||
| var preDictTaskData; | |||
| var dataSetTaskData; | |||
| var userInfoData; | |||
| var labelPropertyData; | |||
| var repoId = $('#repoId').val(); | |||
| console.log("repoId=" + repoId); | |||
| function setDataSetTask(){ | |||
| dataset_task_list(); | |||
| display_createdatasetlabel(0); | |||
| //getUser(); | |||
| //dislpayUser(); | |||
| getLabelPropertyTask(); | |||
| displayLabelPropertyTask(); | |||
| $(".ui.dataset.modal").modal("show"); | |||
| } | |||
| function getLabelPropertyTask(){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/api/label-property-task-all/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| labelPropertyData = json; | |||
| console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function displayLabelPropertyTask(){ | |||
| var html="<option value=\"\" selected=\"\">请选择</option>"; | |||
| for (var i=0;i<labelPropertyData.length;i++){ | |||
| var row = "<option value=\""+labelPropertyData[i].id+ | |||
| "\">"+labelPropertyData[i].task_name + | |||
| "</option>"; | |||
| html=html+row; | |||
| } | |||
| console.log(html); | |||
| document.getElementById('labelpropertytask_dataset').innerHTML=html; | |||
| document.getElementById('labelpropertytask_auto').innerHTML=html; | |||
| } | |||
| function dataset_task_list(){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/gitea-dataset/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| data:{ | |||
| 'repoId':repoId, | |||
| 'dateset_type':'[1]' | |||
| }, | |||
| async:false, | |||
| success:function(json){ | |||
| dataSetTaskData = json; | |||
| console.log(json); | |||
| // return json.token; | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function countLabel(){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/gitea/label-count/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| alert("请等待几分钟,服务端正在加紧统计。"); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function display_createdatasetlabel(sindex=-1){ | |||
| var html=""; | |||
| for (var i=0;i<dataSetTaskData.length;i++){ | |||
| if (i==sindex){ | |||
| var row = "<option value=\""+dataSetTaskData[i].id+ | |||
| "\" selected=\"\">"+dataSetTaskData[i].task_name+ | |||
| "</option>"; | |||
| $("#datasetlabeltaskname").attr({value:dataSetTaskData[i].task_name + "-人工标注"}); | |||
| }else{ | |||
| var row = "<option value=\""+dataSetTaskData[i].id+ | |||
| "\">"+dataSetTaskData[i].task_name+ | |||
| "</option>"; | |||
| } | |||
| html=html+row; | |||
| } | |||
| console.log(html); | |||
| document.getElementById('dataset_list').innerHTML=html; | |||
| } | |||
| function setPredictTask(){ | |||
| pre_predict_task_list(); | |||
| display_createlabel(0); | |||
| getUser(); | |||
| dislpayUser(); | |||
| getLabelPropertyTask(); | |||
| displayLabelPropertyTask(); | |||
| } | |||
| function pre_predict_task_list(){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/api/pre-predict-taskforLabel/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| preDictTaskData = json; | |||
| console.log(json); | |||
| // return json.token; | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function sele_Change(sele){ | |||
| var predictTaskName = $('#pre_predict_task_for_label option:selected').text(); | |||
| console.log("select predictTaskName =" + predictTaskName); | |||
| $("#labeltaskname").attr({value:predictTaskName+"-人工标注"}); | |||
| } | |||
| function sele_export_Change(sele){ | |||
| var isNeedPicture = $('#isNeedPicture option:selected').val(); | |||
| if(isNeedPicture == 3){ | |||
| document.getElementById("maxscore_div").style.display="block"; | |||
| document.getElementById("minscore_div").style.display="block"; | |||
| $('#maxscore').val("1.0"); | |||
| $('#minscore').val("0.6"); | |||
| }else{ | |||
| document.getElementById("maxscore_div").style.display="none"; | |||
| document.getElementById("minscore_div").style.display="none"; | |||
| $('#maxscore').val(""); | |||
| $('#minscore').val(""); | |||
| } | |||
| } | |||
| function dataset_sele_Change(sele){ | |||
| var dataset_listName = $('#dataset_list option:selected').text(); | |||
| console.log("select dataset_list =" + dataset_listName); | |||
| $("#datasetlabeltaskname").attr({value:dataset_listName+"-人工标注"}); | |||
| } | |||
| function display_createlabel(sindex=-1){ | |||
| var html=""; | |||
| for (var i=0;i<preDictTaskData.length;i++){ | |||
| if (i==sindex){ | |||
| var row = "<option value=\""+preDictTaskData[i].id+ | |||
| "\" selected=\"\">"+preDictTaskData[i].task_name+ | |||
| "</option>"; | |||
| $("#labeltaskname").attr({value:preDictTaskData[i].task_name + "-人工标注"}); | |||
| }else{ | |||
| var row = "<option value=\""+preDictTaskData[i].id+ | |||
| "\">"+preDictTaskData[i].task_name+ | |||
| "</option>"; | |||
| } | |||
| html=html+row; | |||
| } | |||
| console.log(html); | |||
| document.getElementById('pre_predict_task_for_label').innerHTML=html; | |||
| } | |||
| var createsucced; | |||
| function submit_datasettask(){ | |||
| console.log($('#datasetlabeltaskname').val()); | |||
| var task_name = $('#datasetlabeltaskname').val(); | |||
| if (isEmpty(task_name) || task_name.length > 32){ | |||
| alert("人工标注任务名称不能为空或者不能超过32个字符。"); | |||
| return; | |||
| } | |||
| var assign_user_id = $('#assign_user option:selected').val(); | |||
| if(isEmpty(assign_user_id)){ | |||
| assign_user_id = token; | |||
| } | |||
| var relate_task_id = $('#dataset_list option:selected').val(); | |||
| if(isEmpty(relate_task_id)){ | |||
| alert("数据集对象不能为空。"); | |||
| return; | |||
| } | |||
| var labelpropertytaskid = $('#labelpropertytask_dataset option:selected').val(); | |||
| createsucced = true; | |||
| label_task_create(task_name, relate_task_id, 2,assign_user_id,labelpropertytaskid); | |||
| if(createsucced){ | |||
| $(".ui.dataset.modal").modal("hide"); | |||
| //$("#labelDataModal").modal('hide'); | |||
| } | |||
| page(0,pageSize); | |||
| } | |||
| function submit_labeltask(){ | |||
| console.log($('#labeltaskname').val()); | |||
| var task_name = $('#labeltaskname').val(); | |||
| if (isEmpty(task_name) || task_name.length > 32){ | |||
| alert("人工标注任务名称不能为空或者不能超过32个字符。"); | |||
| return; | |||
| } | |||
| var relate_task_id = $('#pre_predict_task_for_label option:selected').val(); | |||
| if(isEmpty(relate_task_id)){ | |||
| alert("关联的自动标注任务不能为空。"); | |||
| return; | |||
| } | |||
| var assign_user_id = $('#label_assign_user option:selected').val(); | |||
| if(isEmpty(assign_user_id)){ | |||
| assign_user_id = token; | |||
| } | |||
| var labelpropertytaskid = $('#labelpropertytask_dataset option:selected').val(); | |||
| createsucced = true; | |||
| label_task_create(task_name, relate_task_id, 1,assign_user_id,labelpropertytaskid); | |||
| if(createsucced){ | |||
| $("#labelModal").modal('hide'); | |||
| } | |||
| page(0,pageSize); | |||
| } | |||
| function label_task_create(task_name, relate_task_id, taskType,assign_user_id,labelpropertytaskid){ | |||
| var task_flow_type = $('#task_flow_type option:selected').val(); | |||
| var relate_other_label_task = []; | |||
| if(task_flow_type == 2){ | |||
| var items = document.getElementsByName("category"); | |||
| for (i = 0; i < items.length; i++) { | |||
| if (items[i].checked) { | |||
| relate_other_label_task.push(items[i].value); | |||
| } | |||
| } | |||
| } | |||
| relate_other_label_task_jsonstr = JSON.stringify(relate_other_label_task); | |||
| console.log("relate_task_id=" + relate_task_id); | |||
| $.ajax({ | |||
| type:"POST", | |||
| contentType:'application/json', | |||
| url:ip + "/gitea/label-task/", | |||
| dataType:"json", | |||
| async:false, | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| beforeSend: function (xhr) { | |||
| xhr.withCredentials = true | |||
| }, | |||
| data:JSON.stringify({'task_name':task_name, | |||
| 'assign_user_id':assign_user_id, | |||
| 'task_flow_type':task_flow_type, | |||
| 'relate_task_id':relate_task_id,//task id | |||
| 'relate_other_label_task': relate_other_label_task_jsonstr, | |||
| "taskType": taskType, | |||
| "appid": repoId, | |||
| "createUserName":userName, | |||
| "labelPropertyTaskId":labelpropertytaskid | |||
| }), | |||
| success:function(res){ | |||
| console.log(res); | |||
| if(res.code == 0){ | |||
| alert("人工校验任务创建成功!"); | |||
| createsucced = true; | |||
| } | |||
| else{ | |||
| alert("创建人工标注任务失败," + res.message); | |||
| createsucced = false; | |||
| } | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function list(current,pageSize){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/gitea/label-task-page/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| data:{'startPage':current, | |||
| 'pageSize':pageSize}, | |||
| async:false, | |||
| success:function(json){ | |||
| tablePageData = json; | |||
| tableData = json.data; | |||
| //console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| var otherUserLabelTaskData; | |||
| function flow_type_sele_Change(sele){ | |||
| var task_flow_type = $('#task_flow_type option:selected').val(); | |||
| if(task_flow_type == 2){ | |||
| var datasetid = $('#dataset_list option:selected').val(); | |||
| getOtherUserLabelTaskByDataSetId(datasetid); | |||
| var html = "<p>请选择该数据集要审核的标注任务</p>"; | |||
| for(var i = 0; i < otherUserLabelTaskData.length; i++){ | |||
| html += "<p><input type=\"checkbox\" name=\"category\" value=\"" + otherUserLabelTaskData[i].id + "\"/>" + otherUserLabelTaskData[i].task_name + "(标注人:" + otherUserLabelTaskData[i].assign_user + ")" + "</p>"; | |||
| } | |||
| document.getElementById('related_task_list').innerHTML=html; | |||
| }else{ | |||
| document.getElementById('related_task_list').innerHTML= ""; | |||
| } | |||
| } | |||
| function getOtherUserLabelTaskByDataSetId(datasetid){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/gitea/label-related-task/" + datasetid + "/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| otherUserLabelTaskData = json; | |||
| console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function dislpayUser(){ | |||
| var html="<option value=\"\" selected=\"\">请选择</option>"; | |||
| for (var i=0;i<userInfoData.length;i++){ | |||
| var row = "<option value=\""+userInfoData[i].id+ | |||
| "\">"+userInfoData[i].username+ | |||
| "</option>"; | |||
| html=html+row; | |||
| } | |||
| console.log(html); | |||
| document.getElementById('assign_user').innerHTML=html; | |||
| document.getElementById('label_assign_user').innerHTML=html; | |||
| } | |||
| function getUser(){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/api/queryAllUser/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| userInfoData = json; | |||
| console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function delete_labeltask(){ | |||
| var stop = del(); | |||
| if (stop){ | |||
| return; | |||
| } | |||
| var Check = $("table[id='label_task_list'] input[type=checkbox]:checked");//在table中找input下类型为checkbox属性为选中状态的数据 | |||
| Check.each(function () {//遍历 | |||
| var row = $(this).parent("td").parent("tr");//获取选中行 | |||
| var id = row.find("[id='labeltask_id']").html();//获取name='Sid'的值 | |||
| delete_labeltask_byid(id); | |||
| }); | |||
| page(0,pageSize); | |||
| } | |||
| function del(){ | |||
| if($("table[id='label_task_list'] input[type=checkbox]").is(":checked")) { | |||
| if (confirm("确实要删除吗?")) { | |||
| // alert("已经删除!"); | |||
| return false; | |||
| } else { | |||
| // alert("已经取消了删除操作"); | |||
| return true; | |||
| } | |||
| }else if($("table[id='label_task_list']").find("input").length=="0"){ | |||
| alert("暂无可删的数据!"); | |||
| return true; | |||
| }else{ | |||
| alert("请先选择需要删除的选项!"); | |||
| return true; | |||
| } | |||
| } | |||
| function delete_labeltask_byid(label_task_id){ | |||
| $.ajax({ | |||
| type:"DELETE", | |||
| url:ip + "/gitea/label-task/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| data:{'label_task_id': label_task_id}, | |||
| success:function(json){ | |||
| console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| } | |||
| function getTaskTypeDesc(task_type){ | |||
| if(task_type == 1){ | |||
| return "自动标注结果"; | |||
| }else if(task_type == 2){ | |||
| return "原始数据集-图片"; | |||
| }else if(task_type == 3){ | |||
| return "原始数据集-CT影像"; | |||
| }else if(task_type == 4){ | |||
| return "原始数据集-视频"; | |||
| } | |||
| return "其它"; | |||
| } | |||
| function getLabelDesc(task_flow_type){ | |||
| if(task_flow_type == 2){ | |||
| return "审核"; | |||
| }else{ | |||
| return "人工" | |||
| } | |||
| } | |||
| function getTaskSataus(task_status,task_status_desc){ | |||
| if(task_status == 0){ | |||
| return "标注中:" + task_status_desc; | |||
| }else if(task_status == 1){ | |||
| return "审核中:" + task_status_desc; | |||
| } | |||
| } | |||
| function getVerify(task_status,id,task_type){ | |||
| console.log("task_status=" + task_status + " userType=" + userType); | |||
| if(task_status == 0 && (userType == 1 || userType == 0) ){ | |||
| return "<a onclick=\"startToVerify(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">转审核</a> "; | |||
| }else if(task_status == 1 && userType == 2){ | |||
| return "<a onclick=\"goVerify(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">进入审核</a> " + "<a onclick=\"startToLabel(\'"+id+"\',\'" + task_type +"\');\" class=\"btn btn-xs btn-success\">转标注</a> "; | |||
| }else{ | |||
| return ""; | |||
| } | |||
| } | |||
| function getLabel(task_status,id,task_type,task_flow_type){ | |||
| if(task_status == 0 && (userType == 1 || userType == 0)){ | |||
| return "<a onclick=\"personLabel(\'" + id + "\'," + task_type + ")\"><b>" + getLabelDesc(task_flow_type) + "标注</b></a><br>"; | |||
| }else{ | |||
| return ""; | |||
| } | |||
| } | |||
| function display_list(){ | |||
| var html="<tr>\ | |||
| <th></th>\ | |||
| <th id=\"labeltask_head\"></th>\ | |||
| <th>标注任务名称</th>\ | |||
| <th>关联的任务名称</th>\ | |||
| <th>数据类型</th>\ | |||
| <th>标注人员</th>\ | |||
| <th>审核人员</th>\ | |||
| <th>任务开始时间</th>\ | |||
| <th>任务状态</th>\ | |||
| <th>总标注数量</th>\ | |||
| <th>操作</th>\ | |||
| </tr>"; | |||
| for (var i=0;i<tableData.length;i++){ | |||
| var row = "<tr>\ | |||
| <td><input type=\"checkbox\" class=\"flat-grey list-child\"/></td>\ | |||
| <td id=\"labeltask_id\">"+tableData[i].id+"</td>\ | |||
| <td>"+tableData[i].task_name+"</td>\ | |||
| <td>"+tableData[i].relate_task_name+"</td>\ | |||
| <td>"+ getTaskTypeDesc(tableData[i].task_type) +"</td>\ | |||
| <td>"+tableData[i].assign_user+"</td>\ | |||
| <td>"+tableData[i].verify_user+"</td>\ | |||
| <td>"+tableData[i].task_add_time+"</td>\ | |||
| <td>"+getTaskSataus(tableData[i].task_status,tableData[i].task_status_desc)+"</td>\ | |||
| <td>"+tableData[i].total_label+"</td>\ | |||
| <td>" + | |||
| getLabel(tableData[i].task_status,tableData[i].id,tableData[i].task_type,tableData[i].task_flow_type) + "<a onclick=\"setTaskId(\'"+tableData[i].id+"\');\"><b>导出标注</b></a>" | |||
| + | |||
| "</td>\ | |||
| </tr>"; | |||
| html=html+row; | |||
| } | |||
| //console.log(html); | |||
| document.getElementById('label_task_list').innerHTML=html; | |||
| $('#label_task_list tr').find('td:eq(1)').hide(); | |||
| $('#label_task_list tr').find('th:eq(1)').hide(); | |||
| } | |||
| function startToLabel(taskid, task_type){//从审核转回标注,标注人不变。 | |||
| $.ajax({ | |||
| type:"PATCH", | |||
| url:ip + "/gitea/label-task-status/", | |||
| dataType:"json", | |||
| async:false, | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| data:{ | |||
| "label_task_id" : taskid, | |||
| "verify_user_id" : 0, | |||
| "task_status" : 0 | |||
| }, | |||
| success:function(res){ | |||
| console.log(res); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| var current =$('#displayPage1').text(); | |||
| page(current - 1,pageSize); | |||
| } | |||
| function startToVerify(taskid, task_type){ | |||
| $("#hide_labeltasktoverifyid").val(taskid); | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/api/queryVerifyUser/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| console.log(json); | |||
| var html="<option value=\"\" selected=\"\">请选择</option>"; | |||
| for (var i=0;i<json.length; i++){ | |||
| var row = "<option value=\""+json[i].id+"\">" + json[i].username + "</option>"; | |||
| html=html+row; | |||
| } | |||
| document.getElementById('label_verify_user').innerHTML=html; | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| $("#startToVerify").modal('show'); | |||
| } | |||
| function submit_labeltask_toverify(){ | |||
| var label_task_id = $('#hide_labeltasktoverifyid').val(); | |||
| console.log("label_task_id=" +label_task_id); | |||
| var verify_user_id = $('#label_verify_user option:selected').val(); | |||
| //修改状态 | |||
| $.ajax({ | |||
| type:"PATCH", | |||
| url:ip + "/gitea/label-task-status/", | |||
| dataType:"json", | |||
| async:false, | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| data:{ | |||
| "label_task_id" : label_task_id, | |||
| "verify_user_id" : verify_user_id, | |||
| "task_status" : 1 | |||
| }, | |||
| success:function(res){ | |||
| console.log(res); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| $("#startToVerify").modal('hide'); | |||
| var current =$('#displayPage1').text(); | |||
| page(current - 1,pageSize); | |||
| } | |||
| function goVerify(taskid, task_type){ | |||
| sessionStorage.setItem('label_task',taskid); | |||
| sessionStorage.setItem('label_task_status',1);//审核 | |||
| console.log("task_type=" + task_type); | |||
| if(task_type == 2 || task_type == 1 || task_type == 4){ | |||
| window.location.href="labeling.html"; | |||
| }else if(task_type == 3){ | |||
| window.location.href="labelingDcm.html"; | |||
| } | |||
| } | |||
| function personLabel(taskid, task_type){ | |||
| sessionStorage.setItem('label_task',taskid); | |||
| sessionStorage.setItem('token',token); | |||
| sessionStorage.setItem('userType',1); | |||
| var pathname = window.location.pathname; | |||
| var search = window.location.search | |||
| var url_name = pathname + search | |||
| sessionStorage.setItem('return_url',url_name); | |||
| console.log("task_type=" + task_type); | |||
| if(task_type == 2 || task_type == 1 || task_type == 4){ | |||
| window.open("/self/labeling.html","标注"); | |||
| //window.location.href="/self/labeling.html"; | |||
| }else if(task_type == 3){ | |||
| window.location.href="labelingDcm.html"; | |||
| } | |||
| } | |||
| function setMultiTaskId(){ | |||
| var Check = $("table[id='label_task_list'] input[type=checkbox]:checked");//在table中找input下类型为checkbox属性为选中状态的数据 | |||
| if(Check.length == 0){ | |||
| alert("请选择一个或者多个标注数据进行导出。"); | |||
| return; | |||
| } | |||
| var taskList = []; | |||
| Check.each(function () {//遍历 | |||
| var row = $(this).parent("td").parent("tr");//获取选中行 | |||
| var id = row.find("[id='labeltask_id']").html();//获取name='Sid'的值 | |||
| taskList.push(id); | |||
| //$('#hide_labeltaskid').val(id); | |||
| }); | |||
| setTaskId(JSON.stringify(taskList)); | |||
| } | |||
| function setTaskId(labeltaskid){ | |||
| $('#hide_labeltaskid').val(labeltaskid); | |||
| console.log("go here1"); | |||
| bar.style.width='1%'; | |||
| document.getElementById('text-progress').innerHTML="0%"; | |||
| document.getElementById("predtask_id").removeAttribute("disabled"); | |||
| console.log("go here2"); | |||
| $(".ui.export.modal").modal("show"); | |||
| } | |||
| function isBeetween(score_threshhold){ | |||
| if(isEmpty(score_threshhold)){ | |||
| return true; | |||
| } | |||
| var regPos = /^\d+(\.\d+)?$/; //非负浮点数 | |||
| if(!regPos.test(score_threshhold)){ | |||
| return false; | |||
| }else{ | |||
| if(score_threshhold >1 || score_threshhold < 0){ | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| function downloadFile(){ | |||
| var labeltaskid = $('#hide_labeltaskid').val(); | |||
| var isNeedPicture = $('#isNeedPicture option:selected').val(); | |||
| var maxscore = $('#maxscore').val(); | |||
| var minscore = $('#minscore').val(); | |||
| var exportFormat = $('#exportFormat option:selected').val(); | |||
| if(isNeedPicture == 3){ | |||
| if(!isBeetween(maxscore)){ | |||
| alert("标注得分最大值应该填写0--1.0之间的数值。"); | |||
| return; | |||
| } | |||
| if(!isBeetween(minscore)){ | |||
| alert("标注得分最小值应该填写0--1.0之间的数值。"); | |||
| return; | |||
| } | |||
| if(!isEmpty(maxscore) && !isEmpty(minscore)){ | |||
| if(minscore>maxscore){ | |||
| alert("标注得分最小值应该小于标注得分最大值。"); | |||
| return; | |||
| } | |||
| } | |||
| } | |||
| document.getElementById("predtask_id").setAttribute("disabled", true); | |||
| var taskreturnid = ""; | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/gitea-label-task-export/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| data:{ | |||
| "label_task_id" : labeltaskid, | |||
| "needPicture" : isNeedPicture, | |||
| "exportFormat":exportFormat, | |||
| "maxscore":maxscore, | |||
| "minscore":minscore | |||
| }, | |||
| async:false, | |||
| success:function(json){ | |||
| taskreturnid = json.message; | |||
| console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| redirect(response); | |||
| } | |||
| }); | |||
| console.log("taskreturnid=" +taskreturnid); | |||
| if(!isEmpty(taskreturnid)){ | |||
| setIntervalToDo(taskreturnid); | |||
| } | |||
| } | |||
| var timeId=[]; | |||
| var count; | |||
| var progress; | |||
| function setIntervalToDo(taskreturnid){ | |||
| count=0; | |||
| var tmpTimeId = self.setInterval("clock('" + taskreturnid +"')",1000);//5秒刷新 | |||
| timeId.push(tmpTimeId); | |||
| console.log("开始刷新。timeId=" + tmpTimeId); | |||
| } | |||
| function clock(taskreturnid){ | |||
| count++; | |||
| if(count > 600 ){ | |||
| for(var i = 0;i < timeId.length; i++){ | |||
| console.log("清除定时器1。exportTimeId=" + timeId[i]); | |||
| window.clearInterval(timeId[i]); | |||
| } | |||
| timeId = []; | |||
| $(".ui.export.modal").modal("hide"); | |||
| return; | |||
| } | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:ip + "/api/query-download-progress/", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| data:{'taskId': taskreturnid}, | |||
| async:false, | |||
| success:function(json){ | |||
| progress = json; | |||
| console.log(json); | |||
| }, | |||
| error:function(response) { | |||
| progress = null; | |||
| console.log('query return null.'); | |||
| redirect(response); | |||
| } | |||
| }); | |||
| if(!isEmpty(progress)){ | |||
| if(progress.progress >= 100){ | |||
| var iSpeed = progress.progress; | |||
| bar.style.width=iSpeed+'%'; | |||
| document.getElementById('text-progress').innerHTML=iSpeed+'%' + ",开始下载文件。" | |||
| for(var i = 0;i < timeId.length; i++){ | |||
| console.log("清除定时器2。exportTimeId=" + timeId[i]); | |||
| window.clearInterval(timeId[i]); | |||
| } | |||
| timeId = []; | |||
| var url = ip + "/api/label-file-download/"; | |||
| var $iframe = $('<iframe />'); | |||
| var $form = $('<form method="get" target="_self"/>'); | |||
| $form.attr('action', url); //设置get的url地址 | |||
| $form.append('<input type="hidden" name="taskId" value="' + taskreturnid + '" />'); | |||
| $iframe.append($form); | |||
| $(document.body).append($iframe); | |||
| $form[0].submit();//提交表单 | |||
| $iframe.remove();//移除框架 | |||
| $(".ui.export.modal").modal("hide"); | |||
| }else{ | |||
| //更新进度 | |||
| var iSpeed = progress.progress; | |||
| bar.style.width=iSpeed+'%'; | |||
| document.getElementById('text-progress').innerHTML=iSpeed+'%' | |||
| } | |||
| }else{ | |||
| count = 600; | |||
| } | |||
| } | |||
| function page(current,pageSize){ | |||
| list(current,pageSize); | |||
| display_list(); | |||
| setPage(tablePageData,pageSize); | |||
| sessionStorage.setItem('label_task_page',current); | |||
| } | |||
| function nextPage(){ | |||
| var current = $('#displayPage1').text(); | |||
| console.log("current=" + current); | |||
| page(current,pageSize); | |||
| } | |||
| function prePage(){ | |||
| var current =$('#displayPage1').text(); | |||
| console.log("current=" + current); | |||
| if(current > 1){ | |||
| console.log("current=" + (current - 2)); | |||
| page(current - 2,pageSize); | |||
| } | |||
| } | |||
| function goPage(){ | |||
| var goNum = $('#goNum').val(); | |||
| var pageTotal = $("#totalNum").text(); | |||
| var pageNum = parseInt(pageTotal/pageSize); | |||
| if(pageTotal%pageSize!=0){ | |||
| pageNum += 1; | |||
| }else { | |||
| pageNum = pageNum; | |||
| } | |||
| if (goNum<=0){ | |||
| alert("请输入大于0的数值"); | |||
| } | |||
| else if(goNum<=pageNum){ | |||
| page(goNum - 1,pageSize); | |||
| } | |||
| else{ | |||
| alert("不能超出总页码!"); | |||
| } | |||
| } | |||
| $("#goNum").keydown(function (e) { | |||
| if (e.keyCode == 13) { | |||
| goPage(); | |||
| } | |||
| }); | |||
| function setPage(pageData,pageSize){ | |||
| if (isEmpty(pageData)){ | |||
| return; | |||
| } | |||
| var startIndex = pageData.current * pageSize; | |||
| if(pageData.total > 0){ | |||
| startIndex = startIndex + 1; | |||
| } | |||
| $('#startIndex').text(startIndex); | |||
| $('#endIndex').text(pageData.current * pageSize + pageData.data.length); | |||
| $('#totalNum').text(pageData.total); | |||
| $('#displayPage1').text(pageData.current + 1); | |||
| console.log("set prePage status, pageData.current=" + pageData.current); | |||
| if(pageData.current == 0){ | |||
| console.log("set prePage disabled."); | |||
| $('#prePage').removeAttr("href"); | |||
| $('#prePage').attr('style','color:#f5f5f6;'); | |||
| } | |||
| else{ | |||
| $('#prePage').attr("href","javascript:prePage()"); | |||
| $('#prePage').attr('style','color:#000;'); | |||
| } | |||
| if((pageData.current + 1) * pageSize >= pageData.total){ | |||
| console.log("set nextPage disabled."); | |||
| $('#nextPage').removeAttr("href"); | |||
| } | |||
| else{ | |||
| $('#nextPage').attr("href","javascript:nextPage()"); | |||
| } | |||
| var pageTotal = pageData.total; | |||
| var pageNum = parseInt(pageTotal/pageSize); | |||
| if(pageTotal%pageSize!=0){ | |||
| pageNum += 1; | |||
| }else { | |||
| pageNum = pageNum; | |||
| } | |||
| $("#totalPageNum").text(pageNum); | |||
| } | |||
| var tmpCurrent = sessionStorage.getItem("label_task_page"); | |||
| if(isEmpty(tmpCurrent)){ | |||
| tmpCurrent = 0; | |||
| } | |||
| page(tmpCurrent,pageSize); | |||
| @@ -0,0 +1,874 @@ | |||
| <!-- <!DOCTYPE html> --> | |||
| <!DOCTYPE html> | |||
| <html > | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>PCL数据标注平台V2.0</title> | |||
| <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> | |||
| <meta name="description" content="Developed By M Abdur Rokib Promy"> | |||
| <meta name="keywords" content="Admin, Bootstrap 3, Template, Theme, Responsive"> | |||
| <!-- bootstrap 3.0.2 --> | |||
| <link href="/self/css/bootstrap.min.css" rel="stylesheet" type="text/css" /> | |||
| <!-- font Awesome --> | |||
| <link href="/self/css/font-awesome.min.css" rel="stylesheet" type="text/css" /> | |||
| <!-- Ionicons --> | |||
| <link href="/self/css/ionicons.min.css" rel="stylesheet" type="text/css" /> | |||
| <!-- google font --> | |||
| <!-- Theme style --> | |||
| <link href="/self/css/style.css" rel="stylesheet" type="text/css" /> | |||
| <link href="/self/css/jquery.yhhDataTable.css" rel="stylesheet" type="text/css" /> | |||
| <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | |||
| <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> | |||
| <!--[if lt IE 9]> | |||
| <![endif]--> | |||
| <script> | |||
| window.config={ | |||
| AppSubUrl:'', | |||
| StaticUrlPrefix: '', | |||
| csrf: '', | |||
| } | |||
| </script> | |||
| <style> | |||
| html body{ height: 100%;margin: 0;padding: 0;} | |||
| .containers{ | |||
| height: 100%; | |||
| } | |||
| .table-define td{border-bottom: 1px solid #222324;padding-top: 5px !important;padding-bottom:5px !important;border-top: 0px !important;padding-left: 20px !important;vertical-align: middle !important;} | |||
| .btn:hover{background: transparent;} | |||
| .display_area_content { } /* this class is used to clear the display area content */ | |||
| .force_small_font { font-size:small !important; } | |||
| .draw_tool{padding:0;color:#fff} | |||
| .draw_li {padding: 0.2em;border: 0.5px solid rgba(34,35,36,0.2);border-bottom: 0;border-radius: 3px;cursor: pointer;} | |||
| ul.region_shape { font-size:xx-large; list-style-type:none; overflow:hidden; padding:0.4em 0; margin:0; } | |||
| /*ul.region_shape li { float:left; padding:0 0.2em; fill:#ffffff; stroke:#000000; }*/ | |||
| ul.region_shape li { float:right; padding:0 0.2em; fill:#ffffff; stroke:#000000; } | |||
| ul.region_shape li:hover { cursor:pointer; fill:#ffffff; stroke:#ff0000; } | |||
| ul.region_shape .selected { fill:#ffffff; stroke:#ff0000; } | |||
| /*.toolbar { display:inline-block; margin-left:1rem; }*/ | |||
| .toolbar { display:inline-block; margin-right:1rem; } | |||
| .toolbar svg { fill:white; margin: 0.2rem 0.1rem; height:1.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none;} | |||
| .toolbar svg:hover { fill:yellow; cursor:pointer; } | |||
| .toolbar svg:active { fill:white; } | |||
| .toolbar ul { display:inline-block; padding:0.2rem; margin:0; } | |||
| /*.toolbar li { display:inline; float:left; padding:0rem 0.3rem; border:1px solid white;} *//* main menu items */ | |||
| .toolbar li { display:inline; float:right; padding:0rem 0.3rem; border:1px solid white;} | |||
| .toolbar li:hover { color:red; cursor:pointer; } | |||
| /* Top panel : #navbar, #toolbar */ | |||
| .top_panel { font-size:0.9rem; display:block; background-color:#212121; color:#ffffff; z-index:1001; margin-bottom:1rem;} | |||
| /* Navigation menu bar that appear at the top */ | |||
| .menubar { display:inline-block; height:1.8rem; } /* height needed to avoid extra bottom border */ | |||
| .menubar a:link { color:#eeeeee; text-decoration:none; } | |||
| .menubar a:visited { color:#eeeeee; text-decoration:none; } | |||
| .menubar ul { display:block; padding:0; margin:0; } | |||
| /*.menubar li { display:inline; float:left; padding:0.45rem 1rem; }*/ | |||
| .menubar li { display:inline; float:right; padding:0.45rem 1rem; } | |||
| .menubar li:hover { background-color:#616161; cursor:default; } | |||
| .menubar li ul { display:none; background-color:#212121; border:1px solid #616161; min-width:10rem; position:absolute; z-index:100; margin:0.4rem -1rem;} | |||
| .menubar li ul li { display:block; float:none; color:#eeeeee; margin:0; padding:0.6rem 1rem; } | |||
| .menubar li ul li:hover { cursor:pointer; } | |||
| .menubar li ul li.submenu_divider { margin:0 0.4rem; padding:0; height:1px; border-bottom:1px solid #424242; } | |||
| .menubar li:hover ul { display:block; } | |||
| /* toolbar containing small icons for tools */ | |||
| .toolbar { display:inline-block; margin-right:1rem; } | |||
| /*.toolbar { display:inline-block; margin-left:1rem; }*/ | |||
| .toolbar svg { fill:white; margin: 0.2rem 0.1rem; height:1.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none;} | |||
| .toolbar svg:hover { fill:yellow; cursor:pointer; } | |||
| .toolbar svg:active { fill:white; } | |||
| .toolbar ul { display:inline-block; padding:0.2rem; margin:0; } | |||
| /*.toolbar li { display:inline; float:left; padding:0rem 0.3rem; border:1px solid white;} *//* main menu items */ | |||
| .toolbar li { display:inline; float:right; padding:0rem 0.3rem; border:1px solid white;} | |||
| .toolbar li:hover { color:red; cursor:pointer; } | |||
| /* Middle panel: containing #image_panel, #leftsidebar */ | |||
| /*.middle_panel { display:table; table-layout:fixed; width:100%; z-index:1; padding:0;}*/ | |||
| .middle_panel { display:table; table-layout:fixed; right:0px,width:100%; z-index:1; padding:0;} | |||
| /*#leftsidebar { display:none; z-index:10; vertical-align:top;}*/ | |||
| #leftsidebar { display:none; z-index:10; vertical-align:top;} | |||
| /*#rightsidebar { z-index:-10; vertical-align:left;}*/ | |||
| /*#display_area { display:table-cell; width:100%; z-index:1; margin:0; padding-left:1em; vertical-align:top; }*/ | |||
| #display_area { display:table-cell; width:100%; z-index:1; margin:0; padding-right:1em; vertical-align:top; } | |||
| /* layers of canvas */ | |||
| /*#image_panel { position:relative; outline:none; } | |||
| #image_panel img { visibility:hidden; opacity:0; position:absolute; top:0px; left:0px; width:100%; height:100%; outline:none; }*/ | |||
| #image_panel { position:relative; outline:none; } | |||
| #image_panel img { visibility:hidden; opacity:0; position:absolute; top:0px; right:0px; width:100%; height:100%; outline:none; } | |||
| #image_panel canvas { position:absolute; top:0px; left:0px; outline:none;} | |||
| #image_panel .visible { visibility:visible !important; opacity:1 !important; } | |||
| #image_panel label>img { visibility:visible; opacity:1; position:relative; width:auto; height:4em; outline:none; } | |||
| #leftsidebar_collapse_panel { display:none; position:relative; z-index:10; vertical-align:top; } | |||
| /*#leftsidebar_show_button { font-size:large; margin-left:0.1rem; }*/ | |||
| #leftsidebar_show_button { font-size:large; margin-right:0.1rem; } | |||
| #leftsidebar_show_button:hover { color:red; cursor: pointer; } | |||
| /* Left sidebar accordion */ | |||
| button.leftsidebar_accordion { font-size:large; background-color:#f2f2f2; cursor:pointer; padding:0.5em 0.5em; width:100%; text-align:left; border:0; outline:none; } | |||
| button.leftsidebar_accordion:focus { outline: none; } | |||
| button.leftsidebar_accordion.active, button.leftsidebar_accordion:hover { background-color: #e6e6e6; } | |||
| button.leftsidebar_accordion:after { content:'\02795'; color:#4d4d4d; float:right; } | |||
| button.leftsidebar_accordion.active:after { content: '\2796'; } | |||
| .leftsidebar_accordion_panel { display:none; padding:0 0.5em; font-size:small; border-right:0px solid #f2f2f2; border-bottom:0px solid #f2f2f2; } | |||
| .leftsidebar_accordion_panel.show { display:block; } | |||
| /* Keyboard shortcut panel */ | |||
| .leftsidebar_accordion_panel table { border-collapse:collapse; } | |||
| .leftsidebar_accordion_panel td { border:1px solid #f2f2f2; padding:0.2rem 0.4rem; } | |||
| /* buttons */ | |||
| /*.button_panel { display:inline-block; width:100%; margin:0.2rem 0; }*/ | |||
| .button_panel { display:inline-block; width:100%; margin:0.2rem 0; } | |||
| .button_panel .text_button, .text_button { color: #0000ff; padding: 0.2rem 0.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; } | |||
| .button_panel .flush_right { float:right; } | |||
| .button_panel .text_button:hover, .text_button:hover { cursor:pointer; } | |||
| .button_panel .text_button:active, .text_button:active { color: #000000; } | |||
| .button_panel .active { border-bottom:1px solid black; } | |||
| .button_panel .button { display:inline-block; padding:0.35rem 0.5rem; margin:0 0.05rem; cursor:pointer; background-color:#cccccc; border-radius:0.2rem; -moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; } | |||
| .button_panel .button:hover { background-color:black; color:white; } | |||
| /* Attributes properties: name, description, type, ... */ | |||
| #attribute_properties { display:table; right:200;width:100%; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; } | |||
| /*#attribute_properties { display:table; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; }*/ | |||
| #attribute_properties .property { display:table-row;} | |||
| #attribute_properties .property span { display:table-cell; padding: 0.2rem 0.4rem; } | |||
| #attribute_properties .property span input { width: 100%; border:1px solid #cccccc; margin: 0;} | |||
| #attribute_properties .property span input:focus { border:1px solid black; } | |||
| #attribute_properties .property span select { width: 100%; border:1px solid #cccccc; margin: 0;} | |||
| /* Attributes options: options for attribute type={checkbox,radio,...} */ | |||
| #attribute_options { display:table; width:100%; border-collapse:collapse; margin:1rem 0; border:1px solid #cccccc; table-layout:fixed; } | |||
| #attribute_options .new_option_id_entry { display:inline-block; padding:1rem 0.2rem; } | |||
| #attribute_options .new_option_id_entry input {border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 1.3rem;} | |||
| #attribute_options .property { display:table-row;} | |||
| #attribute_options .property span { display:table-cell; padding: 0.2rem 0.2rem; font-weight:bold; } | |||
| /*#attribute_options .property input { display:table-cell; width:100%; border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 0.8rem;}*/ | |||
| #attribute_options .property input { display:table-cell; width:100%; border:none; border-bottom:1px solid #cccccc; margin: 0; font-size: 1.3rem;} | |||
| #attribute_options .property input:focus { border-bottom:1px solid #000000; background-color:#f2f2f2; color:#000000; } | |||
| #attribute_options .property span input[type=checkbox] { vertical-align:middle; } | |||
| #attribute_options .property span input[type=radio] { vertical-align:middle; } | |||
| #user_input_panel { position:fixed; display:none; width:100%; height:100%; top:0; left:50; right:0; bottom:0; background-color: rgba(0,0,0,0.6); z-index:1002; } | |||
| /*#user_input_panel .content { position:fixed; background-color:white; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); padding:2rem 4rem;}*/ | |||
| #user_input_panel .content { position:fixed; background-color:white; top:50%; left:50%; transform:translate(-50%,-50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); padding:2rem 4rem;} | |||
| #user_input_panel .content .title { font-size:large; font-weight:bold; } | |||
| #user_input_panel .content .user_inputs { display:table; width:100%; border-collapse:collapse;} | |||
| #user_input_panel .content .user_inputs .row { display:table-row; } | |||
| #user_input_panel .content .user_inputs .cell { display:table-cell; padding:1rem 0.5rem; vertical-align:middle; border:1px solid #f2f2f2; } | |||
| #user_input_panel .content .user_confirm { display:table; width:100%; text-align:center; margin:2rem 0;} | |||
| #user_input_panel .content .user_confirm .ok { display:table-cell; width:48%; } | |||
| #user_input_panel .content .user_confirm .cancel { display:table-cell; width:48%; } | |||
| #user_input_panel .content .warning { color:red; } | |||
| /* Attribute editor */ | |||
| #annotation_editor_panel { position:fixed; display:none; width:100%; right:0; bottom:0; background-color:white; border-top:2px solid #cccccc; padding:0.2em 1em; overflow:auto; z-index:1001; box-shadow: 0 0 1em #cccccc;} | |||
| /*#annotation_editor { display:table; margin-bottom:3em; border-collapse:collapse; font-size:inherit; position: absolute; top:500px;left:800px; background-color:white; }*/ | |||
| #annotation_editor { display:table; margin-bottom:3em; border-collapse:collapse; font-size:inherit; background-color:white; z-index:10024;} | |||
| #annotation_editor .row { display:table-row; } | |||
| #annotation_editor .highlight .col { background-color:#e6e6e6;} | |||
| #annotation_editor .col { display:table-cell; padding:0.4em 0.6em; border:1px solid #000000; vertical-align:middle; font-size:inherit; } | |||
| #annotation_editor .header { font-weight:bold; white-space:nowrap} | |||
| #annotation_editor .id { font-weight:bold; } | |||
| #annotation_editor .col input[type=checkbox] { vertical-align:middle; } | |||
| #annotation_editor .col input[type=radio] { vertical-align:middle; font-size:inherit; } | |||
| #annotation_editor .col label { vertical-align:middle; font-size:inherit; } | |||
| #annotation_editor .col textarea { border:0.1em solid #cccccc; padding:0; margin:0; font-size:inherit; background-color:#ffffff;height:20px;width: 80px} | |||
| #annotation_editor .col textarea:focus { border:0.1em dashed #cccccc; } | |||
| #annotation_editor .col span { display:block; } | |||
| #annotation_editor .col horizontal_container { display:inline-block; } | |||
| #annotation_editor .col .img_options { display:inline; } | |||
| #annotation_editor .col .img_options .imrow { display:block; } | |||
| #annotation_editor .col .img_options span { display:inline-block; margin: 0.2rem 0.4rem;} | |||
| #annotation_editor .col .img_options span img { height:4em; } | |||
| #annotation_editor .col .img_options p { margin:0; padding:0; font-size:inherit; } | |||
| #annotation_editor .col .img_options input[type=radio] { display:none; } | |||
| #annotation_editor .col .img_options input[type=radio] + label { display:block; cursor:pointer; text-align:center;} | |||
| #annotation_editor .col .img_options input[type=radio]:checked + label { border: 0.1em solid black; background-color:#cccccc; cursor:default; font-size:inherit; } | |||
| /* Region shape selection panel inside leftsidebar */ | |||
| ul.region_shape { font-size:xx-large; list-style-type:none; overflow:hidden; padding:0.4em 0; margin:0; } | |||
| ul.region_shape li { float:left; padding:0 0.2em; fill:#ffffff; stroke:#000000; } | |||
| /*ul.region_shape li { float:right; padding:0 0.2em; fill:#ffffff; stroke:#000000; }*/ | |||
| ul.region_shape li:hover { cursor:pointer; fill:#ffffff; stroke:#ff0000; } | |||
| ul.region_shape .selected { fill:#ffffff; stroke:#ff0000; } | |||
| /* cursor coordinates inside region shape selection panel in leftsidebar */ | |||
| #region_info { font-size:0.8em; margin-bottom:0.4em; } | |||
| /*#message_panel { display:block; width:100%; position:fixed; bottom:300px; z-index:9999; text-align:center; }*/ | |||
| #message_panel { display:block; width:100%; position:fixed; bottom:30px; right:0;z-index:9999; text-align:center; } | |||
| #message_panel .content { display:inline; margin:auto; background-color:#000000; color:#ffff00; font-size:small; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:2rem; padding: 0.5rem 2rem;} | |||
| .text_panel { display:none; margin:auto; font-size:medium; line-height:1.3em; margin: 0; max-width:700px; } | |||
| /*.text_panel li { margin:1em 0; text-align:left; } | |||
| .text_panel p { text-align:left; }*/ | |||
| .text_panel li { margin:1em 0; text-align:right; } | |||
| .text_panel p { text-align:right; } | |||
| .svg_button:hover { cursor:pointer; } | |||
| /* Loading spinbar */ | |||
| .loading_spinbox { display:inline-block; border:0.4em solid #cccccc; border-radius:50%; border-top:0.4em solid black; border-bottom:0.4em solid black;-webkit-animation:spin 2s linear infinite; animation:spin 2s linear infinite; } | |||
| @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } | |||
| @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } | |||
| #invisible_file_input { width:0.1px; height:0.1px; opacity:0; overflow:hidden; position:absolute; z-index:-1; } | |||
| .display_none { display:none !important; } | |||
| .display_block { display:block !important; } | |||
| .display_area_content { } /* this class is used to clear the display area content */ | |||
| .narrow_page_content li { font-size:0.9rem; margin: 0.4rem 0; } | |||
| .narrow_page_content { width:60%; } | |||
| .force_small_font { font-size:small !important; } | |||
| .key { font-family:monospace; padding:1px 6px; background:linear-gradient(to bottom,#f0f0f0,#fcfcfc);; border:1px solid #e0e0e0; white-space:nowrap; color:#303030; border-bottom-width:2px; border-radius:3px; font-size:1.2em; } | |||
| #progress{ | |||
| width: 100%; | |||
| height: 20px; | |||
| background: rgb(255, 255, 255); | |||
| } | |||
| #bar{ | |||
| width: 1%; | |||
| height: 20px; | |||
| margin-top: 1px; | |||
| background: green; | |||
| } | |||
| </style> | |||
| </head> | |||
| <body> | |||
| <svg style="display:none;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
| <defs> | |||
| <symbol id="via_logo"> | |||
| <!-- Logo designed by Abhishek Dutta <adutta@robots.ox.ac.uk>, May 2018 --> | |||
| <title>VGG Image Annotator Logo</title> | |||
| <rect width="400" height="160" x="0" y="0" fill="#212121"></rect> | |||
| <text x="56" y="130" font-family="Serif" font-size="100" fill="white">V</text> | |||
| <text x="180" y="130" font-family="Serif" font-size="100" fill="white">I</text> | |||
| <text x="270" y="130" font-family="Serif" font-size="100" fill="white">A</text> | |||
| <rect width="80" height="100" x="52" y="40" stroke="yellow" fill="none" stroke-width="2"></rect> | |||
| <text x="72" y="30" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">VGG</text> | |||
| <rect width="50" height="100" x="175" y="45" stroke="yellow" fill="none" stroke-width="2"></rect> | |||
| <text x="175" y="35" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">Image</text> | |||
| <rect width="80" height="100" x="265" y="40" stroke="yellow" fill="none" stroke-width="2"></rect> | |||
| <text x="265" y="30" font-family="'Comic Sans MS', cursive, sans-serif" font-size="18" fill="yellow">Annotator</text> | |||
| </symbol> | |||
| <symbol id="shape_rectangle"> | |||
| <rect width="20" height="12" x="6" y="10" stroke-width="2"></rect> | |||
| </symbol> | |||
| <symbol id="shape_circle"> | |||
| <title>Circular region shape</title> | |||
| <circle r="10" cx="16" cy="16" stroke-width="2"></circle> | |||
| </symbol> | |||
| <symbol id="shape_ellipse"> | |||
| <title>Elliptical region shape</title> | |||
| <ellipse rx="12" ry="8" cx="16" cy="16" stroke-width="2"></ellipse> | |||
| </symbol> | |||
| <symbol id="shape_polygon"> | |||
| <path d="M 15.25,2.2372 3.625,11.6122 6,29.9872 l 20.75,-9.625 2.375,-14.75 z" stroke-width="2"></path> | |||
| </symbol> | |||
| <symbol id="shape_point"> | |||
| <circle r="3" cx="16" cy="16" stroke-width="2"></circle> | |||
| </symbol> | |||
| <symbol id="shape_polyline"> | |||
| <title>Polyline region shape</title> | |||
| <path d="M 2,12 10,24 18,12 24,18" stroke-width="2"></path> | |||
| <circle r="1" cx="2" cy="12" stroke-width="2"></circle> | |||
| <circle r="1" cx="10" cy="24" stroke-width="2"></circle> | |||
| <circle r="1" cx="18" cy="12" stroke-width="2"></circle> | |||
| <circle r="1" cx="24" cy="18" stroke-width="2"></circle> | |||
| </symbol> | |||
| <!-- Material icons downloaded from https://material.io/icons --> | |||
| <symbol id="icon_settings"> | |||
| <path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path> | |||
| </symbol> | |||
| <symbol id="icon_save"> | |||
| <path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"></path> | |||
| </symbol> | |||
| <symbol id="icon_open"> | |||
| <path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"></path> | |||
| </symbol> | |||
| <symbol id="icon_gridon"> | |||
| <path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H4v-4h4v4zm0-6H4v-4h4v4zm0-6H4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4z"></path> | |||
| </symbol> | |||
| <symbol id="icon_gridoff"> | |||
| <path d="M8 4v1.45l2 2V4h4v4h-3.45l2 2H14v1.45l2 2V10h4v4h-3.45l2 2H20v1.45l2 2V4c0-1.1-.9-2-2-2H4.55l2 2H8zm8 0h4v4h-4V4zM1.27 1.27L0 2.55l2 2V20c0 1.1.9 2 2 2h15.46l2 2 1.27-1.27L1.27 1.27zM10 12.55L11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H4v-4h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.54V20zm2 0v-1.46L17.46 20H16z"></path> | |||
| </symbol> | |||
| <symbol id="icon_next"> | |||
| <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path> | |||
| </symbol> | |||
| <symbol id="icon_prev"> | |||
| <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path> | |||
| </symbol> | |||
| <symbol id="icon_list"> | |||
| <path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"></path> | |||
| </symbol> | |||
| <symbol id="icon_zoomin"> | |||
| <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> | |||
| <path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/> | |||
| </symbol> | |||
| <symbol id="icon_zoomout"> | |||
| <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"></path> | |||
| </symbol> | |||
| <symbol id="icon_copy"> | |||
| <path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path> | |||
| </symbol> | |||
| <symbol id="icon_paste"> | |||
| <path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path> | |||
| </symbol> | |||
| <symbol id="icon_pasten"> | |||
| <path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path> | |||
| <text x="8" y="18">n</text> | |||
| </symbol> | |||
| <symbol id="icon_pasteundo"> | |||
| <path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"></path> | |||
| <text x="8" y="18">x</text> | |||
| </symbol> | |||
| <symbol id="icon_selectall"> | |||
| <path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"></path> | |||
| </symbol> | |||
| <symbol id="icon_close"> | |||
| <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> | |||
| </symbol> | |||
| <symbol id="icon_insertcomment"> | |||
| <path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path> | |||
| </symbol> | |||
| <symbol id="icon_checkbox"> | |||
| <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path> | |||
| </symbol> | |||
| <symbol id="icon_fileupload"> | |||
| <path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"></path> | |||
| </symbol> | |||
| <symbol id="icon_filedownload"> | |||
| <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path> | |||
| </symbol> | |||
| </defs> | |||
| </svg> | |||
| <!-- header logo: style can be found in header.less --> | |||
| <!-- <header class="header" > | |||
| <div class="logo"> | |||
| 人工标注 | |||
| </div> | |||
| <nav class="navbar navbar-static-top" role="navigation"> | |||
| <span style="font-size:28px" id="title_id">通用图片标注</span> | |||
| </nav> | |||
| </header> --> | |||
| <div style="height:100vh;display:flex;flex-flow:column nowrap;overflow:hidden;position: relative;"> | |||
| <header class="header"> | |||
| <div class="row" style="background-color: #020004;"> | |||
| <div class="col-lg-1"> | |||
| <a id="return_url" href="" style="margin: 8px;display: inline-block;"><i class="fa fa-home fa-fw" style="color: #E1E3E6;font-size: 24px;"></i></a> | |||
| </div> | |||
| <div class="col-lg-9"> | |||
| <div class="row"> | |||
| <div class="col-lg-6" style=" padding-left: 0;"> | |||
| <!-- <button type="button" class="btn" style="background:#3291F8;margin:8px 12px 8px 0;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">返回任务</button> | |||
| <button type="button" class="btn" style="margin: 8px 12px;background:#74818D;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">跳过</button> | |||
| <button type="button" class="btn" style="margin: 8px 12px;background:#FF6200;color: #fff;border-radius: 0;padding: 4px 12px;font-size: 12px;">提交</button> --> | |||
| </div> | |||
| <div class="col-lg-1" style="text-align: center;;line-height: 42px;color: #fff;"> | |||
| <span id="float_text"> dog.1000.jpg</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="col-lg-2"></div> | |||
| </div> | |||
| </header> | |||
| <div class="box1" style="float:left;position: absolute;z-index: 9999;left: 0.4em;top: 3.5em;"> | |||
| <ul class="draw_tool" style="font-size: 18px;background-color: rgba(12,13,13,0.3);color: rgba(225,227,230,0.8);"> | |||
| <li id="region_shape_rect" class="selected draw_li" onclick="createRectLabel()" title="新建矩形标注(W)"><i class="fa fa-square-o"></i></li> | |||
| <li id="region_shape_polygon" class="draw_li" onclick="createMaskLabel()" title="新建多边形标注"><i class="fa fa-first-order" aria-hidden="true"></i> </li> | |||
| <li id="region_shape_point" class="draw_li" onclick="createPointLabel()" title="新建点标注"><i class="fa fa-circle-o"></i></li> | |||
| <li id="delete_shape" class="draw_li" onclick="deleterect()" title="删除选中的标注(D)"><i class="fa fa-times-circle-o" aria-hidden="true"></i></li> | |||
| <li id="delete_all_shape" class="draw_li" onclick="deleteAllRect()" title="删除所有的标注框"><i class="fa fa-times" aria-hidden="true"></i></li> | |||
| <li id="save_shape" class="draw_li" onclick="save()" title="保存标注(S)"><i class="fa fa-floppy-o" aria-hidden="true"></i></li> | |||
| <!-- <li id="previous_shape" onclick="last()" title="上一张(Q)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_prev"></use></svg></li> | |||
| <li id="next_shape" onclick="next()" title="下一张(E)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_next"></use></svg></li> --> | |||
| <li id="copy_shape" class="draw_li" onclick="copyOneBox()" title="复制单个选中的标注(C)"><i class="fa fa-file-o" aria-hidden="true"></i></li> | |||
| <li id="copy_shape" class="draw_li" onclick="copy()" title="复制所有的标注"><i class="fa fa-clone" aria-hidden="true"></i></li> | |||
| <li id="paste_shape" class="draw_li" onclick="paste()" title="粘贴复制的标注(V)"><i class="fa fa-clipboard" aria-hidden="true"></i></li> | |||
| <li id="arrow-left" class="draw_li" onclick="moveLeftOnePx()" title="标注左移一个像素"><i class="fa fa-arrow-left" aria-hidden="true"></i> </li> | |||
| <li id="arrow-right" class="draw_li" onclick="moveRightOnePx()" title="标注右移一个像素"><i class="fa fa-arrow-right" aria-hidden="true"></i> </li> | |||
| <li id="arrow-up" class="draw_li" onclick="moveUpOnePx()" title="标注上移一个像素"><i class="fa fa-arrow-up" aria-hidden="true"></i></li> | |||
| <li id="arrow-down" class="draw_li" onclick="moveDownOnePx()" title="标注下移一个像素"><i class="fa fa-arrow-down" aria-hidden="true"></i></li> | |||
| <li id="setting" class="draw_li" onclick="updateSetting()" title="设置" href="#labeldefine"><i class="fa fa-cog" aria-hidden="true"></i> </li> | |||
| <li id="skip" class="draw_li" onclick="skipLast()" title="跳转至上次标注的地方"><i class="fa fa-eraser" aria-hidden="true"></i></li> | |||
| <!-- <li class="draw_li" onclick="setAutoModel()" title="自动标注" href="#autoLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-cube" aria-hidden="true"></i></li> --> | |||
| <li class="draw_li" onclick="undo()" title="撤销上次标注(Z)" ><i class="fa fa-reply-all" aria-hidden="true"></i></li> | |||
| <li style="padding: 0.2em;border: 0.5px solid rgba(34,35,36,0.2);border-radius: 3px;cursor: pointer;" title="清空指定文件的标注" href="#deleteLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-eraser" aria-hidden="true"></i></li> | |||
| </ul> | |||
| </div> | |||
| <div class="containers" style="flex: 1;"> | |||
| <!-- <aside class="left-side sidebar-offcanvas" ></aside> --> | |||
| <div class="row" style="height: 100%;"> | |||
| <!-- left-side --> | |||
| <!-- <div class="col-lg-1" style="background-color: #020004;height: 100%;border-top: 1px solid #222324;padding: 0;"> | |||
| <div style="line-height: 3em;text-align: center;font-size: 16px;"> | |||
| <span style="color: #fff;float: left;padding-left: 1.5em;">动物-狗</span> | |||
| <a style="float: right;padding-right: 1em;"><i class="fa fa-cog" style="color: #74818D;font-size: 18px;cursor: pointer;"></i></a> | |||
| </div> | |||
| <div style="clear: both;"> | |||
| <input type="text" placeholder="搜索标签" style="width: 80%;margin: 0 10%;background-color: transparent;border-radius: 6px;border: 0.5px solid #43474B;outline: none;color: #74818D;padding: 0.1em;"> | |||
| </div> | |||
| </div> --> | |||
| <!-- canvas --> | |||
| <div class="col-lg-10" id="showPic" style="background-color: #222324;height: 100%;padding: 0;padding-left: 4em;"> | |||
| <!-- <nav class="navbar navbar-default" role="navigation" id="tool0" style="margin-bottom: 0;"> | |||
| <div class="leftsidebar_accordion_panel show"> | |||
| <ul class="region_shape" style="padding: 0;"> | |||
| <li id="region_shape_rect" class="selected" onclick="createRectLabel()" title="新建矩形标注(W)"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_rectangle"></use></svg></li> | |||
| <li id="region_shape_polygon" onclick="createMaskLabel()" title="新建多边形标注"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_polygon"></use></svg></li> | |||
| <li id="region_shape_point" onclick="createPointLabel()" title="新建点标注"><svg height="28" viewbox="0 0 28 28"><use xlink:href="#shape_point"></use></svg></li> | |||
| <li id="delete_shape" onclick="deleterect()" title="删除选中的标注(D)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_close"></use></svg></li> | |||
| <li id="save_shape" onclick="save()" title="保存标注(S)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_save"></use></svg></li> | |||
| <li id="previous_shape" onclick="last()" title="上一张(Q)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_prev"></use></svg></li> | |||
| <li id="next_shape" onclick="next()" title="下一张(E)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_next"></use></svg></li> | |||
| <li id="copy_shape" onclick="copy()" title="复制所有的标注"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_copy"></use></svg></li> | |||
| <li id="paste_shape" onclick="paste()" title="粘贴复制的标注(V)"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_pasten"></use></svg></li> | |||
| <li id="copy_shape" style="font-size: 20px;" onclick="copyOneBox()" title="复制单个选中的标注(C)"><i class="fa fa-files-o" style="vertical-align: bottom;" aria-hidden="true"></i></li> | |||
| <li id="arrow-left" style="font-size: 26px" onclick="moveLeftOnePx()" title="标注左移一个像素"><i class="fa fa-long-arrow-left" aria-hidden="true" ></i></li> | |||
| <li id="arrow-right" style="font-size: 26px" onclick="moveRightOnePx()" title="标注右移一个像素"><i class="fa fa-long-arrow-right" aria-hidden="true"></i></li> | |||
| <li id="arrow-up" style="font-size: 26px" onclick="moveUpOnePx()" title="标注上移一个像素"><i class="fa fa-long-arrow-up" aria-hidden="true"></i></li> | |||
| <li id="arrow-down" style="font-size: 26px" onclick="moveDownOnePx()" title="标注下移一个像素"><i class="fa fa-long-arrow-down" aria-hidden="true"></i></li> | |||
| <li id="delete_all_shape" style="font-size: 22px;" onclick="deleteAllRect()" title="删除所有的标注框"><i class="fa fa-window-close-o" style="vertical-align: middle;" aria-hidden="true" ></i></li> | |||
| <li id="setting" onclick="updateSetting()" title="设置" href="#labeldefine"><svg height="24" viewbox="0 0 28 28"><use xlink:href="#icon_settings"></use></svg></li> | |||
| <li id="skip" style="font-size: 22px" onclick="skipLast()" title="跳转至上次标注的地方"><i class="fa fa-share" aria-hidden="true"></i></li> | |||
| <li style="font-size: 22px" onclick="setAutoModel()" title="自动标注" href="#autoLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-tag" aria-hidden="true"></i></li> | |||
| <li style="font-size: 22px" onclick="undo()" title="撤销上次标注(Z)" ><i class="fa fa-undo" aria-hidden="true"></i></li> | |||
| <li style="font-size: 22px" title="清空指定文件的标注" href="#deleteLabel" data-toggle="modal" data-backdrop="static" ><i class="fa fa-eraser" aria-hidden="true"></i></li> | |||
| </ul> | |||
| </div> | |||
| <div id=labeldefine> | |||
| </div> | |||
| </nav> --> | |||
| <div id="labelwin" width="100%" > | |||
| <input type="hidden" class="form-control" id="postmessage" > | |||
| <div id = "show_region" style="z-index: 50000;position: absolute;width: 0px;height: 0px"></div> | |||
| <canvas id="myCanvas" style="border:1px solid #5a5a5a;"></canvas> | |||
| <div id="float_text"></div> | |||
| </div> | |||
| </div> | |||
| <!-- right side --> | |||
| <div class="col-lg-2" style="background-color: #020004;height: 100%;border-top: 1px solid #222324;padding: 0;"> | |||
| <div style="line-height: 3em;text-align: center;font-size: 14px;"> | |||
| <span id="task_info" style="color: #fff;float: left;padding-left: 1.5em;">train数据集标注任务</span> | |||
| <!-- <a style="float: right;padding-right: 2em;"><i class="fa fa-cog" style="color: #74818D;font-size: 18px;cursor: pointer;"></i></a> --> | |||
| </div> | |||
| <div class="progress" style="clear: both;margin: 0 2em 0 1em;height: 0.5em;"> | |||
| <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;background-color: #389E0D;"> | |||
| <span class="sr-only">60% Complete</span> | |||
| </div> | |||
| </div> | |||
| <div style="margin: 1em 1.5em;font-size: 10px;"> | |||
| <span style="color: #7092BE;margin-right: 1em;">任务标注进度</span><span id="task_progress" style="color:#7092BE;"></span> | |||
| </div> | |||
| <div class="panel" style="margin-bottom: 1em;"> | |||
| <div id = "labelStatus"></div> | |||
| </div> | |||
| <div id="nav" style="height:100%"> | |||
| <ul style="display: flex;padding: 0;margin: 0;color:#7092BE;"> | |||
| <li id="0" class="active">文件列表</li> | |||
| <li id="1">标签列表</li> | |||
| </ul> | |||
| <div class="tabpannel" style="height: 100%;"> | |||
| <!-- <h4 class="ui top attached header"> | |||
| 文件列表 | |||
| </h4> --> | |||
| <!-- <table class="ui single line table" id="filelist" style="table-layout:fixed;word-break: break-all;word-wrap: break-word;"> | |||
| </table> --> | |||
| <div class="panel-body no-padding" id="filepanel" style="height: 100%;"> | |||
| <div style="display: flex;padding: 0.3em 0;border-bottom: 1px solid #222324 ;"> | |||
| <span style="flex: 3;padding-left: 20px;color: #7092BE;">文件名</span> | |||
| <div class="btn-group" style="flex:1"> | |||
| <button type="button" class="btn-default dropdown-toggle" | |||
| data-toggle="dropdown" style="background: transparent;padding: 0;border: 0;vertical-align: top;line-height: 1;color: #7092BE;"> | |||
| ... | |||
| </button> | |||
| <ul class="dropdown-menu" role="menu" style="left:-90px;background: #020004;border: 1px solid #222324;border-radius: 0;width:2em;min-width: 8em;color: #fff;"> | |||
| <li value="1" onclick="showOrder($(this).attr('value'))" style="font-size: 8px;color: #fff;padding: 0.3em 0 0.3em 2em;width: 100%;text-align: start;border-bottom: 0.5px solid #222324;">按文件名排序</li> | |||
| <li value="2" onclick="showOrder($(this).attr('value'))" style="font-size: 8px;color: #fff;padding: 0.3em 0 0.3em 2em;width: 100%;text-align: start;">未标注</li> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| <table class="table table-condensed table-define" id="filelist" style="table-layout:fixed;overflow:auto;word-break: break-all;word-wrap: break-word;color:#7092BE;font-size: 10px;"> | |||
| </table> | |||
| </div> | |||
| <div class="panel-body" id="filepanel" style='position: absolute;bottom: 0;padding: 0.9em 0;width: 100%;border-top: 1px #ccc solid; color: #7092BE;'> | |||
| <div style="width: 80%; margin: 0 10%;"> | |||
| <a id="prePage" href="" style="margin-right: 0.2em;"><i class="fa fa-angle-left"></i></a> | |||
| <span id="startIndex">0</span>-<span id="endIndex">0</span>/<span id="totalNum">0</span> | |||
| <span style="margin-left: 0.2em;">第</span><span id="displayPage1">1</span><span style="margin-right: 0.2em;">页</span> | |||
| <span>跳到</span><input type="text" id="goNum" style="width: 2em;border-radius: 4px;padding: 0 0.4em;margin: 0 0.4em;height: 1.2em;border: 1px solid;" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><span>页</span> | |||
| <a style="margin-left: 0.4em;" id="nextPage" href=""><i class="fa fa-angle-right"></i></a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="hide1 tabpannel"> | |||
| <div class="panel-body no-padding" id="labelpanel"> | |||
| <table class="table table-condensed table-define" style="color: #fff;" > | |||
| <tbody id="boxlabels"> | |||
| </tbody> | |||
| </table> | |||
| </div><!-- /.panel-body --> | |||
| <div class="panel-body no-padding" id="labelcountpanel" style="display: none;"> | |||
| <table class="table table-condensed" id="labelcounttable"> | |||
| </table> | |||
| </div><!-- /.panel-body --> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="panel" id="set_attributes" class="force_small_font display_area_content" style="display:none;"> | |||
| <button class="close" onclick="close_attribute()" style=" padding: .3em 0.8em;"> × </button> | |||
| <div id="user_input_panel"></div> | |||
| <div id="message_panel"> | |||
| <div id="message_panel_content" class="content"></div> | |||
| </div> | |||
| <div id="leftsidebar_collapse_panel"> | |||
| <span class="text_button" onclick="leftsidebar_toggle()" title="Show left sidebar">▸</span> | |||
| </div> | |||
| <div id="leftsidebar"> | |||
| <div class="leftsidebar_accordion_panel show" id="attributes_editor_panel"> | |||
| <div class="button_panel" style="padding:1rem 0;"> | |||
| <h4 class="modal-title">设置</h4> | |||
| </div> | |||
| <div id="attributes_update_panel"> | |||
| <div class="button_panel"> | |||
| <input style="width:50%" type="text" placeholder="attribute name" id="user_input_attribute_id" value=""> | |||
| <span id="button_add_new_attribute" class="button" onclick="add_new_attribute_from_user_input()" title="Add new attribute">+</span> | |||
| </div> | |||
| <div class="button_panel" style="margin:0.1rem 0;width:70%;" > | |||
| <table class="table table-hover" id="attributes_name_list"> | |||
| </table> | |||
| </div> | |||
| <div id="atttibute_child" > | |||
| <div id="type_car" style="display: none;"> | |||
| <span class= "btn btn-xs btn-success" style="margin-left:5px" onclick="show_tpye_attribute();">点击此处快速添加常用车辆类别</span> | |||
| </div> | |||
| <div id="type_color" style="display: none;"> | |||
| <span class= "btn btn-xs btn-success" style="margin-left:5px" onclick="show_color_attribute();">点击此处快速添加常用颜色</span> | |||
| </div> | |||
| <div id="attribute_properties"> </div> | |||
| <div id="attribute_options"></div> | |||
| <p style="text-align:center"></p> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button type="button" class="btn btn-default" onclick="save_attribute()" id="save" style=" margin:0.5rem 0.3rem "> 保存属性值</button> | |||
| <button type="button" class="btn btn-default" onclick="export_attribute()" id="export" style=" margin:0.5rem 0.3rem;float:right"> 导出属性值</button> | |||
| <button type="button" class="btn btn-default" onclick="import_attribute()" id="import" style=" margin:0.5rem 0.3rem;float:right"> 导入属性值</button> | |||
| </div> | |||
| </div> | |||
| </div> <!-- Dialog setAttribute --> | |||
| <div style="width: 100%;" id="vertical_space"></div> | |||
| </div><!-- /.panel --> | |||
| <div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="autoLabel" class="modal fade"> | |||
| <div class="modal-dialog"> | |||
| <div class="modal-content"> | |||
| <div class="modal-header"> | |||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||
| <h4 class="modal-title">自动标注</h4> | |||
| </div> | |||
| <div class="modal-body"> | |||
| <form role="form"> | |||
| <div class="form-group"> | |||
| <label for="exampleInputPassword1">自动标注任务使用的模型</label> | |||
| <select class="form-control" name="预检模型" id="predict_model" onchange="model_sele_Change(this)"> | |||
| <option value="" >请选择</option> | |||
| <!--<option value="1" selected="">Faster RCNN</option> --> | |||
| </select> | |||
| </div> | |||
| <div id="tracking_startid_div" class="form-group" style="display:none"> | |||
| <label for="exampleInputEmail1">追踪起始图片ID</label> | |||
| <input type="" class="form-control" id="tracking_startid" placeholder="追踪起始图片ID"> | |||
| </div> | |||
| <div id="tracking_endid_div" class="form-group" style="display:none"> | |||
| <label for="exampleInputEmail1">追踪结束图片ID</label> | |||
| <input type="" class="form-control" id="tracking_endid" placeholder="追踪结束图片ID"> | |||
| </div> | |||
| <div id="label_id_div" class="form-group"> | |||
| <label for="exampleInputEmail1">标注框ID</label> | |||
| <input type="" class="form-control" id="label_id" placeholder="标注框ID"> | |||
| </div> | |||
| <div id="labelOption_div" class="form-group"> | |||
| <label for="exampleInputEmail1">标注信息选项</label> | |||
| <select class="form-control" name="labelOption" id="labelOption"> | |||
| <option value="4">请选择</option> | |||
| <!--<option value="0" selected="">合并已有的标注信息</option> | |||
| <option value="1">删除已有的标注信息</option> | |||
| <option value="2">识别车的颜色及车的类型</option> --> | |||
| </select> | |||
| </div> | |||
| <div id="progress"> | |||
| <div id="bar"></div> | |||
| </div> | |||
| <div><h5 id="text-progress">0%</h3></div> | |||
| <button id="predtask_id" type="button" onclick="submit_predtask();">提交</button> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="deleteLabel" class="modal fade"> | |||
| <div class="modal-dialog"> | |||
| <div class="modal-content"> | |||
| <div class="modal-header"> | |||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||
| <h4 class="modal-title">清空指定文件的标注</h4> | |||
| </div> | |||
| <div class="modal-body"> | |||
| <form role="form"> | |||
| <div id="delete_startid_div" class="form-group"> | |||
| <label for="exampleInputEmail1">起始文件ID(对应文件列表中第几条)</label> | |||
| <input type="" class="form-control" id="delete_startid" placeholder="起始文件ID"> | |||
| </div> | |||
| <div id="delete_endid_div" class="form-group"> | |||
| <label for="exampleInputEmail1">结束文件ID(对应文件列表中第几条)</label> | |||
| <input type="" class="form-control" id="delete_endid" placeholder="结束文件ID"> | |||
| </div> | |||
| <button id="predtask_id" type="button" onclick="submit_deletelabel();">提交</button> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div aria-hidden="true" aria-labelledby="myModalLabelc" role="dialog" tabindex="-1" id="datasetModal" class="modal fade"> | |||
| <div class="modal-dialog"> | |||
| <div class="modal-content"> | |||
| <div class="modal-header"> | |||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||
| <h4 class="modal-title">导入标注属性</h4> | |||
| </div> | |||
| <div class="modal-body"> | |||
| <div class="form-group"> | |||
| <label id = "labelInfo" for="exampleInputFile">请输入符合格式Json字符串<font color=red>*</font> </label> | |||
| <div> | |||
| <textarea id="jsoninput" rows="8" cols="70"> </textarea> | |||
| </div> | |||
| </div> | |||
| <button id="btnSubmit" type="button" onclick="submit_import_property();">提交</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <script> | |||
| // back to label table | |||
| var back_url = sessionStorage.getItem('return_url') | |||
| document.getElementById('return_url').setAttribute('href',back_url); | |||
| var ulObj = document.getElementById('nav').getElementsByTagName('ul')[0]; | |||
| var divObj = document.getElementsByClassName('tabpannel'); | |||
| var liObj = document.getElementById('nav').getElementsByTagName('li') | |||
| ulObj.onclick = function(event){ | |||
| var ev = window.event || event; | |||
| var item = ev.srcElement || ev.target; | |||
| var id = item.getAttribute("id") | |||
| for (var i=0; i<divObj.length;i++){ | |||
| if(i == id){ | |||
| divObj[i].style.display = 'block' | |||
| liObj[i].classList.add('active') | |||
| } | |||
| else{ | |||
| divObj[i].style.display = 'none' | |||
| liObj[i].classList.remove('active') | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <script> | |||
| var box = document.getElementsByClassName("box1")[0]; //获取元素 | |||
| var x, y; //鼠标相对与div左边,上边的偏移 | |||
| var isDrop = false; //移动状态的判断鼠标按下才能移动 | |||
| box.onmousedown = function(e) { | |||
| var e = e || window.event; //要用event这个对象来获取鼠标的位置 | |||
| x = e.clientX - box.offsetLeft; | |||
| y = e.clientY - box.offsetTop; | |||
| isDrop = true; //设为true表示可以移动 | |||
| } | |||
| document.onmousemove = function(e) { | |||
| //是否为可移动状态 | |||
| if(isDrop) { | |||
| var e = e || window.event; | |||
| var moveX = e.clientX - x; //得到距离左边移动距离 | |||
| var moveY = e.clientY - y; //得到距离上边移动距离 | |||
| //可移动最大距离 | |||
| var maxX = document.documentElement.clientWidth - box.offsetWidth; | |||
| var maxY = document.documentElement.clientHeight - box.offsetHeight; | |||
| //范围限定 当移动的距离最小时取最大 移动的距离最大时取最小 | |||
| //范围限定方法一 | |||
| /*if(moveX < 0) { | |||
| moveX = 0 | |||
| } else if(moveX > maxX) { | |||
| moveX = maxX; | |||
| } | |||
| if(moveY < 0) { | |||
| moveY = 0; | |||
| } else if(moveY > maxY) { | |||
| moveY = maxY; | |||
| } */ | |||
| //范围限定方法二 | |||
| moveX=Math.min(maxX, Math.max(0,moveX)); | |||
| moveY=Math.min(maxY, Math.max(0,moveY)); | |||
| box.style.left = moveX + "px"; | |||
| box.style.top = moveY + "px"; | |||
| } else { | |||
| return; | |||
| } | |||
| } | |||
| document.onmouseup = function() { | |||
| isDrop = false; //设置为false不可移动 | |||
| } | |||
| </script> | |||
| <script src="/self/func.js" type="text/javascript"></script> | |||
| <!-- jQuery 2.0.2 --> | |||
| <!-- --> | |||
| <script src="/self/js/jquery.min.js" type="text/javascript"></script> | |||
| <script src="/self/js/jquery.mousewheel.js"></script> | |||
| <script src="/self/js/jquery.jscrollpane.js"></script> | |||
| <!-- Bootstrap --> | |||
| <script src="/self/js/bootstrap.min.js" type="text/javascript"></script> | |||
| <script src="/self/js/app.js" type="text/javascript" ></script> | |||
| <script src="/self/js/Director/labelingSelfDefine.js" type="text/javascript"></script> | |||
| <script src="/self/js/Director/detection.js" type="text/javascript" ></script> | |||
| <!-- <script src="../js/labelx.js"></script> --> | |||
| </body> | |||
| </html> | |||
| @@ -22,6 +22,7 @@ import ( | |||
| code_indexer "code.gitea.io/gitea/modules/indexer/code" | |||
| issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | |||
| stats_indexer "code.gitea.io/gitea/modules/indexer/stats" | |||
| "code.gitea.io/gitea/modules/labelmsg" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/markup" | |||
| "code.gitea.io/gitea/modules/markup/external" | |||
| @@ -63,6 +64,7 @@ func NewServices() { | |||
| _ = cache.NewContext() | |||
| notification.NewContext() | |||
| decompression.NewContext() | |||
| labelmsg.Init() | |||
| } | |||
| // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology | |||
| @@ -17,6 +17,7 @@ import ( | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/labelmsg" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/minio_ext" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| @@ -131,7 +132,19 @@ func DeleteAttachment(ctx *context.Context) { | |||
| ctx.Error(403) | |||
| return | |||
| } | |||
| err = models.DeleteAttachment(attach, false) | |||
| err = models.DeleteAttachment(attach, true) | |||
| if err != nil { | |||
| ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err)) | |||
| return | |||
| } | |||
| attachjson, _ := json.Marshal(attach) | |||
| labelmsg.SendDeleteAttachToLabelSys(string(attachjson)) | |||
| DeleteAllUnzipFile(attach, "") | |||
| _, err = models.DeleteFileChunkById(attach.UUID) | |||
| if err != nil { | |||
| ctx.Error(500, fmt.Sprintf("DeleteAttachment: %v", err)) | |||
| return | |||
| @@ -416,6 +429,21 @@ func UpdateAttachmentDecompressState(ctx *context.Context) { | |||
| log.Error("UpdateAttachment(%s) failed:%s", uuid, err.Error()) | |||
| return | |||
| } | |||
| log.Info("start to send msg to labelsystem ") | |||
| dataset, _ := models.GetDatasetByID(attach.DatasetID) | |||
| var labelMap map[string]string | |||
| labelMap = make(map[string]string) | |||
| labelMap["UUID"] = uuid | |||
| labelMap["Type"] = fmt.Sprint(attach.Type) | |||
| labelMap["UploaderID"] = fmt.Sprint(attach.UploaderID) | |||
| labelMap["RepoID"] = fmt.Sprint(dataset.RepoID) | |||
| labelMap["AttachName"] = attach.Name | |||
| attachjson, _ := json.Marshal(labelMap) | |||
| labelmsg.SendAddAttachToLabelSys(string(attachjson)) | |||
| log.Info("end to send msg to labelsystem ") | |||
| ctx.JSON(200, map[string]string{ | |||
| "result_code": "0", | |||
| @@ -738,8 +766,8 @@ func CompleteMultipart(ctx *context.Context) { | |||
| } | |||
| if attachment.DatasetID != 0 { | |||
| if typeCloudBrain == models.TypeCloudBrainOne { | |||
| if strings.HasSuffix(attachment.Name, ".zip") { | |||
| if strings.HasSuffix(attachment.Name, ".zip") { | |||
| if typeCloudBrain == models.TypeCloudBrainOne { | |||
| err = worker.SendDecompressTask(contexExt.Background(), uuid) | |||
| if err != nil { | |||
| log.Error("SendDecompressTask(%s) failed:%s", uuid, err.Error()) | |||
| @@ -751,6 +779,21 @@ func CompleteMultipart(ctx *context.Context) { | |||
| } | |||
| } | |||
| } | |||
| if typeCloudBrain == models.TypeCloudBrainTwo { | |||
| attachjson, _ := json.Marshal(attachment) | |||
| labelmsg.SendDecompressAttachToLabelOBS(string(attachjson)) | |||
| } | |||
| } else { | |||
| dataset, _ := models.GetDatasetByID(attachment.DatasetID) | |||
| var labelMap map[string]string | |||
| labelMap = make(map[string]string) | |||
| labelMap["UUID"] = uuid | |||
| labelMap["Type"] = fmt.Sprint(attachment.Type) | |||
| labelMap["UploaderID"] = fmt.Sprint(attachment.UploaderID) | |||
| labelMap["RepoID"] = fmt.Sprint(dataset.RepoID) | |||
| labelMap["AttachName"] = attachment.Name | |||
| attachjson, _ := json.Marshal(labelMap) | |||
| labelmsg.SendAddAttachToLabelSys(string(attachjson)) | |||
| } | |||
| } | |||
| @@ -1,13 +1,14 @@ | |||
| package repo | |||
| import ( | |||
| "sort" | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/auth" | |||
| "code.gitea.io/gitea/modules/base" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "sort" | |||
| ) | |||
| const ( | |||
| @@ -60,19 +61,62 @@ func newFilterPrivateAttachments(ctx *context.Context, list []*models.Attachment | |||
| } | |||
| } | |||
| func QueryDataSet(ctx *context.Context) []*models.Attachment { | |||
| repo := ctx.Repo.Repository | |||
| dataset, err := models.GetDatasetByRepo(repo) | |||
| if err != nil { | |||
| log.Error("zou not found dataset 1") | |||
| ctx.NotFound("GetDatasetByRepo", err) | |||
| return nil | |||
| } | |||
| if ctx.Query("type") == "" { | |||
| log.Error("zou not found type 2") | |||
| ctx.NotFound("type error", nil) | |||
| return nil | |||
| } | |||
| err = models.GetDatasetAttachments(ctx.QueryInt("type"), dataset) | |||
| if err != nil { | |||
| ctx.ServerError("GetDatasetAttachments", err) | |||
| return nil | |||
| } | |||
| attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | |||
| ctx.Data["SortType"] = ctx.Query("sort") | |||
| switch ctx.Query("sort") { | |||
| case "newest": | |||
| sort.Slice(attachments, func(i, j int) bool { | |||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||
| }) | |||
| case "oldest": | |||
| sort.Slice(attachments, func(i, j int) bool { | |||
| return attachments[i].CreatedUnix < attachments[j].CreatedUnix | |||
| }) | |||
| default: | |||
| ctx.Data["SortType"] = "newest" | |||
| sort.Slice(attachments, func(i, j int) bool { | |||
| return attachments[i].CreatedUnix > attachments[j].CreatedUnix | |||
| }) | |||
| } | |||
| return attachments | |||
| } | |||
| func DatasetIndex(ctx *context.Context) { | |||
| log.Info("dataset index 1") | |||
| MustEnableDataset(ctx) | |||
| repo := ctx.Repo.Repository | |||
| dataset, err := models.GetDatasetByRepo(repo) | |||
| if err != nil { | |||
| log.Error("query dataset, not found repo.") | |||
| ctx.NotFound("GetDatasetByRepo", err) | |||
| return | |||
| } | |||
| if ctx.Query("type") == "" { | |||
| log.Error("not found param type") | |||
| log.Error("query dataset, not found param type") | |||
| ctx.NotFound("type error", nil) | |||
| return | |||
| } | |||
| @@ -81,6 +125,7 @@ func DatasetIndex(ctx *context.Context) { | |||
| ctx.ServerError("GetDatasetAttachments", err) | |||
| return | |||
| } | |||
| attachments := newFilterPrivateAttachments(ctx, dataset.Attachments, repo) | |||
| ctx.Data["SortType"] = ctx.Query("sort") | |||
| @@ -3,15 +3,19 @@ package repo | |||
| import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "io/ioutil" | |||
| "net/http" | |||
| "path" | |||
| "strings" | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/base" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/obs" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| ) | |||
| const ( | |||
| @@ -32,6 +36,87 @@ type RespGetDirs struct { | |||
| FileInfos string `json:"fileInfos"` | |||
| } | |||
| func DeleteAllUnzipFile(attachment *models.Attachment, parentDir string) { | |||
| uuid := attachment.UUID | |||
| dirArray := strings.Split(parentDir, "/") | |||
| if !strings.HasSuffix(attachment.Name, ".zip") { | |||
| log.Error("The file is not zip file, can not query the dir") | |||
| return | |||
| } else if attachment.DecompressState != models.DecompressStateDone { | |||
| log.Error("The file has not been decompressed completely now") | |||
| return | |||
| } | |||
| dirArray = append([]string{attachment.Name}, dirArray...) | |||
| if parentDir == "" { | |||
| dirArray = []string{attachment.Name} | |||
| } | |||
| if attachment.Type == models.TypeCloudBrainOne { | |||
| dirs, err := GetDatasetDirs(uuid, parentDir) | |||
| if err != nil { | |||
| log.Error("getDatasetDirs failed:", err.Error()) | |||
| return | |||
| } | |||
| var fileInfos []FileInfo | |||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
| if err != nil { | |||
| log.Error("json.Unmarshal failed:", err.Error()) | |||
| return | |||
| } | |||
| for _, fileInfo := range fileInfos { | |||
| log.Info("fileName=" + fileInfo.FileName) | |||
| log.Info("parentDir=" + fileInfo.ParenDir) | |||
| if fileInfo.IsDir { | |||
| DeleteAllUnzipFile(attachment, fileInfo.FileName) | |||
| } else { | |||
| absolutepath := path.Join(attachment.RelativePath()+attachment.UUID, fileInfo.ParenDir) | |||
| log.Info("absolutepath=" + absolutepath) | |||
| storage.Attachments.Delete(absolutepath) | |||
| } | |||
| } | |||
| } | |||
| if attachment.Type == models.TypeCloudBrainTwo { | |||
| input := &obs.ListObjectsInput{} | |||
| input.Bucket = setting.Bucket | |||
| // 设置每页100个对象 | |||
| input.MaxKeys = 100 | |||
| input.Prefix = setting.BasePath + attachment.RelativePath() + attachment.UUID | |||
| index := 1 | |||
| log.Info("prefix=" + input.Prefix) | |||
| for { | |||
| output, err := storage.ObsCli.ListObjects(input) | |||
| if err == nil { | |||
| fmt.Printf("Page:%d\n", index) | |||
| index++ | |||
| for _, val := range output.Contents { | |||
| log.Info("delete obs file:" + val.Key) | |||
| delObj := &obs.DeleteObjectInput{} | |||
| delObj.Bucket = setting.Bucket | |||
| delObj.Key = val.Key | |||
| storage.ObsCli.DeleteObject(delObj) | |||
| } | |||
| if output.IsTruncated { | |||
| input.Marker = output.NextMarker | |||
| } else { | |||
| break | |||
| } | |||
| } else { | |||
| if obsError, ok := err.(obs.ObsError); ok { | |||
| fmt.Printf("Code:%s\n", obsError.Code) | |||
| fmt.Printf("Message:%s\n", obsError.Message) | |||
| } | |||
| break | |||
| } | |||
| } | |||
| } | |||
| } | |||
| func DirIndex(ctx *context.Context) { | |||
| uuid := ctx.Params("uuid") | |||
| parentDir := ctx.Query("parentDir") | |||
| @@ -58,30 +143,35 @@ func DirIndex(ctx *context.Context) { | |||
| dirArray = []string{attachment.Name} | |||
| } | |||
| dirs, err := getDatasetDirs(uuid, parentDir) | |||
| if err != nil { | |||
| log.Error("getDatasetDirs failed:", err.Error()) | |||
| ctx.ServerError("getDatasetDirs failed:", err) | |||
| return | |||
| } | |||
| var fileInfos []FileInfo | |||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
| if err != nil { | |||
| log.Error("json.Unmarshal failed:", err.Error()) | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return | |||
| } | |||
| /* | |||
| dirs, err := GetDatasetDirs(uuid, parentDir) | |||
| if err != nil { | |||
| log.Error("getDatasetDirs failed:", err.Error()) | |||
| ctx.ServerError("getDatasetDirs failed:", err) | |||
| return | |||
| } | |||
| */ | |||
| //var fileInfos []FileInfo | |||
| /* | |||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
| if err != nil { | |||
| log.Error("json.Unmarshal failed:", err.Error()) | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return | |||
| } | |||
| */ | |||
| ctx.Data["Path"] = dirArray | |||
| ctx.Data["Dirs"] = fileInfos | |||
| ctx.Data["Dirs"] = true | |||
| ctx.Data["Uuid"] = uuid | |||
| ctx.Data["PageIsDataset"] = true | |||
| ctx.HTML(200, tplDirIndex) | |||
| } | |||
| func getDatasetDirs(uuid string, parentDir string) (string, error) { | |||
| func GetDatasetDirs(uuid string, parentDir string) (string, error) { | |||
| var req string | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| @@ -0,0 +1,37 @@ | |||
| package repo | |||
| import ( | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/base" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| ) | |||
| const ( | |||
| tplLabelIndex base.TplName = "repo/datasets/label/index" | |||
| ) | |||
| func LabelIndex(ctx *context.Context) { | |||
| log.Info("Go Here LabelIndex.") | |||
| uuid := ctx.Params("uuid") | |||
| attach, err := models.GetAttachmentByUUID(uuid) | |||
| if err != nil { | |||
| log.Info("query attach error") | |||
| } else { | |||
| dataset, err := models.GetDatasetByID(attach.DatasetID) | |||
| if err != nil { | |||
| log.Info("query dataset error") | |||
| } else { | |||
| ctx.Data["repoId"] = dataset.RepoID | |||
| } | |||
| } | |||
| attachments := QueryDataSet(ctx) | |||
| ctx.Data["uuid"] = uuid | |||
| ctx.Data["Attachments"] = attachments | |||
| ctx.HTML(200, tplLabelIndex) | |||
| } | |||
| @@ -926,6 +926,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Group("/dirs", func() { | |||
| m.Get("/:uuid", reqRepoDatasetReader, repo.DirIndex) | |||
| }) | |||
| m.Group("/label", func() { | |||
| m.Get("/:uuid", reqRepoDatasetReader, repo.LabelIndex) | |||
| }) | |||
| }, context.RepoRef()) | |||
| m.Group("/cloudbrain", func() { | |||
| @@ -23,7 +23,11 @@ | |||
| </div> | |||
| <div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}"> | |||
| <a class="ui text center" href="datasets/dirs/{{.UUID}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a> | |||
| <a class="ui text center" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a> | |||
| </div> | |||
| <div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}"> | |||
| <a class="ui text center" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a> | |||
| </div> | |||
| {{if $.Permission.CanWrite $.UnitTypeDatasets}} | |||
| @@ -24,4 +24,15 @@ | |||
| </tbody> | |||
| </table> | |||
| <table id="dataset-files-table" class="ui single line table"> | |||
| </table> | |||
| <script src="{{StaticUrlPrefix}}/self/test.js"></script> | |||
| <script type="text/javascript"> | |||
| displayDir({{$.Uuid}}) | |||
| </script> | |||
| {{end}} | |||
| @@ -0,0 +1,212 @@ | |||
| {{if .Dirs}} | |||
| <style> | |||
| /* ul{ | |||
| display: flex;; | |||
| position: absolute; | |||
| list-style: none; | |||
| transform: translate(-50%,-50%); | |||
| } | |||
| li{ | |||
| position: relative; | |||
| padding: 20px; | |||
| color: #000; | |||
| line-height: 1; | |||
| transition: 0.2s all linear; | |||
| cursor: pointer; | |||
| } | |||
| li::before{ | |||
| content: ""; | |||
| position: absolute; | |||
| } */ | |||
| ul,li{ | |||
| list-style: none; | |||
| } | |||
| div#nav{ | |||
| border: 1px solid #ccc; | |||
| } | |||
| div#nav ul{ | |||
| border-bottom: 1px solid #ccc; | |||
| } | |||
| div#nav li{ | |||
| position: relative; | |||
| display: inline-block; | |||
| line-height: 3em; | |||
| text-align: center; | |||
| width: 50%; | |||
| cursor: pointer; | |||
| transition: 0.2s all linear; | |||
| } | |||
| div.hide{ | |||
| display: none; | |||
| } | |||
| div#nav li.active{ | |||
| color: rgba(0,0,0,.85); | |||
| font-weight: 700; | |||
| opacity: 1; | |||
| border-bottom: 2px solid rgba(0,0,0,.85); | |||
| transition: 0.2s all linear; | |||
| } | |||
| /* div#nav li::before{ | |||
| content: ""; | |||
| position: absolute; | |||
| top: 0; | |||
| left: 100%; | |||
| width: 0; | |||
| height: 100%; | |||
| border-bottom: 2px solid #f000; | |||
| transition: 0.2s all linear; | |||
| } | |||
| .active ~ li::before{ | |||
| left: 0; | |||
| } | |||
| .active::before{ | |||
| width: 100%; | |||
| left: 0; | |||
| top: 0; | |||
| } | |||
| .hover::before{ | |||
| width: 50%; | |||
| } */ | |||
| </style> | |||
| <div id="uuid_div" style="display: none"> | |||
| <input type="" value="{{$.Uuid}}" id="hide_uuidid" style="display:none;"> | |||
| </div> | |||
| <div id="myCanvas_div" style="width:100%;height:100% ; position: relative;"> | |||
| <!-- <div style="display:inline-block; width:6%;height: 100%; position: relative; vertical-align: middle;"> | |||
| <img src="/img/left_new_new.png" onclick="clickLast()" style="margin-left: 15px" /> | |||
| </div> --> | |||
| <div style="display:inline-block; width:71%; height: 100%; position: relative;border: 1px solid #ccc;border-radius: 6px;"> | |||
| <!-- <div style="text-align:center"> | |||
| <a> | |||
| 文件名: | |||
| <span id="filename"></span> | |||
| </a> | |||
| </div> --> | |||
| <div id="win_canvas" style="width:100%;height:42em"> | |||
| <canvas id="myCanvas" style="display:none;"> | |||
| </canvas> | |||
| <code id="textcontent" style="display:none;overflow: auto;">这是一个测试。</code> | |||
| <div style="padding:0.2em 0;position: absolute;border-top: 1px solid #ccc;width: 100%;bottom:0;font-size: 1em;padding: 0.5em 1em;"> | |||
| <div id="breadFile" class="ui small breadcrumb"> | |||
| <!-- <div class="section">Home</div> | |||
| <div class="divider"> / </div> | |||
| <div class="active section">Search</div> --> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div style="font-size: 1.5rem; opacity: 0.7; position: absolute;left: 0.5rem;top: 20rem;cursor: pointer;" onclick="clickLast()"><i class="chevron circle left icon" ></i></div> | |||
| <div style="font-size: 1.5rem; opacity: 0.7; position: absolute;right: 0.5rem;top: 20rem;cursor: pointer;" onclick="clickNext()"><i class="chevron circle right icon" ></i></div> | |||
| </div> | |||
| <!-- <div style="display:inline-block; width:6%;height: 100%; position: relative; vertical-align: middle;"> | |||
| <img src="/img/right_new_new.png" onclick="clickNext()" style="margin-left: 15px"/> | |||
| </div> --> | |||
| <div id="nav" style="display:inline-block; width:25%;height: 100%; position: relative;vertical-align: top; background: #ffffff;margin-left: 20px;border-radius: 6px;"> | |||
| <ul style="display: flex;padding: 0;margin: 0;"> | |||
| <li id="0" class="active">文件列表</li> | |||
| <li id="1">标签列表</li> | |||
| </ul> | |||
| <div class="tabpannel"> | |||
| <!-- <h4 class="ui top attached header"> | |||
| 文件列表 | |||
| </h4> --> | |||
| <!-- <table class="ui single line table" id="filelist" style="table-layout:fixed;word-break: break-all;word-wrap: break-word;"> | |||
| </table> --> | |||
| <div class="ui list" id="filelist"></div> | |||
| <div class="panel-body" id="filepanel" style='position: absolute;bottom: 0;padding: 0.9em 0;width: 100%;border-top: 1px #ccc solid;'> | |||
| <div style="width: 90%; margin: 0 auto;"> | |||
| <a id="prePage" href="" style="margin-right: 0.2em;color: #000;"><i class="angle left icon"></i></a> | |||
| <span id="startIndex">0</span>-<span id="endIndex">0</span>/<span id="totalNum">0</span> | |||
| <span style="margin-left: 0.2em;">第</span><span id="displayPage1">1</span><span style="margin-right: 0.2em;">页</span> | |||
| <span>跳到</span><input type="text" id="goNum" style="width: 2em;border-radius: 4px;padding: 0 0.4em;margin: 0 0.4em;height: 1.2em;border: 1px solid;" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><span>页</span> | |||
| <a style="margin-left: 0.4em;color: #000;" id="nextPage" href=""><i class="angle right icon"></i></a> | |||
| <!-- 第<span id="startIndex">0</span>至<span id="endIndex">0</span>条, 共<span id="totalNum">0</span>条. | |||
| <span > | |||
| <span > | |||
| 当前页:<span id="displayPage1">1</span> | |||
| </span> | |||
| <a id="nextPage" href="">下一页</a> | |||
| <span> | |||
| 共<span id="totalPageNum"></span>页 | |||
| </span> | |||
| </span> | |||
| <span> 跳转至:<input type="text" id="goNum" style="width: 50px;border-radius: 6px" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><a id="goHref" href="javascript:goPage()"> GO</a></span> --> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="hide tabpannel"> | |||
| <div style="margin-top: 1em;" id="labellist"> | |||
| </div> | |||
| </div> | |||
| <!-- <div class="ui pointing secondary menu"> | |||
| <a class="item " data-tab="first">First</a> | |||
| <a class="item active" data-tab="second">Second</a> | |||
| </div> | |||
| <div class="ui bottom attached tab segment active" data-tab="first"> | |||
| First | |||
| </div> | |||
| <div class="ui bottom attached tab segment" data-tab="second"> | |||
| Second | |||
| </div> | |||
| --> | |||
| </div> | |||
| </div> | |||
| <script> | |||
| var ulObj = document.getElementById('nav').getElementsByTagName('ul')[0]; | |||
| var divObj = document.getElementsByClassName('tabpannel'); | |||
| var liObj = document.getElementById('nav').getElementsByTagName('li') | |||
| ulObj.onclick = function(event){ | |||
| var ev = window.event || event; | |||
| var item = ev.srcElement || ev.target; | |||
| var id = item.getAttribute("id") | |||
| for (var i=0; i<divObj.length;i++){ | |||
| if(i == id){ | |||
| divObj[i].style.display = 'block' | |||
| liObj[i].classList.add('active') | |||
| } | |||
| else{ | |||
| divObj[i].style.display = 'none' | |||
| liObj[i].classList.remove('active') | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <script src="{{StaticUrlPrefix}}/self/dataset_preview.js"></script> | |||
| {{end}} | |||
| @@ -1,29 +1,35 @@ | |||
| {{template "base/head" .}} | |||
| <div class="repository dataset dir-list view"> | |||
| {{template "repo/header" .}} | |||
| <form class="ui container"> | |||
| <div class="ui stackable grid {{if .Error}}hide{{end}}" id="dir-content"> | |||
| <div class="row"> | |||
| <div class="column sixteen wide"> | |||
| <p> | |||
| {{ range $index, $item := .Path }}<a href='{{$.Link}}/?parentDir={{if gt $index 0}}{{DatasetPathJoin $.Path $index "/"}}{{else}}{{end}}'>{{ $item }}</a><span class="directory-seperator">/</span>{{ end }} | |||
| </p> | |||
| <div style="background:#fff"> | |||
| {{template "base/head" .}} | |||
| <div class="repository dataset dir-list view"> | |||
| {{template "repo/header" .}} | |||
| <div> | |||
| <form class="ui container"> | |||
| <div class="ui stackable grid {{if .Error}}hide{{end}}" id="dir-content"> | |||
| <div class="row"> | |||
| <div class="column sixteen wide"> | |||
| <div class="ui breadcrumb"> | |||
| {{ range $index, $item := .Path }}<a class="section" href='{{$.Link}}/?parentDir={{if gt $index 0}}{{DatasetPathJoin $.Path $index "/"}}{{else}}{{end}}'>{{ $item }}</a><div class="divider"> / </div>{{ end }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="ui grid"> | |||
| <div class="row"> | |||
| <div class="ui sixteen wide column"> | |||
| <div class="dir list"> | |||
| {{template "repo/datasets/dirs/dir_list" .}} | |||
| <div class="ui grid"> | |||
| <div class="row" style="padding-top: 0.5rem;padding-bottom: 0;"> | |||
| <div class="ui sixteen wide column"> | |||
| <div class="dir list"> | |||
| {{template "repo/datasets/dirs/dir_preview" .}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -0,0 +1,209 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| #progress{ | |||
| width: 100%; | |||
| height: 20px; | |||
| background: rgb(255, 255, 255); | |||
| } | |||
| #bar{ | |||
| width: 1%; | |||
| height: 20px; | |||
| margin-top: 1px; | |||
| background: green; | |||
| } | |||
| </style> | |||
| <div class="repository dataset dir-list view"> | |||
| {{template "repo/header" .}} | |||
| <input type="hidden" id="repoId" value="{{.repoId}}"> | |||
| <div class="ui container"> | |||
| <div class="header"> | |||
| <h3 class="modal-title">人工标注任务列表</h3> | |||
| </div> | |||
| <div class="ui container"> | |||
| <div class="ui container"> | |||
| <table class="ui celled table" id="label_task_list"></table> | |||
| <div class="ui container" style="height: 30px;"> | |||
| <div style="float:right"> | |||
| 显示<span id="startIndex">0</span>到<span id="endIndex">0</span>条,共<span id="totalNum">0</span>条。 | |||
| <span > | |||
| <a id="prePage" href=""><b>上一页</b></a> | |||
| <span > | |||
| 当前页:<span id="displayPage1">1</span> | |||
| </span> | |||
| <a id="nextPage" href=""><b>下一页</b></a> | |||
| <span> | |||
| 共<span id="totalPageNum"></span>页 | |||
| </span> | |||
| <span> 跳转到:<input type="text" id="goNum" style="width: 50px;border-radius:6px" maxlength="5" oninput="value=value.replace(/[^\d]/g,'')"><a id="goHref" href="javascript:goPage()"> GO</a></span> | |||
| </span> | |||
| </div> | |||
| </div> | |||
| <div class="ui container" style="height: 30px;"> | |||
| <!-- <button type="button" onclick="setPredictTask();" class="ui blue button" style="float:left">新建自动标注结果图片标注</button> --> | |||
| <button type="button" onclick="setDataSetTask();" class="ui blue button" style="float:left">新建数据集图片标注</button> | |||
| <button type="button" onclick="setMultiTaskId();" class="ui blue button" style="float:right;margin-left:20px;">导出标注数据</button> | |||
| <button type="button" onclick="countLabel();" class="ui blue button" style="float:right;margin-left:20px;">统计所有标注数量</button> | |||
| <button type="button" onclick="delete_labeltask();" class="ui blue button" style="float:right">删除人工标注</button> | |||
| </div> | |||
| <!-- 增加新建数据集人工标注--> | |||
| <div id="labelDataModal" class="ui dataset modal"> | |||
| <i class="close icon"></i> | |||
| <div class="header"> | |||
| <h4 class="modal-title">新建数据集图片标注</h4> | |||
| </div> | |||
| <div class="content"> | |||
| <div class="ui form"> | |||
| <div class="field"> | |||
| <label for="exampleInputPassword1">选择数据集对象<font color=red>*</font></label> | |||
| <select name="pre_predict_task" id="dataset_list" onchange="dataset_sele_Change(this)"> | |||
| <option value="" selected="">请选择</option> | |||
| </select> | |||
| </div> | |||
| <div class="field" > | |||
| <label for="exampleInputEmail1">人工标注任务名称<font color=red>*</font></label> | |||
| <input type="text" id="datasetlabeltaskname" placeholder="标注任务名称,不超过32个字符"> | |||
| </div> | |||
| <div class="field" style="display:none"> | |||
| <label for="exampleInputEmail2">任务指派给</label> | |||
| <select name="任务指派给" id="assign_user"> | |||
| <option value="">请选择</option> | |||
| </select> | |||
| </div> | |||
| <div class="field" > | |||
| <label for="exampleInputEmail2">模式</label> | |||
| <select name="模式" id="task_flow_type" onchange="flow_type_sele_Change(this)"> | |||
| <option value="1" select="true"> 标注工作模式</option> | |||
| <!-- <option value="2"> 标注审核模式</option> | |||
| <option value="3"> 主动分类学习模式</option> --> | |||
| </select> | |||
| </div> | |||
| <div class="field" style="display:none"> | |||
| <label id = "labelInfo" for="exampleInputFile">标注类别(也可以直接在标注界面上进行设置)</label> | |||
| <select name="labelpropertytask" id="labelpropertytask_dataset" > | |||
| <option value="" selected="">请选择</option> | |||
| </select> | |||
| </div> | |||
| <button type="button" onclick="submit_datasettask();">提交</button> | |||
| </div> | |||
| </div> | |||
| </div> <!-- /.box-body --> | |||
| <div id="labelModal" class="ui predict modal"> | |||
| <div class="modal-dialog"> | |||
| <div class="modal-content"> | |||
| <div class="modal-header"> | |||
| <button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button> | |||
| <h4 class="modal-title">新建自动标注结果人工标注</h4> | |||
| </div> | |||
| <div class="modal-body"> | |||
| <div class="form-group"> | |||
| <label for="exampleInputPassword1">关联的自动标注任务<font color=red>*</font></label> | |||
| <select class="form-control" name="pre_predict_task" id="pre_predict_task_for_label" onchange="sele_Change(this)"> | |||
| <option value="" selected="">请选择</option> | |||
| </select> | |||
| <!-- <input type="" class="form-control" id="prepredtaskid" placeholder="预检任务"> --> | |||
| </div> | |||
| <div class="form-group" > | |||
| <label for="exampleInputEmail2">任务指派给</label> | |||
| <select class="form-control" name="任务指派给" id="label_assign_user"> | |||
| <option value=""> 请选择</option> | |||
| </select> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label for="exampleInputEmail1">人工标注任务名称<font color=red>*</font></label> | |||
| <input type="" class="form-control" id="labeltaskname" placeholder="校验标注任务名称,不超过32个字符" maxlength="32"> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label id = "labelInfo" for="exampleInputFile">标注类别属性,请输入符合格式Json字符串 </label> | |||
| <select class="form-control" name="labelpropertytask" id="labelpropertytask_auto"> | |||
| <option value="" selected="">请选择</option> | |||
| </select> | |||
| </div> | |||
| <button type="button" onclick="submit_labeltask();">提交</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> <!-- /.box-body --> | |||
| <div id="labeltaskexport" class="ui export modal"> | |||
| <i class="close icon"></i> | |||
| <div class="header"> | |||
| <h4 class="modal-title">导出标注数据</h4> | |||
| </div> | |||
| <div class="content"> | |||
| <div class="ui form"> | |||
| <input type="" value="" id="hide_labeltaskid" style="display:none;"> | |||
| <div class="field"> | |||
| <label for="exampleInputPassword1">是否带图片导出<font color=red>*</font></label> | |||
| <select class="form-control" name="是否带图片导出" id="isNeedPicture" onchange="sele_export_Change(this)"> | |||
| <option value="1" selected="">不带图片导出</option> | |||
| <option value="2">带图片导出</option> | |||
| <option value="3">导出所有标注抠图</option> | |||
| </select> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="exampleInputPassword1">选择标注导出格式<font color=red>*</font></label> | |||
| <select class="form-control" id="exportFormat"> | |||
| <option value="1" selected="">COCO</option> | |||
| <option value="2">VOC</option> | |||
| </select> | |||
| </div> | |||
| <div class="field" id="maxscore_div" style="display:none;"> | |||
| <label for="exampleInputEmail1">标注得分最大值(0--1.0),目标检测得分大于此值时,不导出</label> | |||
| <input type="" class="form-control" id="maxscore" placeholder="标注得分最大值(0--1.0),当目标检测得分大于此值时,不导出。" maxlength="10"> | |||
| </div> | |||
| <div class="field" id="minscore_div" style="display:none;"> | |||
| <label for="exampleInputEmail1">标注得分最小值(0--0.99),目标检测得分小于此值时,不导出</label> | |||
| <input type="" class="form-control" id="minscore" placeholder="标注得分最小值(0--0.99),当目标检测得分小于此值时,不导出。" maxlength="10"> | |||
| </div> | |||
| <div class="field" id="progress"> | |||
| <div id="bar"></div> | |||
| </div> | |||
| <div class="field"><h5 id="text-progress">0%</h3></div> | |||
| <div class="field"> | |||
| <button id="predtask_id" type="button" class="btn btn-default" onclick="downloadFile();">提交</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div><!-- /.box-body --> | |||
| </div> | |||
| <!-- </div> --> | |||
| </div><!-- /.box --> | |||
| </div> | |||
| <script src="/self/labelTaskPage.js"></script> | |||
| {{template "base/footer" .}} | |||