添加任务建议

- 新增 `/task_suggestions` 路由,用于获取任务建议
- 添加任务建议的下拉菜单和搜索按钮
- 实现前端逻辑,支持根据任务名称搜索建议并显示结果
This commit is contained in:
Cp0204 2024-12-12 16:43:10 +08:00
parent 2687de5428
commit f1db510957
2 changed files with 83 additions and 7 deletions

View File

@ -15,8 +15,10 @@ from flask import (
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.cron import CronTrigger
import subprocess import subprocess
import requests
import hashlib import hashlib
import logging import logging
import base64
import json import json
import sys import sys
import os import os
@ -139,7 +141,9 @@ def logout():
def index(): def index():
if not is_login(): if not is_login():
return redirect(url_for("login")) return redirect(url_for("login"))
return render_template("index.html", version=app.config["APP_VERSION"], plugin_flags=PLUGIN_FLAGS) return render_template(
"index.html", version=app.config["APP_VERSION"], plugin_flags=PLUGIN_FLAGS
)
# 获取配置数据 # 获取配置数据
@ -212,6 +216,21 @@ def run_script_now():
) )
@app.route("/task_suggestions")
def get_task_suggestions():
if not is_login():
return jsonify({"error": "未登录"})
base_url = base64.b64decode("aHR0cHM6Ly9zLjkxNzc4OC54eXo=").decode()
query = request.args.get("q", "").lower()
deep = request.args.get("d", "").lower()
url = f"{base_url}/task_suggestions?q={query}&d={deep}"
try:
response = requests.get(url)
return jsonify(response.json())
except Exception as e:
return jsonify({"error": str(e)})
@app.route("/get_share_detail") @app.route("/get_share_detail")
def get_share_files(): def get_share_files():
if not is_login(): if not is_login():

View File

@ -176,10 +176,23 @@
<label class="col-sm-2 col-form-label">任务名称</label> <label class="col-sm-2 col-form-label">任务名称</label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="input-group"> <div class="input-group">
<input type="text" name="taskname[]" class="form-control" v-model="task.taskname" placeholder="必填" @focus="focusTaskname(index, task)" @input="changeTaskname(task)"> <input type="text" name="taskname[]" class="form-control" v-model="task.taskname" placeholder="必填" @focus="smart_param.showSuggestions=true;focusTaskname(index, task)" @input="changeTaskname(index, task)">
<div class="input-group-append" v-if="task.taskname"> <div class="dropdown-menu" :class="{'show': smart_param.showSuggestions && smart_param.taskSuggestions.length && smart_param.index === index}" style="width: 100%; max-height: 500px; overflow-y: auto;">
<div class="text-muted text-center" style="font-size: small;">以下资源来自第三方,网络公开搜集,请自行辨识,如有侵权请联系夸克官方</div>
<div v-for="suggestion in smart_param.taskSuggestions" :key="suggestion.taskname" class="dropdown-item" @click.prevent="selectSuggestion(task, suggestion)" style="cursor: pointer;">
<span v-html="suggestion.verify ? '✅': '❔'"></span> {{ suggestion.taskname }}
<small class="text-muted">
<a :href="suggestion.shareurl" target="_blank" @click.stop>{{ suggestion.shareurl }}</a>
</small>
</div>
</div>
<div class="input-group-append">
<button class="btn btn-primary" type="button" @click="searchSuggestions(index, task.taskname)">
<i v-if="smart_param.isSearching && smart_param.index === index" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></i>
<i v-else class="bi bi-search-heart"></i>
</button>
<div class="input-group-text"> <div class="input-group-text">
<a target="_blank" :href="`https://www.google.com/search?q=%22pan.quark%22+${task.taskname}`"><i class="bi bi-search"></i></a> <a target="_blank" :href="`https://www.google.com/search?q=%22pan.quark.cn/s%22+${task.taskname}`"><i class="bi bi-google"></i></a>
</div> </div>
</div> </div>
</div> </div>
@ -413,6 +426,10 @@
index: null, index: null,
savepath: "", savepath: "",
origin_savepath: "", origin_savepath: "",
taskSuggestions: [],
showSuggestions: false,
lastSuggestionsTime: 0,
isSearching: false,
}, },
}, },
filters: { filters: {
@ -436,6 +453,11 @@
this.checkNewVersion(); this.checkNewVersion();
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
document.addEventListener('keydown', this.handleKeyDown); document.addEventListener('keydown', this.handleKeyDown);
document.addEventListener('click', (e) => {
if (!e.target.closest('.input-group')) {
this.smart_param.showSuggestions = false;
}
});
}, },
methods: { methods: {
checkNewVersion() { checkNewVersion() {
@ -537,7 +559,7 @@
focusTaskname(index, task) { focusTaskname(index, task) {
this.smart_param.index = index this.smart_param.index = index
this.smart_param.origin_savepath = task.savepath this.smart_param.origin_savepath = task.savepath
regex = new RegExp(`/${task.taskname}(/|$)`) regex = new RegExp(`/${task.taskname.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(/|$)`)
if (task.savepath.includes('TASKNAME')) { if (task.savepath.includes('TASKNAME')) {
this.smart_param.savepath = task.savepath; this.smart_param.savepath = task.savepath;
} else if (task.savepath.match(regex)) { } else if (task.savepath.match(regex)) {
@ -546,7 +568,8 @@
this.smart_param.savepath = undefined; this.smart_param.savepath = undefined;
} }
}, },
changeTaskname(task) { changeTaskname(index, task) {
this.searchSuggestions(index, task.taskname, 500);
if (this.smart_param.savepath) if (this.smart_param.savepath)
task.savepath = this.smart_param.savepath.replace('TASKNAME', task.taskname); task.savepath = this.smart_param.savepath.replace('TASKNAME', task.taskname);
}, },
@ -690,7 +713,41 @@
} else { } else {
task.runweek = [1, 2, 3, 4, 5, 6, 7]; task.runweek = [1, 2, 3, 4, 5, 6, 7];
} }
},
searchSuggestions(index, taskname, limit_msec = 0) {
if (taskname.length == 0)
return
if (limit_msec > 0) {
const now = Date.now();
if (now - this.smart_param.lastSuggestionsTime < limit_msec)
return;
this.smart_param.lastSuggestionsTime = now;
} }
this.smart_param.isSearching = true
axios.get('/task_suggestions', {
params: {
q: taskname,
d: limit_msec == 0 ? 1 : 0
}
}).then(response => {
this.smart_param.taskSuggestions = response.data;
this.smart_param.index = index;
this.showSuggestions = true;
}).catch(error => {
console.error('Error fetching suggestions:', error);
}).finally(() => {
this.smart_param.isSearching = false;
});
},
selectSuggestion(task, suggestion) {
task.taskname = suggestion.taskname;
task.shareurl = suggestion.shareurl;
if (this.smart_param.savepath)
task.savepath = this.smart_param.savepath.replace('TASKNAME', task.taskname);
this.changeShareurl(task);
this.smart_param.showSuggestions = false;
this.smart_param.index = null;
},
} }
}); });
</script> </script>