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