移动端支持下载人信息与筛选(仅管理员)
- 详情抽屉显示下载人昵称,取不到时回退为 #id - 任务列表新增「下载人」筛选,选项从当前分类派生,切分类时清空 - 管理员判定改用后端下发的 isAdmin,不再硬编码 userId === 3
This commit is contained in:
@@ -16,7 +16,7 @@ const galleryNameType = ref("shortName");
|
|||||||
|
|
||||||
const realAuthCode = computed(() => store.state.AuthCode);
|
const realAuthCode = computed(() => store.state.AuthCode);
|
||||||
const weekUsed = computed(() => store.state.weekUsed);
|
const weekUsed = computed(() => store.state.weekUsed);
|
||||||
const isLion = computed(() => store.state.userId === 3);
|
const isAdmin = computed(() => store.state.isAdmin);
|
||||||
|
|
||||||
const connectionText = computed(() => ({
|
const connectionText = computed(() => ({
|
||||||
connected: "已连接",
|
connected: "已连接",
|
||||||
@@ -137,7 +137,7 @@ onMounted(() => {
|
|||||||
<span class="setting-label">删除本地授权码</span>
|
<span class="setting-label">删除本地授权码</span>
|
||||||
<span class="chevron">›</span>
|
<span class="chevron">›</span>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="isLion" type="button" class="setting-row is-button is-danger"
|
<button v-if="isAdmin" type="button" class="setting-row is-button is-danger"
|
||||||
@click="store.dispatch('resetUndone')">
|
@click="store.dispatch('resetUndone')">
|
||||||
<span class="setting-label">重置未完成任务</span>
|
<span class="setting-label">重置未完成任务</span>
|
||||||
<span class="chevron">›</span>
|
<span class="chevron">›</span>
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ watch(detailGallery, (gallery) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const isLion = computed(() => store.state.userId === 3);
|
// Admin-only fields come from the backend's isAdmin flag, not a hardcoded id.
|
||||||
|
const isAdmin = computed(() => store.state.isAdmin);
|
||||||
const isDone = computed(() => (task.value ? task.value.status === "下载完成" : false));
|
const isDone = computed(() => (task.value ? task.value.status === "下载完成" : false));
|
||||||
const isCollect = computed(() => Boolean(task.value && task.value.isCollect));
|
const isCollect = computed(() => Boolean(task.value && task.value.isCollect));
|
||||||
|
|
||||||
@@ -139,9 +140,9 @@ function submitTask() {
|
|||||||
<dd>{{ task.createTimeDisplay || "—" }}</dd>
|
<dd>{{ task.createTimeDisplay || "—" }}</dd>
|
||||||
<dt>原始页面</dt>
|
<dt>原始页面</dt>
|
||||||
<dd><a v-if="task.link" :href="task.link" target="_blank" rel="noopener">打开链接</a><span v-else>—</span></dd>
|
<dd><a v-if="task.link" :href="task.link" target="_blank" rel="noopener">打开链接</a><span v-else>—</span></dd>
|
||||||
<template v-if="isLion">
|
<template v-if="isAdmin">
|
||||||
<dt>downloader</dt>
|
<dt>下载人</dt>
|
||||||
<dd>{{ task.downloader }}</dd>
|
<dd>{{ task.downloaderName || `#${task.downloader}` }}</dd>
|
||||||
</template>
|
</template>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,23 @@ const sortType = computed({
|
|||||||
set: value => store.commit("_setSortType", value),
|
set: value => store.commit("_setSortType", value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isAdmin = computed(() => store.state.isAdmin);
|
||||||
|
const downloaderFilter = computed({
|
||||||
|
get: () => store.state.downloaderFilter,
|
||||||
|
set: value => store.commit("_setDownloaderFilter", value),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Options come from the current category, so the dropdown can never offer a
|
||||||
|
// downloader that would filter the visible list down to nothing.
|
||||||
|
const downloaderOptions = computed(() => {
|
||||||
|
const seen = new Map();
|
||||||
|
;(store.state.currentTasks || []).forEach(task => {
|
||||||
|
if (task.downloaderName && !seen.has(task.downloader))
|
||||||
|
seen.set(task.downloader, task.downloaderName);
|
||||||
|
});
|
||||||
|
return [...seen].map(([id, name]) => ({id, name}));
|
||||||
|
});
|
||||||
|
|
||||||
const emptyText = computed(() => {
|
const emptyText = computed(() => {
|
||||||
if (store.state.category === "myDownload") return "您未下载过";
|
if (store.state.category === "myDownload") return "您未下载过";
|
||||||
if (store.state.category === "myCollect") return "您未收藏过";
|
if (store.state.category === "myCollect") return "您未收藏过";
|
||||||
@@ -97,6 +114,17 @@ async function refreshTasks() {
|
|||||||
<el-option value="shortName" label="简洁名"/>
|
<el-option value="shortName" label="简洁名"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</label>
|
</label>
|
||||||
|
<label class="filter" v-if="isAdmin">
|
||||||
|
<span class="filter-label">下载人</span>
|
||||||
|
<el-select v-model="downloaderFilter" size="small"
|
||||||
|
class="filter-select filter-select-downloader"
|
||||||
|
clearable placeholder="全部">
|
||||||
|
<el-option v-for="item in downloaderOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.id"
|
||||||
|
:label="item.name"/>
|
||||||
|
</el-select>
|
||||||
|
</label>
|
||||||
<button type="button" class="chip-button" :disabled="refreshing" @click="refreshTasks">
|
<button type="button" class="chip-button" :disabled="refreshing" @click="refreshTasks">
|
||||||
{{ refreshing ? "刷新中" : "刷新" }}
|
{{ refreshing ? "刷新中" : "刷新" }}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
+29
-11
@@ -325,6 +325,8 @@ const mutations = {
|
|||||||
state.AuthCode = data.AuthCode
|
state.AuthCode = data.AuthCode
|
||||||
state.userId = data.userId
|
state.userId = data.userId
|
||||||
state.username = data.username
|
state.username = data.username
|
||||||
|
state.isAdmin = Boolean(data.isAdmin)
|
||||||
|
state.downloaderFilter = null
|
||||||
state.isAuth = true
|
state.isAuth = true
|
||||||
ElMessage("验证成功,加载中")
|
ElMessage("验证成功,加载中")
|
||||||
},
|
},
|
||||||
@@ -402,6 +404,8 @@ const mutations = {
|
|||||||
_setCategory(state, category){
|
_setCategory(state, category){
|
||||||
state.category = category
|
state.category = category
|
||||||
state.visiblePages = 1
|
state.visiblePages = 1
|
||||||
|
// 换分类后旧的下载人筛选可能在新分类里根本不存在,先清掉。
|
||||||
|
state.downloaderFilter = null
|
||||||
confirmCurrentTask(state)
|
confirmCurrentTask(state)
|
||||||
sortTasks(state)
|
sortTasks(state)
|
||||||
},
|
},
|
||||||
@@ -413,6 +417,12 @@ const mutations = {
|
|||||||
_setGalleryNameType(state, galleryNameType){
|
_setGalleryNameType(state, galleryNameType){
|
||||||
state.galleryNameType = galleryNameType
|
state.galleryNameType = galleryNameType
|
||||||
},
|
},
|
||||||
|
_setDownloaderFilter(state, downloader){
|
||||||
|
state.downloaderFilter = downloader === null || downloader === undefined
|
||||||
|
? null
|
||||||
|
: Number(downloader)
|
||||||
|
state.visiblePages = 1
|
||||||
|
},
|
||||||
_setShowNameType(state, type){
|
_setShowNameType(state, type){
|
||||||
if(type === "shortName")
|
if(type === "shortName")
|
||||||
state.length = state.shortLength
|
state.length = state.shortLength
|
||||||
@@ -481,23 +491,23 @@ const state = {
|
|||||||
sortType:'shortName', //排序类型 shortName name createTime
|
sortType:'shortName', //排序类型 shortName name createTime
|
||||||
currentTasks: [], //当前任务
|
currentTasks: [], //当前任务
|
||||||
weekUsed: {}, //每周用量
|
weekUsed: {}, //每周用量
|
||||||
|
isAdmin: false, //管理员(后端 validate 下发)
|
||||||
|
downloaderFilter: null, //管理员按下载人筛选,null 表示全部
|
||||||
}
|
}
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
currentTasks(state){
|
currentTasks(state){
|
||||||
if(state.isSearch)
|
const tasks = activeTaskList(state)
|
||||||
return state.searchTask.slice((state.page - 1) * state.length, state.page * state.length)
|
return tasks.slice((state.page - 1) * state.length, state.page * state.length)
|
||||||
else
|
|
||||||
return state.currentTasks.slice((state.page - 1) * state.length, state.page * state.length)
|
|
||||||
},
|
},
|
||||||
min(){
|
min(){
|
||||||
return 1
|
return 1
|
||||||
},
|
},
|
||||||
visibleTasks(state){
|
visibleTasks(state){
|
||||||
return (state.currentTasks || []).slice(0, state.visiblePages * state.length)
|
return activeTaskList(state).slice(0, state.visiblePages * state.length)
|
||||||
},
|
},
|
||||||
taskTotal(state){
|
taskTotal(state){
|
||||||
return (state.currentTasks || []).length
|
return activeTaskList(state).length
|
||||||
},
|
},
|
||||||
taskRemaining(state, getters){
|
taskRemaining(state, getters){
|
||||||
return Math.max(0, getters.taskTotal - state.visiblePages * state.length)
|
return Math.max(0, getters.taskTotal - state.visiblePages * state.length)
|
||||||
@@ -507,11 +517,7 @@ const getters = {
|
|||||||
},
|
},
|
||||||
max(state){
|
max(state){
|
||||||
let max = 0
|
let max = 0
|
||||||
let tasks
|
const tasks = activeTaskList(state)
|
||||||
if(state.isSearch)
|
|
||||||
tasks = state.searchTask
|
|
||||||
else
|
|
||||||
tasks = state.currentTasks
|
|
||||||
|
|
||||||
if(!tasks)
|
if(!tasks)
|
||||||
return 1
|
return 1
|
||||||
@@ -531,6 +537,18 @@ export default new vuex.Store({
|
|||||||
getters
|
getters
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前视图实际要展示的任务。
|
||||||
|
* 下载人筛选只在管理员生效,作用于「我的下载/收藏/全部」三种分类的结果。
|
||||||
|
*/
|
||||||
|
function activeTaskList(state){
|
||||||
|
if(state.isSearch)
|
||||||
|
return state.searchTask
|
||||||
|
if(state.isAdmin && state.downloaderFilter !== null)
|
||||||
|
return state.currentTasks.filter(task => task.downloader === state.downloaderFilter)
|
||||||
|
return state.currentTasks
|
||||||
|
}
|
||||||
|
|
||||||
function getShortname(name){
|
function getShortname(name){
|
||||||
if(name === null)
|
if(name === null)
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -220,6 +220,10 @@ body {
|
|||||||
width: 90px;
|
width: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filter-select-downloader {
|
||||||
|
width: 96px;
|
||||||
|
}
|
||||||
|
|
||||||
.chip-button {
|
.chip-button {
|
||||||
flex: none;
|
flex: none;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
|
|||||||
Reference in New Issue
Block a user