后台获取数据. 获取内容完成. TODO: 注册型客户端.

This commit is contained in:
eson 2020-11-19 15:32:43 +08:00
parent 93b9303ee1
commit 5864a2645f
16 changed files with 131 additions and 73 deletions

View File

@ -1 +1 @@
google-chrome --pack-extension=./myblock --pack-extension-key=./myblock.pem
google-chrome --pack-extension=./chromeproxy --pack-extension-key=./chromeproxy.pem

View File

@ -9,7 +9,7 @@
"name": "Chrome Extension debugging",
"port": 9222,
"type": "chrome",
"url": "https://www.baidu.com",
"url": "http:/localhost:7123",
"webRoot": "${workspaceFolder}"
}
]

View File

@ -3,14 +3,13 @@ var task_manager = {
}
function GetRemoteTask(sender) {
fetch(TaskUrl).then(function (response) {
function GetTask(sender) {
fetch(GetTaskUrl).then(function (response) {
if (response.ok) {
response.json().then(function (value) {
// console.log(value);
if(value.code == 200) {
task_manager[sender.tab.id] ;
chrome.tabs.executeScript(sender.tab.id, {runAt: "document_end", code: `window.location.href = "${value.data.url}"` }, function (results) {
response.json().then(function (task) {
if(task.code == 200) {
task_manager[sender.tab.id] = task;
chrome.tabs.executeScript(sender.tab.id, {runAt: "document_end", code: `window.location.href = "${task.data.url}"` }, function (results) {
})
Tell(sender, InjectMsgType.FETCH);
} else {
@ -25,23 +24,54 @@ function GetRemoteTask(sender) {
})
}
function FinishTask(sender, content) {
var task = task_manager[sender.tab.id];
var formdata = new FormData();
formdata.append("taskid", task.data.taskid);
formdata.append("content", content);
fetch(FinishTaskUrl, {method: "POST", body: formdata }).then(function (response) {
if (response.ok) {
response.json().then(function (value) {
if (value.code == 200) {
GetTask(sender);
return
}
});
}
}).catch(function(error){
// TODO: 汇报错误
GetTask(sender);
return;
});
}
function ErrorTask(sender, error) {
var task = task_manager[sender.tab.id];
var formdata = new FormData();
formdata.append("taskid", task.data.taskid);
formdata.append("error", error);
fetch(ErrorTaskUrl, {method: "POST", body: formdata});
}
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
// console.log(request);
sendResponse({});
console.log(request, sender); // 利用sender tab id 返回正确的任务id
// console.log(request, sender); // 利用sender tab id 返回正确的任务id
switch (request.type) {
case BackgroundMsgType.CONTENT:
// TODO: 按照task id返回 拿到的内容
// 重新获取任务
GetRemoteTask(sender);
FinishTask(sender, request.content);
break;
case BackgroundMsgType.ERROR:
// TODO: 按照task id返回 错误
// 重新获取任务
GetRemoteTask(sender);
ErrorTask(sender, request.error)
GetTask(sender);
break;
case BackgroundMsgType.GETTASK:
GetRemoteTask(sender);
GetTask(sender);
break;
case BackgroundMsgType.NOTWANT:
Tell(sender,InjectMsgType.WAIT);
@ -49,8 +79,6 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
default:
break;
}
// sendResponse({type: MsgType.NEWURL, url: "https://playerduo.com/api/playerDuo-service-v2/rip113?lang=en&deviceType=browser"});
// GetRemoteTask(sender);
});
function Tell(sender, jnjectType) {
@ -61,18 +89,11 @@ function Tell(sender, jnjectType) {
}
}
// 配置使用的监听
chrome.webRequest.onBeforeRequest.addListener(function (details) {
if (details.url.startsWith("http://eson.config")) {
var params = new URLSearchParams(details.url)
TaskUrl = params.get("taskurl");
GetTaskUrl = params.get("taskurl");
chrome.tabs.remove(details.tabId, function () { });
return { cancel: true };
}

View File

@ -1,6 +1,11 @@
var TaskUrl = "http://localhost:7123/task/get";
const TaskIDKey = "chrome_proxy_tid_key"
var Host = "http://localhost:7123"
var GetTaskUrl = `${Host}/task/get`;
var FinishTaskUrl = `${Host}/task/content`;
var ErrorTaskUrl = `${Host}/task/error`;
const TaskIDKey = "chrome_proxy_tid_key";
const BackgroundMsgType = {
NOTWANT: 'notwant',
@ -9,7 +14,7 @@ const BackgroundMsgType = {
TIMEOUT: 'timeout',
ERROR: 'error',
OK: 'ok',
}
};
const InjectMsgType = {
FETCH: 'fetch',
@ -17,4 +22,4 @@ const InjectMsgType = {
ERROR: 'error',
NOTASK: 'notask',
OK: 'ok',
}
};

View File

@ -19,23 +19,16 @@ chrome.runtime.onMessage.addListener(function (request) {
break;
default:
break;
}
// chrome.runtime.onMessage.removeListener(assignTextToTextareas); //optional
};
});
if(typeof chrome.app.isInstalled != undefined){
var href = window.location.href;
var content = document.documentElement.innerHTML;
if (href.startsWith("https://playerduo.com") && content.startsWith('<head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">')) {
// SendContent();
Tell(BackgroundMsgType.CONTENT, content);
} else {
// NotWant()
Tell(BackgroundMsgType.NOTWANT, content)
}
var href = window.location.href;
var content = document.documentElement.innerHTML;
if (href.startsWith("https://playerduo.com") && content.startsWith('<head></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">')) {
Tell(BackgroundMsgType.CONTENT, content);
} else {
console.log(chrome.app);
Tell(BackgroundMsgType.NOTWANT, content);
}
function Tell(backgroundType, content) {

View File

Before

(image error) Size: 25 KiB

After

(image error) Size: 25 KiB

View File

Before

(image error) Size: 1.2 KiB

After

(image error) Size: 1.2 KiB

View File

Before

(image error) Size: 2.8 KiB

After

(image error) Size: 2.8 KiB

View File

Before

(image error) Size: 5.1 KiB

After

(image error) Size: 5.1 KiB

View File

Before

(image error) Size: 8.1 KiB

After

(image error) Size: 8.1 KiB

View File

@ -5,16 +5,16 @@ go 1.15
require (
github.com/474420502/focus v0.12.0
github.com/bwmarrin/snowflake v0.3.0
github.com/davecgh/go-spew v1.1.1
github.com/gin-gonic/gin v1.6.3
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/google/uuid v1.1.2
github.com/json-iterator/go v1.1.10 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/ugorji/go v1.2.0 // indirect
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba // indirect
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 // indirect
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7 // indirect
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)

View File

@ -16,6 +16,7 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -43,10 +44,9 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
@ -63,10 +63,12 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@ -79,8 +81,8 @@ github.com/ugorji/go/codec v1.2.0/go.mod h1:dXvG35r7zTX6QImXOSFhGMmKtX+wJ7VTWzGv
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU=
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 h1:phUcVbl53swtrUN8kQEXFhUxPlIlWyBfKmidCu7P95o=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -97,10 +99,12 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba h1:xmhUJGQGbxlod18iJGqVEp9cHIPLl7QiX2aA3to708s=
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7 h1:Z991aAXPjz0tLnj74pVXW3eWJ5lHMIBvbRfMq4M2jHA=
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -108,6 +112,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -128,6 +133,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=

View File

@ -34,5 +34,5 @@ func (op *Oplog) Write(data interface{}) {
op.oplog.Println(string(data))
return
}
log.Println("data must gin.H: ", data)
log.Println("data must Task: ", data)
}

View File

@ -1,7 +1,6 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
@ -15,21 +14,28 @@ import (
var taskQueue = NewQueue()
var waitQueue = NewQueue()
var readyQueue = NewQueue()
var errorQueue = NewQueue()
var snowNode *snowflake.Node
func initSnowflake() {
if snowNode == nil {
node, err := snowflake.NewNode(1)
if err != nil {
panic(err)
}
snowNode = node
}
}
func init() {
log.SetFlags(log.Llongfile | log.LstdFlags)
initOplog()
// Create a new Node with a Node number of 1
node, err := snowflake.NewNode(1)
if err != nil {
panic(err)
}
snowNode = node
initSnowflake()
engine.GET("/", func(c *gin.Context) {
c.JSON(200, Response{Code: 200, Message: "", Data: nil})
c.JSON(200, Response{Code: 200, Message: "Home Page"})
})
task := engine.Group("/task")
@ -37,13 +43,19 @@ func init() {
task.POST("/put", PutTask)
task.POST("/content", ContentTask)
task.POST("/error", ErrorTask)
task.GET("/ready", ReadyTask)
task.POST("/ack", AckTask)
}
// GetTask 获取当前一条任务列表
func GetTask(c *gin.Context) {
if result, ok := taskQueue.Pop(); ok {
c.JSON(http.StatusOK, Response{Code: 200, Message: "", Data: result})
if itask, ok := taskQueue.Pop(); ok {
task := itask.(*Task)
waitQueue.Push(task.data["taskid"], task)
c.JSON(http.StatusOK, Response{Code: 200, Message: "", Data: task})
return
}
c.JSON(http.StatusOK, Response{Code: 204, Message: "No Task"})
@ -73,25 +85,31 @@ func PutTask(c *gin.Context) {
// ContentTask 把一条任务放入队列
func ContentTask(c *gin.Context) {
r := c.PostForm("response")
response := &Response{}
json.Unmarshal([]byte(r), response)
if response.Code == 200 {
data := response.Data.(gin.H)
tid := data["taskid"]
if iv, ok := waitQueue.Remove(tid); ok {
var err error
tid, ok := c.GetPostForm("taskid")
if !ok {
c.JSON(http.StatusOK, Response{Code: 404, Message: "taskid is not set"})
}
if iv, ok := waitQueue.Remove(tid); ok {
if content, ok := c.GetPostForm("content"); ok {
task := iv.(*Task)
task.Store("content", data["content"])
task.Store("content", content)
task.Store("is_read", "false")
task.Store("status", "ready")
readyQueue.Push(tid, task) // 进入回调发送队列.TODO: 内容持久化
c.JSON(200, Response{Code: 200, Data: task})
return
}
}
c.JSON(200, Response{Code: 404, Message: fmt.Sprintln("response: ", err)})
}
// AckTask 确认整个任务流程完成.
func AckTask(c *gin.Context) {
tid := c.Query("taskid")
tid := c.PostForm("taskid")
if tid != "" {
if itask, ok := readyQueue.Get(tid); ok {
task := itask.(*Task)
@ -112,7 +130,7 @@ func AckTask(c *gin.Context) {
c.JSON(http.StatusOK, Response{Code: 404, Message: fmt.Sprintf("taskid: %s is not found", tid)})
}
// ReadyTask 把一条任务放入队列
// ReadyTask 已完成的任务. 读取期间为readying状态.
func ReadyTask(c *gin.Context) {
tid := c.Query("taskid")
if tid != "" {
@ -128,3 +146,18 @@ func ReadyTask(c *gin.Context) {
}
c.JSON(http.StatusOK, Response{Code: 404, Message: fmt.Sprintf("taskid: %s is not found", tid)})
}
// ErrorTask 任务错误无法完成
func ErrorTask(c *gin.Context) {
tid := c.PostForm("taskid")
errorStr := c.PostForm("error")
if itask, ok := waitQueue.Remove(tid); ok {
task := itask.(*Task)
task.Store("error", errorStr)
errorQueue.Push(tid, task) // 进入回调发送队列.TODO: 内容持久化
c.JSON(http.StatusOK, Response{Code: 200})
return
}
c.JSON(http.StatusOK, Response{Code: 404})
return
}