ソースを参照

fix: 移动端新建会话加载反馈 + 登录协议前置校验

## 移动端新建会话没有等待反馈
桌面端在弹窗里显示「正在准备会话…」,移动端点选容器后面板立刻关闭,
要等 0.6~0.7 秒建房完成才跳转 —— 这段时间屏幕上什么都没发生。
现在会话页在建房期间显示「正在准备会话…」。

## 登录页协议勾选
移动端 sendCode() 原先完全不检查 agreed,
用户不勾协议也能发出验证码,到登录那步才被拦。
现在获取验证码前就校验并提示。

Co-Authored-By: Claude Code <noreply@anthropic.com>
Huccct 2 時間 前
親
コミット
1ad98a0393
2 ファイル変更、41 行追加、2 行削除
  1. 30 2
      src/app/mobile/pages/chat/chat.ts
  2. 11 0
      src/app/mobile/pages/login/login.ts

+ 30 - 2
src/app/mobile/pages/chat/chat.ts

@@ -175,7 +175,13 @@ type SheetTab = 'task' | 'file' | 'deliver' | 'state';
             />
           }
           @case ('empty') {
-            @if (chat.emptyReason() === 'removed') {
+            @if (preparingRoom()) {
+              <!-- 新建会话建房间中(2026-11-13):给出明确反馈,避免「点了没反应」 -->
+              <div class="m-loading" role="status" aria-live="polite" aria-label="正在准备会话">
+                <span class="m-typing"><i></i><i></i><i></i></span>
+                <p class="m-loading-text">正在准备会话…</p>
+              </div>
+            } @else if (chat.emptyReason() === 'removed') {
               <!-- 已软删会话(2026-11-09 用户裁决):URL 直达也不认领 -->
               <app-m-empty
                 icon="fa-solid fa-trash-can"
@@ -596,8 +602,15 @@ type SheetTab = 'task' | 'file' | 'deliver' | 'state';
       .m-loading {
         display: grid;
         place-items: center;
+        gap: var(--sp-3);
         padding: var(--sp-8);
       }
+      /* 建会话/加载中的说明文字(2026-11-13) */
+      .m-loading-text {
+        margin: 0;
+        font-size: var(--fs-13);
+        color: var(--muted);
+      }
       .m-typing {
         display: inline-flex;
         gap: 4px;
@@ -888,6 +901,15 @@ export class MbChatPage implements OnDestroy {
   protected readonly sheetOpen = signal(false);
   /** 图片走灯箱 */
   protected readonly lightbox = signal<{ url: string; name: string; size: number } | null>(null);
+  /**
+   * 正在为新建会话开独立房间(2026-11-13)。
+   *
+   * 🔴 桌面端在「新建对话」弹窗里显示「正在准备会话…」,移动端没有对应位置 ——
+   *    点选容器后面板立刻关闭,要等 0.6~0.7 秒建房完成才跳转,
+   *    这段时间屏幕上什么都没发生,用户以为点了没反应(真机实测反馈)。
+   *    这里在会话页给出明确反馈。
+   */
+  protected readonly preparingRoom = signal(false);
   /** 其余文件走全屏预览 */
   protected readonly preview = signal<{ url: string; name: string; mimeType: string } | null>(null);
   protected readonly sheetTab = signal<SheetTab>('task');
@@ -1399,7 +1421,13 @@ export class MbChatPage implements OnDestroy {
     if (sessionId === 'new') {
       const ws = this.route.snapshot.queryParamMap.get('ws');
       /* 一房间一会话:建房完成后再进入(2026-11-12,与桌面端同口径) */
-      const created = await this.chat.startBlankWithRoom(agentId, ws || null);
+      this.preparingRoom.set(true);
+      let created: Awaited<ReturnType<typeof this.chat.startBlankWithRoom>> = null;
+      try {
+        created = await this.chat.startBlankWithRoom(agentId, ws || null);
+      } finally {
+        this.preparingRoom.set(false);
+      }
       if (created) {
         /*
          * 首页输入坞带过来的草稿(2026-11-09):用户先在首页打字、再选人,

+ 11 - 0
src/app/mobile/pages/login/login.ts

@@ -401,6 +401,17 @@ export class MbLoginPage implements OnDestroy {
       this.error.set('请输入正确的 11 位手机号');
       return;
     }
+    /*
+     * 🔴 获取验证码前必须先勾选协议(2026-11-13 用户反馈)。
+     *
+     * 原先只有 `submit()` 检查,`sendCode()` 完全没管 ——
+     * 用户不勾协议也能把验证码发出去,到了登录那步才被拦,
+     * 体验上是「先给了希望再拒绝」。现在前置到发送前。
+     */
+    if (!this.agreed()) {
+      this.error.set('请先阅读并同意《服务协议》和《隐私政策》');
+      return;
+    }
     this.sending.set(true);
     try {
       await this.api.sendMobileCode(this.phone());