feat(mobile): redesign today home and switch mentor persona to female

- today: immersive community hero + hold-to-talk voice card, numbered
  schedule rows, common-functions grid (learning/report/question-board)
- login: female mentor bust; sop: female mentor chat avatars
- speech: raise browser-fallback mentor pitch to match female voice
This commit is contained in:
2026-07-19 02:38:18 +08:00
parent a8460bbaed
commit 4c2b5deb00
8 changed files with 451 additions and 531 deletions
+77 -38
View File
@@ -1,17 +1,20 @@
<template>
<view class="page login-page">
<view class="login-shell">
<view class="login-head">
<view class="brand-lockup">
<image class="login-logo" src="/static/brand-logo.png" mode="aspectFit" />
<view class="brand-copy">
<text class="brand-name">银城物业</text>
<text class="brand-divider">|</text>
<text class="login-eyebrow">数字师傅</text>
</view>
<view class="brand-lockup">
<image class="login-logo" src="/static/brand-logo.png" mode="aspectFit" />
<view class="brand-copy">
<text class="brand-name">银城物业</text>
<text class="brand-divider">·</text>
<text class="login-eyebrow">数字师傅</text>
</view>
</view>
<view class="mentor-block">
<image class="mentor-image" src="/static/mentor-female-bust.png" mode="aspectFit" />
<view class="mentor-bubble">
<text class="mentor-bubble-text">手机号登录,一分钟上手</text>
</view>
<text class="page-title">银城员工端</text>
<text class="page-subtitle">高效协同 · 贴心服务 · 让工作更简单</text>
</view>
<view class="panel login-card">
@@ -77,6 +80,8 @@
show-icon
/>
</view>
<text class="agreement">登录即同意《服务协议》与《隐私政策》</text>
</view>
</view>
</template>
@@ -213,7 +218,7 @@ onShow(() => {
.login-shell {
min-height: 100vh;
padding: 72px 24px 36px;
padding: 36px 24px 28px;
overflow: hidden;
}
@@ -240,24 +245,19 @@ onShow(() => {
left: -72px;
}
.login-head {
position: relative;
max-width: 720px;
margin: 0 auto 32px;
}
.brand-lockup {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 28px;
justify-content: center;
gap: 10px;
max-width: 720px;
margin: 0 auto 22px;
}
.login-logo {
width: 48px;
height: 48px;
width: 34px;
height: 34px;
flex: none;
transform: translateX(6px) scale(1.4);
}
.brand-copy {
@@ -286,21 +286,49 @@ onShow(() => {
color: #e60012;
}
.login-head .page-title {
display: block;
color: #252931;
font-size: 34px;
font-weight: 800;
line-height: 1.16;
letter-spacing: 1px;
.mentor-block {
display: flex;
align-items: flex-start;
gap: 12px;
max-width: 720px;
margin: 0 auto 18px;
padding: 0 6px;
}
.login-head .page-subtitle {
display: block;
margin-top: 12px;
color: #6d7078;
font-size: 15px;
line-height: 1.6;
.mentor-image {
width: 128px;
height: 130px;
flex: none;
}
.mentor-bubble {
position: relative;
margin-top: 20px;
padding: 12px 16px;
border: 1px solid rgba(225, 227, 232, 0.9);
border-radius: 14px;
background: #ffffff;
box-shadow: 0 6px 16px rgba(29, 31, 35, 0.08);
}
.mentor-bubble::before {
position: absolute;
top: 22px;
left: -6px;
width: 10px;
height: 10px;
border-bottom: 1px solid rgba(225, 227, 232, 0.9);
border-left: 1px solid rgba(225, 227, 232, 0.9);
background: #ffffff;
content: '';
transform: rotate(45deg);
}
.mentor-bubble-text {
color: #25282d;
font-size: 16px;
font-weight: 600;
line-height: 1.5;
}
.login-card {
@@ -310,7 +338,7 @@ onShow(() => {
gap: 18px;
max-width: 720px;
margin: 0 auto;
padding: 36px 20px 36px;
padding: 28px 20px 28px;
border: 1px solid rgba(225, 227, 232, 0.95);
border-top: 4px solid #e60012;
border-radius: 18px;
@@ -470,6 +498,16 @@ onShow(() => {
border-radius: 10px;
}
.agreement {
display: block;
max-width: 720px;
margin: 16px auto 0;
color: #a4a8b0;
font-size: 12px;
line-height: 1.5;
text-align: center;
}
@media (max-width: 375px) {
.login-shell {
padding-right: 32px;
@@ -482,8 +520,9 @@ onShow(() => {
font-size: 17px;
}
.login-head .page-title {
font-size: 32px;
.mentor-image {
width: 112px;
height: 114px;
}
.code-row {
+6 -5
View File
@@ -17,7 +17,7 @@
<scroll-view scroll-y class="chat-thread" :scroll-top="threadScrollTop" :scroll-with-animation="true">
<view class="thread-inner">
<view class="bubble-row left">
<view class="avatar master-avatar">师</view>
<image class="avatar master-avatar" src="/static/mentor-female-avatar.png" mode="aspectFill" />
<view class="bubble master">
<text class="bubble-text">你好,我是老师傅。工作里的 SOP、话术、流程直接问我,答案都带引用依据;也可以按住下面的按钮说话。</text>
</view>
@@ -37,14 +37,14 @@
</view>
<view v-else-if="msg.role === 'pending'" class="bubble-row left">
<view class="avatar master-avatar">师</view>
<image class="avatar master-avatar" src="/static/mentor-female-avatar.png" mode="aspectFill" />
<view class="bubble master pending-bubble">
<text class="bubble-text">师傅思考中…</text>
</view>
</view>
<view v-else class="bubble-row left">
<view class="avatar master-avatar">师</view>
<image class="avatar master-avatar" src="/static/mentor-female-avatar.png" mode="aspectFill" />
<view class="master-col">
<view v-if="msg.voiceStatus !== 'unavailable'" class="voice-line">
<view
@@ -154,7 +154,7 @@
</template>
<view v-if="!loggedIn" class="bubble-row left">
<view class="avatar master-avatar">师</view>
<image class="avatar master-avatar" src="/static/mentor-female-avatar.png" mode="aspectFill" />
<view class="bubble master">
<text class="bubble-text">登录后才能查询 SOP、生成总结卡并反馈答案。</text>
<view class="bubble-actions">
@@ -2066,7 +2066,8 @@ onUnload(() => {
}
.master-avatar {
background: #e70014;
overflow: hidden;
background: #f3f4f6;
color: #ffffff;
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -151,7 +151,7 @@ export const createSpeechPlaybackController = (
const utterance = new window.SpeechSynthesisUtterance(value.slice(0, 600));
utterance.lang = 'zh-CN';
utterance.rate = profile?.speed || 0.95;
utterance.pitch = profile?.role === 'mentor' ? 0.85 : profile?.role === 'customer' ? 1.05 : 1;
utterance.pitch = profile?.role === 'mentor' ? 1.06 : profile?.role === 'customer' ? 1.05 : 1;
utterance.onend = () => {
if (currentGeneration === generation && activeKey === key) stop();
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB