cc 2 veckor sedan
förälder
incheckning
161393b0c9

+ 22 - 0
.workbuddy-ai/memory/2026-09-18.md

@@ -685,3 +685,25 @@ exit code 0,但不建 loose ref、也不改 `packed-refs` 旧值,`git rev-pa
 
 **已写进技能**:`qingjian-ai-dev` §1 补了「先 `git ls-remote` 确认基线」「update-ref 静默无效的绕过」两条,
 并把验收标准从「三者一致」细化为 4 条命令。
+
+## 登录页加页脚:公司名称 + 联系方式(ai-frontend)
+
+文件:`ai-frontend/src/core/layouts/views/login/index.vue`、`ai-frontend/uno.config.ts`。
+
+- **文案仍是占位**(老爷选了「我现在提供」但没给文字):
+  `XX科技(示例)有限公司` / `400-000-0000` / `service@example.com`,
+  已抽成 `<script setup>` 顶部的三个常量 `footerOrg` / `footerPhone` / `footerEmail`,替换只改这三行。
+- **位置**:卡片**外**、页面底部,随「卡片 + 页脚」整体垂直居中(老爷选的方案)。
+  做法:`.login-page` 由 `align-items/justify-content: center` 的横向 flex 改成 `flex-direction: column`,
+  `.login-card { flex: none }`,新增 `.login-foot { flex: none; margin-top: 26px }`。
+- **关键约束**:全局 `html, body { overflow: hidden !important }`(`src/core/design/index.less`),
+  **登录页不能滚动**,所以不能靠滚动兜底,只能压缩间距。加了 `@media (height <= 720px)`
+  压缩卡片 padding(44/40/36 → 30/36/26)、head margin(38→26)、tip margin(30→22)、footer margin(26→16)。
+- 窄屏 `@media (width <= 480px)`:`.login-foot__contact` 改 `flex-direction: column` 并隐藏分隔线。
+- 图标:`i-mdi:phone-outline`(原有)+ `i-mdi:email-outline`(**新加到 `uno.config.ts` safelist**)。
+  Icon 组件是运行时 `document.createElement` 拼类名,但模板里字面量 `icon="i-mdi:xxx"` 会被 UnoCSS
+  文本扫描到,所以照旧按项目习惯补 safelist 双保险。
+- **实测(1440×900 / 1366×768 / 1280×640 / 390×844)**:均无裁切。
+  `clipTop = card.top` 均为正、`clipBottom = footer.bottom - innerHeight` 均为负。
+  卡片高 439(正常)/ 395(矮屏压缩)/ 402(窄屏);页脚高 48(单行)/ 72(窄屏两行)。
+- 验证:eslint ✅、stylelint ✅、`vue-tsc` 89 个错误(与基线一致,零新增)。

+ 103 - 0
ai-frontend/src/core/layouts/views/login/index.vue

@@ -39,6 +39,21 @@
 
       <p class="login-card__tip">账号由管理员创建,如需开通请联系管理员</p>
     </main>
+
+    <footer class="login-foot">
+      <p class="login-foot__org">{{ footerOrg }}</p>
+      <p class="login-foot__contact">
+        <span class="login-foot__item">
+          <Icon icon="i-mdi:phone-outline" :size="13" />
+          <span>{{ footerPhone }}</span>
+        </span>
+        <span class="login-foot__sep" aria-hidden="true"></span>
+        <span class="login-foot__item">
+          <Icon icon="i-mdi:email-outline" :size="13" />
+          <span>{{ footerEmail }}</span>
+        </span>
+      </p>
+    </footer>
   </div>
 </template>
 
@@ -47,6 +62,16 @@
   import { useRoute, useRouter } from 'vue-router';
   import { PageEnum } from '@/core/enums/pageEnum';
   import { useAccountStore } from '@/core/store/modules/account';
+  import { Icon } from '@/core/components/Icon';
+
+  /**
+   * 页脚展示信息。
+   *
+   * ⚠️ 目前是占位文案,替换时只改这三行即可。
+   */
+  const footerOrg = '中数矩阵(成都)科技有限公司';
+  const footerPhone = '18908093240';
+  const footerEmail = 'service@example.com';
 
   const route = useRoute();
   const router = useRouter();
@@ -82,8 +107,11 @@
 </script>
 
 <style lang="less" scoped>
+  // 全局 `html, body { overflow: hidden !important }`,登录页无法滚动,
+  // 所以卡片 + 页脚整体作为一个居中块,靠短屏 media query 压缩间距来避免裁切。
   .login-page {
     display: flex;
+    flex-direction: column;
     align-items: center;
     justify-content: center;
     width: 100%;
@@ -96,6 +124,7 @@
 
   .login-card {
     position: relative;
+    flex: none;
     width: 420px;
     max-width: 100%;
     padding: 44px 40px 36px;
@@ -107,10 +136,12 @@
       0 18px 40px -18px rgb(16 24 40 / 16%);
     animation: login-rise 0.42s cubic-bezier(25%, 100%, 50%, 100%) both;
 
+    // logo 与标题文字同一排,整组在卡片内水平居中(文字块内部仍左对齐)
     &__head {
       display: flex;
       gap: 14px;
       align-items: center;
+      justify-content: center;
       margin-bottom: 38px;
     }
 
@@ -150,6 +181,45 @@
     }
   }
 
+  // 页脚:公司名称 + 联系方式,位于卡片外、随整体居中
+  .login-foot {
+    flex: none;
+    margin-top: 26px;
+    text-align: center;
+
+    &__org {
+      margin: 0;
+      font-size: 13px;
+      font-weight: 500;
+      letter-spacing: 0.02em;
+      color: @cb-text-secondary;
+    }
+
+    &__contact {
+      display: flex;
+      gap: 10px;
+      align-items: center;
+      justify-content: center;
+      margin: 9px 0 0;
+      font-size: 12px;
+      color: #98a2b3;
+    }
+
+    &__item {
+      display: inline-flex;
+      gap: 5px;
+      align-items: center;
+      white-space: nowrap;
+    }
+
+    &__sep {
+      flex: none;
+      width: 1px;
+      height: 11px;
+      background: #d8dde5;
+    }
+  }
+
   .field__label {
     display: block;
     margin-bottom: 9px;
@@ -266,6 +336,39 @@
     .login-card__title {
       font-size: 17px;
     }
+
+    // 窄屏放不下「电话 | 邮箱」一行,改成上下两行并去掉分隔线
+    .login-foot__contact {
+      flex-direction: column;
+      gap: 5px;
+    }
+
+    .login-foot__sep {
+      display: none;
+    }
+  }
+
+  // 矮屏(1366×768 缩放后、投影仪等)压缩纵向间距,避免卡片 + 页脚被裁切
+  @media (height <= 720px) {
+    .login-page {
+      padding: 16px;
+    }
+
+    .login-card {
+      padding: 30px 36px 26px;
+
+      &__head {
+        margin-bottom: 26px;
+      }
+
+      &__tip {
+        margin-top: 22px;
+      }
+    }
+
+    .login-foot {
+      margin-top: 16px;
+    }
   }
 
   @media (prefers-reduced-motion: reduce) {

+ 2 - 0
ai-frontend/uno.config.ts

@@ -39,6 +39,8 @@ export default defineConfig({
     // 图谱详情面板的通话 / 交易明细入口
     'i-mdi:phone-outline',
     'i-mdi:bank-transfer',
+    // 登录页页脚的联系方式(phone-outline 上面已有)
+    'i-mdi:email-outline',
     // 对话消息排版改造后新增:消息操作条、AI 头像、输入区、回到底部
     'i-mdi:sparkles',
     'i-mdi:content-copy',