feat(mobile): 登录修复 + 人名字典 + 留言板FAB + 流转算法重构
- login: catch补齐toast,修复密码错误静默失败 - detail: formatUserName渲染当前位置,dictVersion驱动响应式重绘 - detail: 留言板改为悬浮按钮+底部抽屉,未读徽标逻辑 - TaskSwipeCards: lanes终极递归算法,SPAWN不限层级开辟新Tab,先序push修复Tab顺序 - TreeCanvas: 父子相对坐标延伸算法,替代旧版奇偶距离递增
This commit is contained in:
@ -134,40 +134,35 @@ export default {
|
||||
if (!this.product || !this.product.task_tree) return result;
|
||||
|
||||
const mainLane = { _key: 'main', label: '主分支', cards: [], _cardIdx: 0 };
|
||||
const isMainFn = (t) => !t.parent_task_id || t.task_type === 'TRANSFER' || t.task_type === 'RECOVERY';
|
||||
|
||||
const sortTasks = (tasks) => {
|
||||
if (!tasks) return [];
|
||||
return [...tasks].sort((a, b) => {
|
||||
const aMain = isMainFn(a) ? -1 : 1;
|
||||
const bMain = isMainFn(b) ? -1 : 1;
|
||||
if (aMain !== bMain) return aMain - bMain;
|
||||
return new Date(a.created_at) - new Date(b.created_at);
|
||||
});
|
||||
return [...tasks].sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
|
||||
};
|
||||
|
||||
// 🚀 终极递归收集算法
|
||||
const followMain = (taskList, lane) => {
|
||||
if (!taskList || !taskList.length) return;
|
||||
const sorted = sortTasks(taskList);
|
||||
|
||||
for (const t of sorted) {
|
||||
if (isMainFn(t)) {
|
||||
lane.cards.push({ ...t, _key: t.id + '_' + lane._key, _isMain: lane._key === 'main' });
|
||||
if (t.child_tasks && t.child_tasks.length) {
|
||||
const nextMain = t.child_tasks.filter(c =>
|
||||
c.task_type === 'TRANSFER' || c.task_type === 'RECOVERY');
|
||||
followMain(nextMain, lane);
|
||||
// SPAWN 子节点 → 新分支(含嵌套 spawn)
|
||||
const spawns = t.child_tasks.filter(c => c.task_type === 'SPAWN');
|
||||
for (const sc of spawns) {
|
||||
const blabel = this.branchLabelMap[sc.id] || '分支';
|
||||
const branchLane = { _key: 'branch_' + sc.id, label: blabel, cards: [], _cardIdx: 0 };
|
||||
branchLane.cards.push({ ...sc, _key: sc.id + '_' + branchLane._key, _isMain: false });
|
||||
if (sc.child_tasks && sc.child_tasks.length) {
|
||||
followMain(sc.child_tasks, branchLane);
|
||||
}
|
||||
result.push(branchLane);
|
||||
}
|
||||
// 1. 无条件入列:既然进到了这个 lane,就属于这个 lane 的卡片
|
||||
lane.cards.push({ ...t, _key: t.id + '_' + lane._key, _isMain: lane._key === 'main' });
|
||||
|
||||
if (t.child_tasks && t.child_tasks.length) {
|
||||
// 1. 同一分支线性延续
|
||||
const nextOnThisLane = t.child_tasks.filter(c =>
|
||||
c.task_type === 'TRANSFER' || c.task_type === 'RECOVERY'
|
||||
);
|
||||
followMain(nextOnThisLane, lane);
|
||||
|
||||
// 2. 凡是 SPAWN,必定开辟新分支 (不限层级)
|
||||
const spawns = t.child_tasks.filter(c => c.task_type === 'SPAWN');
|
||||
for (const sc of spawns) {
|
||||
const blabel = (this.branchLabelMap && this.branchLabelMap[sc.id]) || '协助分支';
|
||||
const branchLane = { _key: 'branch_' + sc.id, label: blabel, cards: [], _cardIdx: 0 };
|
||||
result.push(branchLane); // 先占坑:父分支排在前面
|
||||
followMain([sc], branchLane); // 再递归:孙子分支自然排在后面
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user