diff --git a/docs/20260708/uni-app用户侧前端重建计划.md b/docs/20260708/uni-app用户侧前端重建计划.md
index da284850..731dff43 100644
--- a/docs/20260708/uni-app用户侧前端重建计划.md
+++ b/docs/20260708/uni-app用户侧前端重建计划.md
@@ -224,6 +224,7 @@ mobile-uni/
- PC 成长激励和组织权限页已收口真实数据边界: 派专项必须输入真实员工手机号或 extPartyId,不再写入 `mobile-user`;无项目范围接口时只显示空态,不再展示假项目样例。
- `mobile-uni` 本地 dev 代理已对齐 portless:默认 `/dev-api -> https://wygj-api.localhost`,不再依赖裸 `8080`;真实浏览器登录链路已复跑通过。
- 员工今日页“今日安排”已优先回读真实 `/api/aihr/mobile/practice/assignments`;有待训练专项或每日三题时覆盖公开 home seed,真实浏览器已验证 `13900000998` 首页显示当天 daily 任务并可跳到练习页。
+- 员工今日页到练习页已补任务上下文传递:首页点“开始”会把当前 assignment 带到练习页,daily 任务高亮并提示填写,主管专项可直接启动,减少跳页后的二次选择。
## 7. 风险
diff --git a/mobile-uni/src/pages/user/practice/index.vue b/mobile-uni/src/pages/user/practice/index.vue
index 3c53b3df..2e0cd634 100644
--- a/mobile-uni/src/pages/user/practice/index.vue
+++ b/mobile-uni/src/pages/user/practice/index.vue
@@ -21,7 +21,7 @@
-
+
{{ item.source === 'daily' ? '每日三题' : '主管专项' }}
{{ item.question || item.scenarioName }}
@@ -174,6 +174,7 @@ type PracticeStatus = 'idle' | 'starting' | 'active' | 'submitting' | 'finished'
const defaultScenarioId = 'complaint-water';
const defaultScenarioName = '投诉接待';
+const pendingAssignmentKey = 'aihr_pending_assignment_id';
const status = ref('idle');
const sessionId = ref('');
const roundIndex = ref(0);
@@ -199,6 +200,7 @@ const drillAnswers = ref>({});
const assignmentLoading = ref(false);
const answeringId = ref(null);
const activeAssignmentId = ref();
+const highlightedAssignmentId = ref(null);
const loggedIn = ref(false);
const busy = computed(() => status.value === 'starting' || status.value === 'submitting');
const canStartPractice = computed(() => status.value === 'idle' || status.value === 'finished');
@@ -257,6 +259,7 @@ const clearPracticeData = () => {
redFlagActive.value = false;
answeringId.value = null;
activeAssignmentId.value = undefined;
+ highlightedAssignmentId.value = null;
};
const requireLogin = () => {
@@ -297,6 +300,7 @@ const loadAssignments = async () => {
try {
assignments.value = await getPracticeAssignments(true);
drillAnswers.value = Object.fromEntries(assignments.value.map((item) => [item.id, item.userAnswer || '']));
+ consumePendingAssignment();
} catch (error) {
handleError(error, '今日任务加载失败');
} finally {
@@ -304,6 +308,25 @@ const loadAssignments = async () => {
}
};
+const consumePendingAssignment = () => {
+ const raw = uni.getStorageSync(pendingAssignmentKey);
+ if (!raw) return;
+ uni.removeStorageSync(pendingAssignmentKey);
+ const id = Number(raw);
+ if (!Number.isFinite(id)) return;
+ const item = assignments.value.find((row) => row.id === id);
+ if (!item) {
+ message.value = '首页任务已更新,请从列表选择';
+ return;
+ }
+ highlightedAssignmentId.value = item.id;
+ if (item.source !== 'daily' && item.status === '待训练' && canStartPractice.value) {
+ startAssignment(item);
+ return;
+ }
+ message.value = item.source === 'daily' ? '已定位首页任务,请填写话术后提交' : '该任务已完成,请选择其他任务';
+};
+
const submitDaily = async (item: PracticeAssignment) => {
if (answeringId.value) return;
const answer = (drillAnswers.value[item.id] || '').trim();
@@ -560,10 +583,16 @@ onShow(() => {
.assignment-row {
margin-top: 10px;
padding: 12px;
+ border: 1px solid transparent;
border-radius: 14px;
background: #f8fafc;
}
+.assignment-row.highlighted {
+ border-color: #2563eb;
+ background: #eff6ff;
+}
+
.assignment-badge {
display: inline-flex;
width: fit-content;
diff --git a/mobile-uni/src/pages/user/today/index.vue b/mobile-uni/src/pages/user/today/index.vue
index 09a270be..d1a45beb 100644
--- a/mobile-uni/src/pages/user/today/index.vue
+++ b/mobile-uni/src/pages/user/today/index.vue
@@ -117,6 +117,7 @@ const message = ref('');
const loggedIn = ref(false);
const quickQuestions = ['催费话术', '投诉应对', '收费标准'];
const pendingSopQueryKey = 'aihr_sop_pending_query';
+const pendingAssignmentKey = 'aihr_pending_assignment_id';
const iconFor = (title: string) => {
if (title.includes('SOP') || title.includes('查')) return '/static/map-icons/ask.png';
@@ -218,6 +219,9 @@ const goLogin = () => {
};
const openPrimarySchedule = () => {
+ if (primaryAssignment.value) {
+ uni.setStorageSync(pendingAssignmentKey, String(primaryAssignment.value.id));
+ }
uni.switchTab({ url: '/pages/user/practice/index' });
};