579 lines
18 KiB
Vue
579 lines
18 KiB
Vue
<template>
|
||
<el-drawer class="DashBoard" v-model="store.state.isShowHistory" size="90%" direction="ltr">
|
||
<span>E站额度本周已用:{{weekUsed.weekUsedAmount}} <br>上次重置时间:{{weekUsed.lastResetAmountTime}}</span><br>
|
||
<el-button @click="queryWeekUsedAmount">查询用量</el-button>
|
||
<hr>
|
||
<el-row>
|
||
<el-col>
|
||
<el-input style="width: 200px;" v-model="param" v-if="type !== 'tag'">
|
||
<template #prepend>
|
||
链接:
|
||
</template>
|
||
</el-input>
|
||
<el-button @click="queryRemoteTask" v-show="type === 'link'">解析链接</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
<hr>
|
||
<el-button @click="isQuerying = true">里站搜索</el-button>
|
||
<el-button @click="isAlterAuthCode = true">修改授权码</el-button>
|
||
<el-button @click="deleteAuthCode">删除本地授权码</el-button>
|
||
<el-button @click="isConfig = true">配置</el-button><br>
|
||
<span style="display: inline">夜间模式</span>
|
||
<el-switch @click="toggleStyle" v-model="isDark">夜间模式</el-switch>
|
||
<hr>
|
||
<el-button @click="isQuerying = true">里站搜索</el-button>
|
||
<el-button @click="isViewingTag = true">查看标签</el-button>
|
||
<br>
|
||
<el-button v-if="isLion" @click="resetUndone">重置任务</el-button>
|
||
<div v-show="thumbnailGallery !== {}">
|
||
<span>
|
||
{{thumbnailGallery.shortName}}
|
||
</span><br>
|
||
<picture>
|
||
<el-image :src="thumbnailGallery.url" :preview-src-list="[thumbnailGallery.url,]" :initial-index="0" class="preview"
|
||
style="height: 30vh" fit="contain"/>
|
||
</picture>
|
||
</div>
|
||
</el-drawer>
|
||
|
||
<el-dialog title="查询本子" v-model="chosenGallery" width="100%">
|
||
<table>
|
||
<tr>本子名字:{{chosenGallery.name}}</tr>
|
||
<tr>本子页数:{{chosenGallery.pages}}</tr>
|
||
<tr>本子语言:{{chosenGallery.language}}</tr>
|
||
<tr>本子大小:{{chosenGallery.fileSize}}</tr>
|
||
<tr>本子状态:{{chosenGallery.status}}</tr>
|
||
<tr v-if="chosenGallery.availableResolution">
|
||
目标分辨率:<el-select v-model="targetResolution">
|
||
<el-option v-for="(fileSize, resolution) in chosenGallery.availableResolution" :value="resolution"
|
||
:label="resolution + ' ' + fileSize">
|
||
</el-option>
|
||
</el-select>
|
||
</tr>
|
||
<tr v-if="chosenGallery.availableResolution">
|
||
标签:<el-tag v-for="tid in paramForTags" closable @close="removeQueryTag(tid)">
|
||
{{store.state.tags.get(tid).tag}}
|
||
</el-tag>
|
||
<el-autocomplete v-model="param" :fetch-suggestions="completeQueryTag" @select="handleTagSelect" ref="tagInputForSubmit"/>
|
||
</tr>
|
||
</table>
|
||
<el-button @click="postTask" v-if="chosenGallery.availableResolution">下载</el-button>
|
||
<el-button @click="removeAllQueryTag" v-if="chosenGallery.availableResolution">清空标签</el-button>
|
||
<tr v-if="chosenGallery.status === '下载完成'">
|
||
<el-button @click="onlineGalleryReader(chosenGallery.gid)">在线预览</el-button>
|
||
<el-button @click="showThumbnail(chosenGallery)">查看封面图</el-button>
|
||
<el-button @click="deleteGallery">删除</el-button>
|
||
</tr>
|
||
</el-dialog>
|
||
|
||
<HentaiSearch :is-querying="isQuerying" @close="isQuerying = false"></HentaiSearch>
|
||
|
||
<el-dialog title="修改授权码" v-model="isAlterAuthCode" width="100%">
|
||
<el-form>
|
||
<el-form-item>
|
||
<template #label>当前授权码</template>
|
||
<template #default>{{realAuthCode}}</template>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<template #label>新的授权码</template>
|
||
<template #default>
|
||
<el-input v-model="newAuthCode"></el-input>
|
||
</template>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<template #label>再次输入授权码</template>
|
||
<template #default>
|
||
<el-input v-model="tempAuthCode"></el-input>
|
||
</template>
|
||
</el-form-item>
|
||
</el-form>
|
||
<el-footer>
|
||
<el-button @click="alterAuthCode">提交</el-button>
|
||
</el-footer>
|
||
</el-dialog>
|
||
|
||
<el-dialog title="配置" v-model="isConfig" width="100%">
|
||
<div>
|
||
夜间模式<hr>
|
||
<span style="display: inline-block">夜间模式跟随系统</span>
|
||
<el-switch v-model="darkConfig.followSystem"></el-switch><br>
|
||
<span style="display: inline-block">自定义起始时间(精确到分)</span>
|
||
<el-switch v-model="darkConfig.customTime"></el-switch><br>
|
||
<el-form :disabled="!darkConfig.customTime">
|
||
<el-time-picker v-model="darkConfig.startTime" /> ~
|
||
<el-time-picker v-model="darkConfig.endTime"/>
|
||
</el-form>
|
||
</div>
|
||
<div>
|
||
在线预览<hr>
|
||
<span style="display: inline-block">在线预览分页页数:</span>
|
||
<input v-model="lengthPerPage">
|
||
</div>
|
||
<template #footer>
|
||
<el-button type="primary" @click="saveConfig">保存</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog title="查看标签" v-model="isViewingTag" style="margin-top: 0; width: 100%">
|
||
<div style="text-align: center">
|
||
输入关键字:<el-input style="width: 150px" v-model="tagKeyWord"></el-input><br>
|
||
<el-button @click="tagKeyWord = ''">重置关键字</el-button>
|
||
<el-button @click="pullNewTag">刷新</el-button>
|
||
</div>
|
||
|
||
<el-table :data="tags" height="350px" stripe>
|
||
<el-table-column prop="id" label="id" width="50px" sortable/>
|
||
<el-table-column prop="tag" label="标签" width="150px"/>
|
||
<el-table-column prop="usage" label="用量" width="75px" sortable/>
|
||
|
||
<el-table-column width="75px">
|
||
<template #default="scoped">
|
||
<el-button v-if="scoped.row.usage === 0" @click="deleteTag(scoped.row.id)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<span style="color: red; font: bold 15px sans-serif">
|
||
创建标签前先看看有没有符合的,尽量用统一一点的标签,比如已经有个图包就不要创建图集之类的了。毕竟标签多起来数据挺多的。
|
||
</span>
|
||
<template #footer>
|
||
输入新标签:<el-input v-model="tag" style="width: 100px"></el-input>
|
||
<el-button @click="postTag">创建标签</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<div class="DashBoard" v-show="!loadComplete">
|
||
<div class="validate">
|
||
<el-input v-model="AuthCode" placeholder="请输入授权码" />
|
||
<el-checkbox v-model="isRemember" >是否记住授权码</el-checkbox><br>
|
||
<el-button @click="validate" type="primary" @keydown.enter="validate">验证</el-button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import store from "../store";
|
||
import {computed, ref, onMounted} from "vue";
|
||
import {ElMessage} from "element-plus"
|
||
import axios from "axios";
|
||
import HentaiSearch from "./HentaiSearch.vue";
|
||
|
||
//授权码相关
|
||
let AuthCode = ref("")
|
||
let isRemember = ref(false)
|
||
let isAlterAuthCode = ref(false)
|
||
let newAuthCode = ref("")
|
||
let tempAuthCode = ref("")
|
||
|
||
let isQuerying = ref(false)
|
||
let isViewingTag = ref(false)
|
||
let isConfig = ref(false)
|
||
let isDark = ref(false)
|
||
let keyword = ref("furry yaoi")
|
||
let darkConfig = ref({})
|
||
let lengthPerPage = ref(0)
|
||
|
||
//查询相关
|
||
let type = ref("link")
|
||
let param = ref("")
|
||
let paramForTags = ref([]) //tidS
|
||
|
||
let targetResolution = ref("")
|
||
let tag = ref("")
|
||
let tagKeyWord = ref("") //查询tag的关键字
|
||
|
||
let realAuthCode = computed(() => {
|
||
return store.state.AuthCode
|
||
})
|
||
|
||
let chosenGallery = computed(() => {
|
||
paramForTags.value.splice(0)
|
||
param.value = ''
|
||
return store.state.chosenGallery
|
||
})
|
||
|
||
let loadComplete = computed(() => {
|
||
return store.state.loadComplete
|
||
})
|
||
|
||
let weekUsed = computed(() => {
|
||
return store.state.weekUsed
|
||
})
|
||
let tags = computed(() => {
|
||
let tags = store.state.tags
|
||
let result = []
|
||
tags.forEach((tag) => {
|
||
result.push(tag)
|
||
})
|
||
|
||
if(isViewingTag.value) { //正在查看标签
|
||
if (tagKeyWord.value.trim() === '')
|
||
return result
|
||
else
|
||
return result.filter((tag) => {
|
||
return tag.tag.includes(tagKeyWord.value)
|
||
})
|
||
}
|
||
return result
|
||
})
|
||
|
||
let thumbnailGallery = computed(() => {
|
||
return store.state.thumbnailGallery
|
||
})
|
||
|
||
let isLion = computed(() => {
|
||
return store.state.userId === 3
|
||
})
|
||
|
||
function pullNewTag(){
|
||
store.dispatch("loadTags")
|
||
}
|
||
|
||
function postTag(){
|
||
store.dispatch("postTag", tag.value)
|
||
}
|
||
|
||
function deleteTag(tid){
|
||
store.dispatch("deleteTag", tid)
|
||
}
|
||
|
||
//修改授权码
|
||
function alterAuthCode(){
|
||
if(newAuthCode.value.trim() === "" || tempAuthCode.value.trim() === "" || newAuthCode.value !== tempAuthCode.value)
|
||
ElMessage("请检查授权码输入是否错误")
|
||
else {
|
||
store.dispatch("alterAuthCode", newAuthCode.value)
|
||
isAlterAuthCode.value = false
|
||
newAuthCode.value = ""
|
||
tempAuthCode.value = ""
|
||
}
|
||
}
|
||
|
||
//查询用量
|
||
function queryWeekUsedAmount(){
|
||
store.dispatch("loadWeekUsedAmount")
|
||
}
|
||
|
||
function postTask(){
|
||
if(!validateLink(chosenGallery.value.link)){
|
||
ElMessage("链接错误")
|
||
return
|
||
}
|
||
if(targetResolution.value === ''){
|
||
ElMessage("请选择分辨率再提交")
|
||
return
|
||
}
|
||
let tempLink = coverLink(chosenGallery.value.link)
|
||
store.dispatch("postGalleryTask", {link: tempLink,
|
||
targetResolution: targetResolution.value,
|
||
tags:tag.value})
|
||
targetResolution.value = ""
|
||
}
|
||
|
||
//查询任务
|
||
function queryRemoteTask(){
|
||
if(!validateLink(param.value)){
|
||
ElMessage("链接错误")
|
||
return
|
||
}
|
||
let tempLink = coverLink(param.value)
|
||
store.dispatch("queryGalleryTask", tempLink)
|
||
}
|
||
function queryLocalTask(){
|
||
switch (type.value){
|
||
case "link":
|
||
store.commit("_searchLocalByLink", param.value)
|
||
break
|
||
case "keyword":
|
||
store.commit("_searchLocalByKeyword", param.value)
|
||
break
|
||
case "tag":
|
||
store.commit("_searchLocalByTag", paramForTags.value)
|
||
break
|
||
}
|
||
}
|
||
let tagInput = ref({}) //用于查询
|
||
let tagInputForSubmit = ref({}) //用于提交
|
||
function completeQueryTag(keyWord, cb) {
|
||
if(keyWord.includes(' ')) { //查询多个标签的时候
|
||
let temp = keyWord.split(' ')
|
||
keyWord = temp[temp.length - 1]
|
||
}else{ //只有一个标签的时候
|
||
keyWord = param.value
|
||
}
|
||
let result = []
|
||
let skip
|
||
let hit = false //用于检测是否有重复标签
|
||
tags.value.forEach((tag) => {
|
||
if(tag.tag.includes(keyWord)) {
|
||
skip = false
|
||
for (let id of paramForTags.value) { //跳过已选中的标签
|
||
if(tag.id === id){
|
||
if(!hit && tag.tag === keyWord){ //是否命中标签
|
||
hit = true
|
||
}
|
||
skip = true
|
||
break
|
||
}
|
||
}
|
||
if(!skip)
|
||
result.push({value: tag.tag, tid: tag.id})
|
||
}
|
||
})
|
||
if(result.length === 0 && !keyWord.includes("#") && chosenGallery.value.gid !== undefined && !hit){ //未命中结果并且准备与下载任务一并提交
|
||
result.push({value: '新建 #' + keyWord + ' 标签?', tag:keyWord})
|
||
}
|
||
cb(result)
|
||
}
|
||
|
||
function removeQueryTag(tid){
|
||
for (let i=0; i<paramForTags.value.length; i++){
|
||
if(paramForTags.value[i] === tid){
|
||
paramForTags.value.splice(i, 1)
|
||
break
|
||
}
|
||
}
|
||
if(chosenGallery.value.gid === undefined) //查询本地标签
|
||
queryLocalTask()
|
||
}
|
||
|
||
function removeAllQueryTag(){
|
||
paramForTags.value.splice(0)
|
||
if(chosenGallery.value.gid === undefined) //查询本地标签
|
||
queryLocalTask()
|
||
}
|
||
|
||
function handleTagSelect(data){
|
||
if('tag' in data){ //需要新建,不知道怎么处理回调,直接把axios搬到vue里面
|
||
axios.post("https://downloader.lionwebsite.xyz/GalleryManage/tag?" + qs.stringify({
|
||
tag:data.tag,
|
||
AuthCode: store.state.AuthCode
|
||
})
|
||
).then((res) => {
|
||
if (res.data.result === 'success') {
|
||
ElMessage('创建标签成功')
|
||
paramForTags.value.push(parseInt(res.data.tid))
|
||
tagInputForSubmit.value.blur()
|
||
store.dispatch("loadTags", false).then()
|
||
}
|
||
else
|
||
ElMessage(res.data.data)
|
||
})}else{
|
||
paramForTags.value.push(data.tid)
|
||
console.log(chosenGallery)
|
||
if(chosenGallery.value.gid === undefined){
|
||
queryLocalTask()
|
||
tagInput.value.blur()
|
||
}else{
|
||
tagInputForSubmit.value.blur()
|
||
}
|
||
}
|
||
param.value = ''
|
||
}
|
||
|
||
function resetLocalQuery(){
|
||
store.commit("_searchLocalByKeyword", "")
|
||
store.commit("_searchLocalByTag", [''])
|
||
param.value = ""
|
||
}
|
||
|
||
//删除任务
|
||
function deleteGallery(){
|
||
store.dispatch("deleteGallery", chosenGallery.value.gid)
|
||
}
|
||
|
||
//验证授权码
|
||
function validate(){
|
||
if(AuthCode.value.trim() === ""){
|
||
ElMessage("请输入授权码后再验证")
|
||
}
|
||
else{
|
||
store.dispatch("validate", AuthCode.value)
|
||
if(isRemember.value)
|
||
localStorage.setItem("auth", AuthCode.value)
|
||
}
|
||
}
|
||
|
||
//验证链接以及伪装链接
|
||
function validateLink(rawLink){
|
||
if(rawLink.trim() === "")
|
||
return false
|
||
if(rawLink.includes("hentai"))
|
||
return rawLink.includes("/g/")
|
||
else
|
||
return false
|
||
}
|
||
function coverLink(rawLink){
|
||
return rawLink.replace("exhentai.org", "element-plus.org").replace("e-hentai.org", "element.org");
|
||
}
|
||
|
||
//打开面板以及在线阅读
|
||
function openPanel(){
|
||
store.commit("_openHistoryPanel")
|
||
}
|
||
function onlineGalleryReader(gid){
|
||
store.dispatch("queryOnlineLinks", gid)
|
||
}
|
||
|
||
//重新给节点发送未完成任务
|
||
function resetUndone(){
|
||
store.dispatch("resetUndone").then()
|
||
}
|
||
function deleteAuthCode(){
|
||
localStorage.removeItem('auth')
|
||
ElMessage("删除授权码完成")
|
||
}
|
||
|
||
function toggleStyle(){
|
||
if(isDark.value)
|
||
dark()
|
||
else
|
||
light()
|
||
}
|
||
|
||
//显示缩略图
|
||
function showThumbnail(gallery){
|
||
store.commit("_changeThumbnailGallery", gallery)
|
||
setTimeout(() => {document.querySelector(".preview > img").click()}, 1)
|
||
}
|
||
|
||
onMounted(() => {
|
||
const auth = localStorage.getItem("auth")
|
||
adjustForStyle()
|
||
store.state.lengthPerPage = localStorage.getItem("lengthPerPage")
|
||
store.state.lengthPerPage = store.state.lengthPerPage === null ? 30: Number(store.state.lengthPerPage)
|
||
lengthPerPage.value = store.state.lengthPerPage
|
||
|
||
if(auth !== null){
|
||
store.dispatch("validate", auth)
|
||
}
|
||
})
|
||
function adjustForStyle(){
|
||
let darkConfigStr = localStorage.getItem("darkConfig")
|
||
if(darkConfigStr !== null) {
|
||
darkConfig.value = JSON.parse(darkConfigStr)
|
||
if (darkConfig.value.followSystem)
|
||
if (isSystemDark()) {
|
||
dark()
|
||
isDark.value = true
|
||
}
|
||
else {
|
||
light()
|
||
isDark.value = false
|
||
}
|
||
|
||
if (darkConfig.value.customTime)
|
||
if (isDarkTime(darkConfig.value)) {
|
||
dark()
|
||
isDark.value = true
|
||
}
|
||
else {
|
||
light()
|
||
isDark.value = false
|
||
}
|
||
|
||
if(isDark.value)
|
||
dark()
|
||
else
|
||
light()
|
||
}else {
|
||
light()
|
||
darkConfig.value = {'followSystem': false, 'customTime': false}
|
||
}
|
||
}
|
||
function isSystemDark(){
|
||
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||
}
|
||
function isDarkTime(darkConfig){
|
||
let date = new Date()
|
||
let startTime = darkConfig.startTime
|
||
let endTime = darkConfig.endTime
|
||
|
||
if(startTime.hour > endTime.hour){ //隔夜 22:00 ~ 8:00
|
||
if(date.getHours() > endTime.getHours() && date.getHours() < startTime.getHours()){ // 大于结束时间且小于起始时间 16:00
|
||
return false
|
||
}else if(date.getHours() === endTime.getHours()){ //22:00 ~ 8:30 8:26
|
||
return date.getMinutes() <= endTime.getMinutes();
|
||
}else if(date.getHours() === startTime.getHours()){ //22:30 ~ 8:00 22:46
|
||
return date.getMinutes() > startTime.getMinutes();
|
||
}else
|
||
return true
|
||
}else{ //不隔夜 00:00 ~ 6:00 22:00 ~ 23:00
|
||
if(date.getHours() > endTime.getHours() || date.getHours() < startTime.getHours()){
|
||
return false
|
||
}else if(date.getHours() === startTime.getHours()){ // 01:30 ~ 06:00 01:32
|
||
return date.getMinutes() >= startTime.getMinutes();
|
||
}else if(date.getHours() === endTime.getHours()){ // 01:30 ~ 06:30 06:35
|
||
return date.getMinutes() <= endTime.getMinutes();
|
||
}else
|
||
return true
|
||
}
|
||
}
|
||
function dark(){
|
||
let html = document.querySelector("html")
|
||
if(!html.classList.contains("dark"))
|
||
html.classList.add('dark')
|
||
document.querySelector(".DashBoard").style.setProperty("background-color", null)
|
||
document.querySelector(".app").style.setProperty("background-color", null)
|
||
let galleries = document.querySelectorAll("#gallery");
|
||
for(let gallery of galleries){
|
||
gallery.style.setProperty("background-color", null)
|
||
}
|
||
|
||
}
|
||
function light(){
|
||
let html = document.querySelector("html")
|
||
if(html.classList.contains("dark"))
|
||
html.classList.remove('dark')
|
||
|
||
document.querySelector(".DashBoard").style.setProperty("background-color", "ghostwhite")
|
||
document.querySelector(".app").style.setProperty("background-color", "#c6e2ff")
|
||
let galleries = document.querySelectorAll("#gallery");
|
||
if(galleries !== undefined && galleries.length !== 0)
|
||
for(let gallery of galleries){
|
||
gallery.style.setProperty("background-color", "FloralWhite")
|
||
}
|
||
}
|
||
function saveConfig(){
|
||
if(darkConfig.value.customTime) {
|
||
if(darkConfig.value.startTime === undefined || darkConfig.value.endTime === undefined){
|
||
ElMessage("请正确选择起始时间")
|
||
return
|
||
}
|
||
}
|
||
|
||
if(lengthPerPage.value < 0 || lengthPerPage.value > 30) {
|
||
ElMessage("分页页数设置错误,范围1~30")
|
||
lengthPerPage.value = 30
|
||
}
|
||
else {
|
||
store.state.lengthPerPage = Number(lengthPerPage.value)
|
||
localStorage.setItem("lengthPerPage", lengthPerPage.value)
|
||
}
|
||
localStorage.setItem("darkConfig", JSON.stringify(darkConfig.value))
|
||
isConfig.value = false
|
||
adjustForStyle()
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
.DashBoard{
|
||
width: auto;
|
||
height: 90vh;
|
||
text-align: center;
|
||
}
|
||
|
||
.validate{
|
||
width: 50vw;
|
||
display: block;
|
||
padding-top: 200px;
|
||
padding-left: 20vw;
|
||
text-align: center;
|
||
}
|
||
.el-input{
|
||
width: 25vw;
|
||
}
|
||
.el-dialogClass .el-dialog__body{
|
||
padding-left: 0;
|
||
padding-right: 0;
|
||
}
|
||
</style> |