feat: 移动端双Token队列拦截器 + 通知列表 + 登录页 + TabBar红点 + v1.0.1
This commit is contained in:
@ -49,7 +49,7 @@
|
||||
<text class="tag-branch">{{ branchLabelsMap[lockedTask.id] || '' }}</text>
|
||||
<text class="fc-status">{{ statusLabel(lockedTask.status) }}</text>
|
||||
<text v-if="lockedTask.is_rework" class="tag tag-rework-sm">⚠返工</text>
|
||||
<text v-if="lockedTask.parent_task_id && lockedTask.status === 'WIP'" class="sub-branch-end"
|
||||
<text v-if="lockedTask.parent_task_id && lockedTask.task_type === 'SPAWN' && lockedTask.status === 'WIP'" class="sub-branch-end"
|
||||
@tap="$emit('action', { task: lockedTask, type: 'end' })">🛑 结束协助</text>
|
||||
</view>
|
||||
<text class="fc-name">{{ lockedTask.task_name }}</text>
|
||||
@ -110,11 +110,29 @@ export default {
|
||||
product: { type: Object, default: null },
|
||||
currentUserId: { type: String, default: "" },
|
||||
currentUsername: { type: String, default: "" },
|
||||
initialLockTaskId: { type: String, default: "" },
|
||||
},
|
||||
emits: ["action", "viewRecords"],
|
||||
data() {
|
||||
return { lockedTaskId: null };
|
||||
},
|
||||
watch: {
|
||||
initialLockTaskId: {
|
||||
immediate: true,
|
||||
handler(id) {
|
||||
if (id && this.focusTasks.some(t => t.id === id)) {
|
||||
this.lockedTaskId = id;
|
||||
}
|
||||
},
|
||||
},
|
||||
product: {
|
||||
handler() {
|
||||
if (this.initialLockTaskId && this.focusTasks.some(t => t.id === this.initialLockTaskId)) {
|
||||
this.lockedTaskId = this.initialLockTaskId;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
taskMap() {
|
||||
const m = {};
|
||||
@ -133,8 +151,8 @@ export default {
|
||||
};
|
||||
if (this.product) walk(this.product.task_tree);
|
||||
result.sort((a, b) => {
|
||||
const aIsMain = !a.parent_task_id || a.task_type !== 'SPAWN';
|
||||
const bIsMain = !b.parent_task_id || b.task_type !== 'SPAWN';
|
||||
const aIsMain = !a.parent_task_id || a.task_type === 'TRANSFER' || a.task_type === 'RECOVERY';
|
||||
const bIsMain = !b.parent_task_id || b.task_type === 'TRANSFER' || b.task_type === 'RECOVERY';
|
||||
if (aIsMain && !bIsMain) return -1;
|
||||
if (!aIsMain && bIsMain) return 1;
|
||||
return new Date(a.created_at) - new Date(b.created_at);
|
||||
@ -154,11 +172,31 @@ export default {
|
||||
branchLabelsMap() {
|
||||
const map = {};
|
||||
if (!this.product || !this.product.task_tree) return map;
|
||||
|
||||
// 拍平树结构,方便随时查父节点状态
|
||||
const flatMap = {};
|
||||
const flatten = (tasks) => {
|
||||
if (!tasks) return;
|
||||
tasks.forEach(t => { flatMap[t.id] = t; flatten(t.child_tasks); });
|
||||
};
|
||||
flatten(this.product.task_tree);
|
||||
|
||||
const traverse = (tasks, prefix) => {
|
||||
if (!tasks) return;
|
||||
let spawnIndex = 0;
|
||||
tasks.forEach((t) => {
|
||||
if (t.task_type !== 'SPAWN') {
|
||||
const parent = t.parent_task_id ? flatMap[t.parent_task_id] : null;
|
||||
|
||||
// 🚀 终极防御判定:
|
||||
// 1. 没有父节点(打底任务) -> 主分支
|
||||
// 2. 明确的基因 (TRANSFER/RECOVERY) -> 主分支
|
||||
// 3. 兜底:如果基因丢失,但它的父节点已经完工(COMPLETED),那它必然是接力的转交任务 -> 主分支
|
||||
const isMain = !t.parent_task_id
|
||||
|| t.task_type === 'TRANSFER'
|
||||
|| t.task_type === 'RECOVERY'
|
||||
|| (!t.task_type && parent && (parent.status === 'COMPLETED' || parent.status === 'CANCELED'));
|
||||
|
||||
if (isMain) {
|
||||
map[t.id] = '主分支';
|
||||
traverse(t.child_tasks, prefix);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user