feat: restore learning feedback and knowledge capabilities

This commit is contained in:
2026-07-18 00:50:11 +08:00
parent 876a23a123
commit 6bdc86e3fc
152 changed files with 30337 additions and 953 deletions
+211 -6
View File
@@ -165,19 +165,36 @@
<text class="tip-text">{{ tipBody }}</text>
<text class="tip-arrow">›</text>
</button>
<button class="tip-card" @click="openPracticeSummary">
<uni-icons class="tip-mark" type="staff" size="22" color="#e60012" />
<text class="tip-label">训练</text>
<text class="tip-divider">|</text>
<text class="tip-text">查看我的训练概况</text>
<text class="tip-arrow">›</text>
</button>
</view>
<button class="question-board-card employee-card" @click="openQuestions">
<view class="question-board-icon">榜</view>
<view class="question-board-copy">
<text class="question-board-title">问题榜</text>
<text class="question-board-desc">看看大家常遇到的难题,也可以发起真实工作求助</text>
</view>
<text class="question-board-arrow">›</text>
</button>
</view>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import { onHide, onShow, onUnload } from '@dcloudio/uni-app';
import type { PracticeAssignment, RoleHome } from '@/types/api';
import { getMobileHome } from '@/services/home';
import { getPracticeAssignments } from '@/services/practice';
import { getSelectedPositionProfile, isLoggedIn, rememberLoginRedirect } from '@/services/auth';
import { resetPageScroll } from '@/services/navigation';
import { ensureEmployeePosition } from '@/services/position';
import { createPageRequestScope, currentAccountKey } from '@/services/request-scope';
const home = ref<RoleHome | null>(null);
const assignments = ref<PracticeAssignment[]>([]);
@@ -187,7 +204,10 @@ const positionProfile = ref(getSelectedPositionProfile());
const quickQuestions = computed(() => positionProfile.value.quickQuestions);
const primaryTipQuestion = computed(() => quickQuestions.value[0] || '岗位SOP');
const pendingSopQueryKey = 'aihr_sop_pending_query';
const pendingToolKey = 'aihr_sop_pending_tool';
const pendingAssignmentKey = 'aihr_pending_assignment_id';
const requests = createPageRequestScope();
let visibleAccountKey = '';
const chipIcons = ['chatbubble', 'help', 'wallet'];
const chipIcon = (index: number) => chipIcons[index] || 'chatbubble';
@@ -293,14 +313,18 @@ const tipBody = computed(() => {
const mentorBubbleText = computed(() => {
if (!loggedIn.value) return '登录后看今天任务';
if (primaryAssignment.value?.source === 'daily') return '今天先完成每日三题';
if (primaryScheduleTitle.value) {
const topic = primaryScheduleTitle.value.replace(/专项|训练|练习/g, '').trim();
if (topic) return `今天先把${topic}练熟`;
const topic = (primaryAssignment.value?.scenarioName || primaryScheduleTitle.value)
.replace(/专项|训练|练习/g, '')
.trim();
if (topic) return `今天先把${topic.slice(0, 8)}${topic.length > 8 ? '…' : ''}练熟`;
}
return '今天先把投诉处理练熟';
});
const loadHome = async () => {
const request = requests.begin('home');
loggedIn.value = isLoggedIn();
positionProfile.value = getSelectedPositionProfile();
message.value = '';
@@ -309,7 +333,7 @@ const loadHome = async () => {
home.value = null;
return;
}
if (!(await ensureEmployeePosition('/pages/user/today/index'))) {
if (!(await ensureEmployeePosition('/pages/user/today/index')) || !requests.isCurrent(request)) {
return;
}
positionProfile.value = getSelectedPositionProfile();
@@ -317,6 +341,7 @@ const loadHome = async () => {
getMobileHome('user'),
getPracticeAssignments(true)
]);
if (!requests.isCurrent(request)) return;
if (homeResult.status === 'fulfilled') {
home.value = homeResult.value;
} else {
@@ -345,6 +370,11 @@ const ask = (query: string) => {
uni.switchTab({ url: '/pages/user/sop/index' });
};
const openPracticeSummary = () => {
uni.setStorageSync(pendingToolKey, 'MY_PRACTICE_SUMMARY');
uni.switchTab({ url: '/pages/user/sop/index' });
};
const goLogin = () => {
rememberLoginRedirect('/pages/user/today/index');
uni.navigateTo({ url: '/pages/auth/login/index' });
@@ -357,6 +387,15 @@ const openPrimarySchedule = () => {
uni.switchTab({ url: '/pages/user/practice/index' });
};
const openQuestions = () => {
if (!loggedIn.value) {
rememberLoginRedirect('/pages/user/questions/index');
uni.navigateTo({ url: '/pages/auth/login/index' });
return;
}
uni.navigateTo({ url: '/pages/user/questions/index' });
};
const openBuilding = (title: string) => {
uni.navigateTo({ url: `/pages/common/building/index?title=${encodeURIComponent(title)}` });
};
@@ -382,9 +421,25 @@ const openTool = (title: string) => {
};
onShow(() => {
const nextAccountKey = currentAccountKey();
if (visibleAccountKey && visibleAccountKey !== nextAccountKey) {
home.value = null;
assignments.value = [];
message.value = '';
}
visibleAccountKey = nextAccountKey;
requests.activate();
resetPageScroll();
void loadHome();
});
onHide(() => {
requests.invalidate();
});
onUnload(() => {
requests.invalidate();
});
</script>
<style scoped>
@@ -394,6 +449,57 @@ onShow(() => {
background: #f7f7f7;
}
.question-board-card {
display: flex;
width: 100%;
gap: 12px;
align-items: center;
margin-top: 16px;
padding: 16px;
color: var(--ink);
text-align: left;
}
.question-board-icon {
display: flex;
flex: 0 0 44px;
width: 44px;
height: 44px;
align-items: center;
justify-content: center;
border-radius: 14px;
background: #fff0f1;
color: var(--brand);
font-weight: 900;
}
.question-board-copy {
min-width: 0;
flex: 1;
}
.question-board-title,
.question-board-desc {
display: block;
}
.question-board-title {
font-size: 17px;
font-weight: 900;
}
.question-board-desc {
margin-top: 4px;
color: var(--muted);
font-size: 13px;
line-height: 1.5;
}
.question-board-arrow {
color: var(--muted);
font-size: 28px;
}
.brand-bar {
display: flex;
align-items: center;
@@ -1030,7 +1136,7 @@ onShow(() => {
.map-desc {
color: #8a8d93;
font-size: 11px;
font-size: 12px;
line-height: 1.35;
white-space: pre-line;
}
@@ -1123,7 +1229,7 @@ onShow(() => {
}
.voice-desc {
font-size: 11px;
font-size: 12px;
}
.chip-text {
@@ -1138,4 +1244,103 @@ onShow(() => {
padding-left: 0;
}
}
:global(html[data-aihr-font-size='extra-large'] .mentor-hero) {
min-height: 270px;
}
:global(html[data-aihr-font-size='extra-large'] .hero-copy) {
width: 100%;
max-width: 100%;
padding-right: 18px;
}
:global(html[data-aihr-font-size='extra-large'] .hero-tip) {
max-width: 160px;
white-space: normal;
}
:global(html[data-aihr-font-size='extra-large'] .mentor-stage) {
position: absolute;
right: 0;
bottom: 0;
width: 154px;
height: 154px;
}
:global(html[data-aihr-font-size='extra-large'] .mentor-bubble) {
display: none;
}
:global(html[data-aihr-font-size='extra-large'] .mentor-image) {
right: 0;
bottom: 0;
width: 144px;
height: 154px;
}
:global(html[data-aihr-font-size='extra-large'] .voice-panel) {
flex-direction: column;
align-items: stretch;
gap: 0;
}
:global(html[data-aihr-font-size='extra-large'] .voice-primary),
:global(html[data-aihr-font-size='extra-large'] .voice-secondary) {
width: 100%;
flex: none;
}
:global(html[data-aihr-font-size='extra-large'] .voice-secondary) {
padding-top: 10px;
border-top: 1px solid #f0f1f3;
}
:global(html[data-aihr-font-size='extra-large'] .secondary-copy) {
max-width: none;
}
:global(html[data-aihr-font-size='extra-large'] .secondary-copy .voice-desc) {
width: auto;
}
:global(html[data-aihr-font-size='extra-large'] .chip-row),
:global(html[data-aihr-font-size='extra-large'] .map-grid) {
grid-template-columns: 1fr;
}
:global(html[data-aihr-font-size='extra-large'] .chip-text) {
max-width: none;
}
:global(html[data-aihr-font-size='extra-large'] .login-section) {
flex-direction: column;
align-items: stretch;
}
:global(html[data-aihr-font-size='extra-large'] .login-button),
:global(html[data-aihr-font-size='extra-large'] .schedule-action) {
width: 100%;
min-width: 0;
flex: 0 0 100%;
}
:global(html[data-aihr-font-size='extra-large'] .schedule-row) {
flex-wrap: wrap;
align-items: flex-start;
}
:global(html[data-aihr-font-size='extra-large'] .schedule-copy) {
flex-basis: calc(100% - 64px);
}
:global(html[data-aihr-font-size='extra-large'] .tip-card) {
align-items: flex-start;
}
:global(html[data-aihr-font-size='extra-large'] .tip-text) {
overflow: visible;
text-overflow: clip;
white-space: normal;
}
</style>