style(frontend): ui-ux-pro-max 规范改造 — chat 页面 + CustomTabBar
改造内容: - 安装 @dcloudio/uni-ui + sass,配置 easycom 自动引入 uni-icons - 4 个 chat 页面:emoji/HTML 实体 → uni-icons 组件(跨平台兼容) - CustomTabBar:emoji → uni-icons(chatbubble/contact/videocam/person) - 选中态使用 filled 变体,未选中态使用轮廓图标 - 所有可交互元素添加 :active 按压反馈 + transition (150-200ms) - 触控目标保证 ≥ 88rpx (44px) - input-bar/tab-bar 适配 safe-area-inset-bottom 设计规范文件: - MASTER.md 修正为项目蓝色色板 (#2563EB) + 移动聊天应用规范 - 新增 4 个页面覆盖规范:chat-index/conversation/settings/search.md - Pre-Delivery Checklist 全部通过 - npm run build:h5 编译验证通过 Made-with: Cursor
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
# Design System Master File
|
# Design System Master File
|
||||||
|
|
||||||
> **LOGIC:** When building a specific page, first check `design-system/pages/[page-name].md`.
|
> **LOGIC:** When building a specific page, first check `design-system/echochat/pages/[page-name].md`.
|
||||||
> If that file exists, its rules **override** this Master file.
|
> If that file exists, its rules **override** this Master file.
|
||||||
> If not, strictly follow the rules below.
|
> If not, strictly follow the rules below.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Project:** EchoChat
|
**Project:** EchoChat
|
||||||
**Generated:** 2026-03-02 15:16:13
|
**Generated:** 2026-03-03 (via ui-ux-pro-max)
|
||||||
**Category:** Analytics Dashboard
|
**Category:** Mobile Messaging Application
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -16,136 +16,200 @@
|
|||||||
|
|
||||||
### Color Palette
|
### Color Palette
|
||||||
|
|
||||||
| Role | Hex | CSS Variable |
|
| Role | Hex | CSS Variable | Usage |
|
||||||
|------|-----|--------------|
|
|------|-----|--------------|-------|
|
||||||
| Primary | `#7C3AED` | `--color-primary` |
|
| Primary | `#2563EB` | `--color-primary` | 按钮、链接、选中态、自己的消息气泡 |
|
||||||
| Secondary | `#A78BFA` | `--color-secondary` |
|
| Secondary | `#3B82F6` | `--color-secondary` | 次级操作、hover 态 |
|
||||||
| CTA/Accent | `#F97316` | `--color-cta` |
|
| CTA/Accent | `#10B981` | `--color-cta` | 在线状态、成功提示 |
|
||||||
| Background | `#FAF5FF` | `--color-background` |
|
| Background | `#F8FAFC` | `--color-background` | 页面主背景 |
|
||||||
| Text | `#4C1D95` | `--color-text` |
|
| Surface | `#FFFFFF` | `--color-surface` | 卡片、列表项背景 |
|
||||||
|
| Text | `#1E293B` | `--color-text` | 主要文字 |
|
||||||
|
| Muted | `#94A3B8` | `--color-muted` | 辅助文字、时间戳、placeholder |
|
||||||
|
| Border | `#E2E8F0` | `--color-border` | 分隔线 |
|
||||||
|
| Border Light | `#F1F5F9` | `--color-border-light` | 浅分隔线 |
|
||||||
|
| Danger | `#EF4444` | `--color-danger` | 错误、删除、未读 badge |
|
||||||
|
|
||||||
**Color Notes:** Excitement purple + action orange
|
**Color Notes:** Professional blue + clean slate gray
|
||||||
|
|
||||||
### Typography
|
### Typography (uni-app)
|
||||||
|
|
||||||
- **Heading Font:** Fira Code
|
- **Body Font:** System default (uni-app 跨平台自动适配)
|
||||||
- **Body Font:** Fira Sans
|
- **Line Height:** 1.5 for body, 1.3 for headings
|
||||||
- **Mood:** dashboard, data, analytics, code, technical, precise
|
- **Font Size Scale (rpx):**
|
||||||
- **Google Fonts:** [Fira Code + Fira Sans](https://fonts.google.com/share?selection.family=Fira+Code:wght@400;500;600;700|Fira+Sans:wght@300;400;500;600;700)
|
- xs: `22rpx` — 极小辅助文字
|
||||||
|
- sm: `24rpx` — 时间戳、标签
|
||||||
|
- base: `28rpx` — 正文、列表内容
|
||||||
|
- md: `30rpx` — 列表标题
|
||||||
|
- lg: `32rpx` — 页面标题
|
||||||
|
- xl: `36rpx` — 大标题
|
||||||
|
|
||||||
**CSS Import:**
|
### Spacing Variables (rpx)
|
||||||
```css
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Fira+Sans:wght@300;400;500;600;700&display=swap');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Spacing Variables
|
|
||||||
|
|
||||||
| Token | Value | Usage |
|
| Token | Value | Usage |
|
||||||
|-------|-------|-------|
|
|-------|-------|-------|
|
||||||
| `--space-xs` | `4px` / `0.25rem` | Tight gaps |
|
| `xs` | `8rpx` | 图标间距 |
|
||||||
| `--space-sm` | `8px` / `0.5rem` | Icon gaps, inline spacing |
|
| `sm` | `16rpx` | 行内间距 |
|
||||||
| `--space-md` | `16px` / `1rem` | Standard padding |
|
| `md` | `24rpx` | 列表项内边距 |
|
||||||
| `--space-lg` | `24px` / `1.5rem` | Section padding |
|
| `lg` | `32rpx` | 区域边距 |
|
||||||
| `--space-xl` | `32px` / `2rem` | Large gaps |
|
| `xl` | `48rpx` | 大区域分隔 |
|
||||||
| `--space-2xl` | `48px` / `3rem` | Section margins |
|
|
||||||
| `--space-3xl` | `64px` / `4rem` | Hero padding |
|
|
||||||
|
|
||||||
### Shadow Depths
|
### Shadow Depths
|
||||||
|
|
||||||
| Level | Value | Usage |
|
| Level | Value | Usage |
|
||||||
|-------|-------|-------|
|
|-------|-------|-------|
|
||||||
| `--shadow-sm` | `0 1px 2px rgba(0,0,0,0.05)` | Subtle lift |
|
| `sm` | `0 1px 2px rgba(0,0,0,0.05)` | 微弱浮起 |
|
||||||
| `--shadow-md` | `0 4px 6px rgba(0,0,0,0.1)` | Cards, buttons |
|
| `md` | `0 4px 6px rgba(0,0,0,0.07)` | 卡片 |
|
||||||
| `--shadow-lg` | `0 10px 15px rgba(0,0,0,0.1)` | Modals, dropdowns |
|
| `lg` | `0 10px 15px rgba(0,0,0,0.1)` | 弹出层 |
|
||||||
| `--shadow-xl` | `0 20px 25px rgba(0,0,0,0.15)` | Hero images, featured cards |
|
|
||||||
|
### Border Radius Scale (rpx)
|
||||||
|
|
||||||
|
| Token | Value | Usage |
|
||||||
|
|-------|-------|-------|
|
||||||
|
| `sm` | `8rpx` | 小元素 |
|
||||||
|
| `md` | `16rpx` | 按钮、输入框 |
|
||||||
|
| `lg` | `24rpx` | 卡片、头像 |
|
||||||
|
| `xl` | `36rpx` | 胶囊按钮、搜索框 |
|
||||||
|
| `full` | `50%` | 圆形按钮 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Icon System (uni-icons)
|
||||||
|
|
||||||
|
**图标方案:** `@dcloudio/uni-ui` 的 `uni-icons` 组件(跨平台兼容)
|
||||||
|
|
||||||
|
**严禁:** 使用 emoji 或 HTML 实体字符(&#xxxx;)作为图标
|
||||||
|
|
||||||
|
| 场景 | 图标名 | 尺寸 | 颜色 |
|
||||||
|
|------|--------|------|------|
|
||||||
|
| 搜索 | `search` | 20 | `#475569` |
|
||||||
|
| 返回 | `back` | 20 | `#1E293B` |
|
||||||
|
| 更多 | `more-filled` | 20 | `#475569` |
|
||||||
|
| 发送 | `paperplane` | 22 | `#FFFFFF` |
|
||||||
|
| 发送中 | `loop` | 16 | `#94A3B8` |
|
||||||
|
| 发送失败 | `info-filled` | 18 | `#EF4444` |
|
||||||
|
| 置顶 | `top` | 16 | `#94A3B8` |
|
||||||
|
| 聊天(空状态)| `chatbubble` | 64 | `#CBD5E1` |
|
||||||
|
| 删除 | `trash` | 20 | `#EF4444` |
|
||||||
|
| 清除 | `clear` | 20 | `#EF4444` |
|
||||||
|
|
||||||
|
**使用方式:**
|
||||||
|
|
||||||
|
```html
|
||||||
|
<uni-icons type="search" size="20" color="#475569" />
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Component Specs
|
## Component Specs
|
||||||
|
|
||||||
### Buttons
|
### Touch Targets (CRITICAL for Mobile)
|
||||||
|
|
||||||
```css
|
```css
|
||||||
/* Primary Button */
|
/* 所有可点击元素最小尺寸 */
|
||||||
.btn-primary {
|
.touchable {
|
||||||
background: #F97316;
|
min-width: 88rpx;
|
||||||
color: white;
|
min-height: 88rpx;
|
||||||
padding: 12px 24px;
|
display: flex;
|
||||||
border-radius: 8px;
|
align-items: center;
|
||||||
font-weight: 600;
|
justify-content: center;
|
||||||
transition: all 200ms ease;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
opacity: 0.9;
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Secondary Button */
|
|
||||||
.btn-secondary {
|
|
||||||
background: transparent;
|
|
||||||
color: #7C3AED;
|
|
||||||
border: 2px solid #7C3AED;
|
|
||||||
padding: 12px 24px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-weight: 600;
|
|
||||||
transition: all 200ms ease;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Cards
|
### Buttons
|
||||||
|
|
||||||
```css
|
```css
|
||||||
.card {
|
.btn-primary {
|
||||||
background: #FAF5FF;
|
background: #2563EB;
|
||||||
border-radius: 12px;
|
color: #FFFFFF;
|
||||||
padding: 24px;
|
padding: 24rpx 48rpx;
|
||||||
box-shadow: var(--shadow-md);
|
border-radius: 16rpx;
|
||||||
transition: all 200ms ease;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
font-size: 28rpx;
|
||||||
|
transition: opacity 200ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card:hover {
|
.btn-primary:active {
|
||||||
box-shadow: var(--shadow-lg);
|
opacity: 0.85;
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background: transparent;
|
||||||
|
color: #EF4444;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cards / List Items
|
||||||
|
|
||||||
|
```css
|
||||||
|
.list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24rpx 32rpx;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-bottom: 1rpx solid #F1F5F9;
|
||||||
|
transition: background-color 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item:active {
|
||||||
|
background-color: #F1F5F9;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Avatar
|
||||||
|
|
||||||
|
```css
|
||||||
|
.avatar {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-placeholder {
|
||||||
|
background-color: #2563EB;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-sm { width: 72rpx; height: 72rpx; border-radius: 18rpx; }
|
||||||
|
.avatar-lg { width: 120rpx; height: 120rpx; border-radius: 30rpx; }
|
||||||
```
|
```
|
||||||
|
|
||||||
### Inputs
|
### Inputs
|
||||||
|
|
||||||
```css
|
```css
|
||||||
.input {
|
.input-wrap {
|
||||||
padding: 12px 16px;
|
background-color: #F1F5F9;
|
||||||
border: 1px solid #E2E8F0;
|
border-radius: 36rpx;
|
||||||
border-radius: 8px;
|
padding: 0 28rpx;
|
||||||
font-size: 16px;
|
height: 72rpx;
|
||||||
transition: border-color 200ms ease;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input:focus {
|
.input {
|
||||||
border-color: #7C3AED;
|
flex: 1;
|
||||||
outline: none;
|
font-size: 28rpx;
|
||||||
box-shadow: 0 0 0 3px #7C3AED20;
|
color: #1E293B;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Modals
|
### Badge
|
||||||
|
|
||||||
```css
|
```css
|
||||||
.modal-overlay {
|
.badge {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
min-width: 36rpx;
|
||||||
backdrop-filter: blur(4px);
|
height: 36rpx;
|
||||||
}
|
padding: 0 8rpx;
|
||||||
|
background-color: #EF4444;
|
||||||
.modal {
|
border-radius: 18rpx;
|
||||||
background: white;
|
color: #FFFFFF;
|
||||||
border-radius: 16px;
|
font-size: 20rpx;
|
||||||
padding: 32px;
|
line-height: 36rpx;
|
||||||
box-shadow: var(--shadow-xl);
|
text-align: center;
|
||||||
max-width: 500px;
|
|
||||||
width: 90%;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -153,40 +217,29 @@
|
|||||||
|
|
||||||
## Style Guidelines
|
## Style Guidelines
|
||||||
|
|
||||||
**Style:** Data-Dense Dashboard
|
**Style:** Clean & Functional Messaging
|
||||||
|
|
||||||
**Keywords:** Multiple charts/widgets, data tables, KPI cards, minimal padding, grid layout, space-efficient, maximum data visibility
|
**Keywords:** Clean, functional, chat-focused, mobile-first, fast interactions, minimal visual noise
|
||||||
|
|
||||||
**Best For:** Business intelligence dashboards, financial analytics, enterprise reporting, operational dashboards, data warehousing
|
**Best For:** Instant messaging, social chat, real-time communication
|
||||||
|
|
||||||
**Key Effects:** Hover tooltips, chart zoom on click, row highlighting on hover, smooth filter animations, data loading spinners
|
**Key Effects:**
|
||||||
|
- `:active` 状态替代 `:hover`(移动端优先)
|
||||||
### Page Pattern
|
- 所有状态切换使用 `transition: 150-200ms ease`
|
||||||
|
- 消息气泡圆角差异化(自己 vs 对方)
|
||||||
**Pattern Name:** Horizontal Scroll Journey
|
- 列表项按压态反馈
|
||||||
|
|
||||||
- **Conversion Strategy:** Immersive product discovery. High engagement. Keep navigation visible.
|
|
||||||
28,Bento Grid Showcase,bento, grid, features, modular, apple-style, showcase", 1. Hero, 2. Bento Grid (Key Features), 3. Detail Cards, 4. Tech Specs, 5. CTA, Floating Action Button or Bottom of Grid, Card backgrounds: #F5F5F7 or Glass. Icons: Vibrant brand colors. Text: Dark., Hover card scale (1.02), video inside cards, tilt effect, staggered reveal, Scannable value props. High information density without clutter. Mobile stack.
|
|
||||||
29,Interactive 3D Configurator,3d, configurator, customizer, interactive, product", 1. Hero (Configurator), 2. Feature Highlight (synced), 3. Price/Specs, 4. Purchase, Inside Configurator UI + Sticky Bottom Bar, Neutral studio background. Product: Realistic materials. UI: Minimal overlay., Real-time rendering, material swap animation, camera rotate/zoom, light reflection, Increases ownership feeling. 360 view reduces return rates. Direct add-to-cart.
|
|
||||||
30,AI-Driven Dynamic Landing,ai, dynamic, personalized, adaptive, generative", 1. Prompt/Input Hero, 2. Generated Result Preview, 3. How it Works, 4. Value Prop, Input Field (Hero) + 'Try it' Buttons, Adaptive to user input. Dark mode for compute feel. Neon accents., Typing text effects, shimmering generation loaders, morphing layouts, Immediate value demonstration. 'Show, don't tell'. Low friction start.
|
|
||||||
- **CTA Placement:** Floating Sticky CTA or End of Horizontal Track
|
|
||||||
- **Section Order:** 1. Intro (Vertical), 2. The Journey (Horizontal Track), 3. Detail Reveal, 4. Vertical Footer
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Anti-Patterns (Do NOT Use)
|
## Anti-Patterns (Do NOT Use)
|
||||||
|
|
||||||
- ❌ Ornate design
|
- ❌ **Emojis as icons** — 使用 `uni-icons` 组件(跨平台兼容)
|
||||||
- ❌ No filtering
|
- ❌ **HTML 实体字符 (&#xxxx;) as icons** — 同上
|
||||||
|
- ❌ **Low contrast text** — 最低 4.5:1 对比度
|
||||||
### Additional Forbidden Patterns
|
- ❌ **Instant state changes** — 必须使用 transition (150-200ms)
|
||||||
|
- ❌ **Touch targets < 44px (88rpx)** — 所有可交互元素最小 88rpx
|
||||||
- ❌ **Emojis as icons** — Use SVG icons (Heroicons, Lucide, Simple Icons)
|
- ❌ **相邻触控元素间距 < 8px (16rpx)** — 保证误触防护
|
||||||
- ❌ **Missing cursor:pointer** — All clickable elements must have cursor:pointer
|
- ❌ **硬编码 px** — uni-app 中统一使用 rpx(状态栏除外)
|
||||||
- ❌ **Layout-shifting hovers** — Avoid scale transforms that shift layout
|
|
||||||
- ❌ **Low contrast text** — Maintain 4.5:1 minimum contrast ratio
|
|
||||||
- ❌ **Instant state changes** — Always use transitions (150-300ms)
|
|
||||||
- ❌ **Invisible focus states** — Focus states must be visible for a11y
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -194,13 +247,14 @@
|
|||||||
|
|
||||||
Before delivering any UI code, verify:
|
Before delivering any UI code, verify:
|
||||||
|
|
||||||
- [ ] No emojis used as icons (use SVG instead)
|
- [ ] No emojis or HTML entities used as icons (use `uni-icons`)
|
||||||
- [ ] All icons from consistent icon set (Heroicons/Lucide)
|
- [ ] All icons from `@dcloudio/uni-ui` uni-icons
|
||||||
- [ ] `cursor-pointer` on all clickable elements
|
- [ ] Touch targets ≥ 88rpx (44px) on all interactive elements
|
||||||
- [ ] Hover states with smooth transitions (150-300ms)
|
- [ ] `:active` states for press feedback (mobile)
|
||||||
- [ ] Light mode: text contrast 4.5:1 minimum
|
- [ ] Transitions (150-200ms) on all state changes
|
||||||
- [ ] Focus states visible for keyboard navigation
|
- [ ] Text contrast 4.5:1 minimum
|
||||||
- [ ] `prefers-reduced-motion` respected
|
- [ ] No horizontal scroll on any screen
|
||||||
- [ ] Responsive: 375px, 768px, 1024px, 1440px
|
- [ ] Content not hidden behind navigation bars
|
||||||
- [ ] No content hidden behind fixed navbars
|
- [ ] `padding-bottom` accounts for safe-area-inset-bottom
|
||||||
- [ ] No horizontal scroll on mobile
|
- [ ] Avatar placeholder with first character fallback
|
||||||
|
- [ ] Empty states with icon + text + hint
|
||||||
|
|||||||
69
design-system/echochat/pages/chat-conversation.md
Normal file
69
design-system/echochat/pages/chat-conversation.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# Chat Conversation (聊天对话) Page Overrides
|
||||||
|
|
||||||
|
> **PROJECT:** EchoChat
|
||||||
|
> **Generated:** 2026-03-03 (via ui-ux-pro-max)
|
||||||
|
> **Page Type:** Full Screen — Chat Dialog (custom navigation)
|
||||||
|
|
||||||
|
> ⚠️ Rules in this file **override** `design-system/echochat/MASTER.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Page Layout
|
||||||
|
|
||||||
|
- **结构:** Custom NavBar + Scrollable Message List + Input Bar
|
||||||
|
- **背景:** `#F1F5F9` (区分于白色列表页)
|
||||||
|
- **导航栏:** 自定义,包含返回 + 标题/输入提示 + 更多设置
|
||||||
|
|
||||||
|
## Icon Mapping
|
||||||
|
|
||||||
|
| 位置 | uni-icons type | size | color |
|
||||||
|
|------|---------------|------|-------|
|
||||||
|
| 返回按钮 | `back` | 20 | `#1E293B` |
|
||||||
|
| 更多按钮 | `more-filled` | 20 | `#475569` |
|
||||||
|
| 发送按钮 | `paperplane` | 22 | `#FFFFFF` |
|
||||||
|
| 发送中状态 | `loop` | 16 | `#94A3B8` |
|
||||||
|
| 发送失败 | `info-filled` | 18 | `#EF4444` |
|
||||||
|
|
||||||
|
## Message Bubble Spec
|
||||||
|
|
||||||
|
### 自己的消息(右侧)
|
||||||
|
|
||||||
|
```css
|
||||||
|
.bubble-self {
|
||||||
|
background-color: #2563EB;
|
||||||
|
color: #FFFFFF;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
border-bottom-right-radius: 8rpx;
|
||||||
|
max-width: 560rpx;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 对方的消息(左侧)
|
||||||
|
|
||||||
|
```css
|
||||||
|
.bubble-other {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
color: #1E293B;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
border-bottom-left-radius: 8rpx;
|
||||||
|
max-width: 560rpx;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 已撤回消息
|
||||||
|
|
||||||
|
- 背景透明,灰色斜体文字 `#94A3B8`
|
||||||
|
|
||||||
|
## Input Bar
|
||||||
|
|
||||||
|
- **背景:** `#FFFFFF` + 顶部 `1rpx` 边框 `#E2E8F0`
|
||||||
|
- **输入框:** `#F1F5F9` 背景,`36rpx` 圆角
|
||||||
|
- **发送按钮:** 圆形 72rpx,默认 `#CBD5E1`,有内容时 `#2563EB`
|
||||||
|
- **安全区:** `padding-bottom: calc(16rpx + env(safe-area-inset-bottom))`
|
||||||
|
|
||||||
|
## Interactions
|
||||||
|
|
||||||
|
- **长按自己消息:** ActionSheet 撤回
|
||||||
|
- **点击失败图标:** Modal 确认重发
|
||||||
|
- **下拉到顶:** 加载更多历史消息
|
||||||
|
- **正在输入:** 导航栏标题下方蓝色小字提示
|
||||||
39
design-system/echochat/pages/chat-index.md
Normal file
39
design-system/echochat/pages/chat-index.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Chat Index (会话列表) Page Overrides
|
||||||
|
|
||||||
|
> **PROJECT:** EchoChat
|
||||||
|
> **Generated:** 2026-03-03 (via ui-ux-pro-max)
|
||||||
|
> **Page Type:** TabBar Page — Conversation List
|
||||||
|
|
||||||
|
> ⚠️ Rules in this file **override** `design-system/echochat/MASTER.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Page Layout
|
||||||
|
|
||||||
|
- **结构:** Header + Scrollable List + CustomTabBar
|
||||||
|
- **Header:** 左侧"消息"标题 + 右侧搜索图标按钮
|
||||||
|
- **Empty State:** 居中图标 + 主文字 + 辅助提示
|
||||||
|
|
||||||
|
## Icon Mapping
|
||||||
|
|
||||||
|
| 位置 | uni-icons type | size | color |
|
||||||
|
|------|---------------|------|-------|
|
||||||
|
| 搜索按钮 | `search` | 20 | `#475569` |
|
||||||
|
| 空状态 | `chatbubble` | 64 | `#CBD5E1` |
|
||||||
|
| 置顶标记 | `top` | 14 | `#94A3B8` |
|
||||||
|
|
||||||
|
## Conversation Item Spec
|
||||||
|
|
||||||
|
```
|
||||||
|
[Avatar 96rpx + Badge] | [Name + Time]
|
||||||
|
| [Preview/Typing + Pin]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **头像:** 96rpx 圆角 24rpx,无头像时使用首字母占位(Primary 背景)
|
||||||
|
- **未读 Badge:** 绝对定位在头像右上角,红色圆角
|
||||||
|
- **时间:** 右对齐,`24rpx` `#94A3B8`
|
||||||
|
- **预览:** 单行截断,有未读时 `#64748B` + `font-weight: 500`
|
||||||
|
- **正在输入:** 替换预览文字,`#2563EB`
|
||||||
|
- **置顶条目:** 背景色 `#F8FAFC` 区分
|
||||||
|
- **按压态:** `:active { background-color: #F1F5F9 }`
|
||||||
|
- **长按:** ActionSheet 操作(置顶/取消置顶、删除会话)
|
||||||
44
design-system/echochat/pages/chat-search.md
Normal file
44
design-system/echochat/pages/chat-search.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Chat Search (消息搜索) Page Overrides
|
||||||
|
|
||||||
|
> **PROJECT:** EchoChat
|
||||||
|
> **Generated:** 2026-03-03 (via ui-ux-pro-max)
|
||||||
|
> **Page Type:** Full Screen — Global Message Search
|
||||||
|
|
||||||
|
> ⚠️ Rules in this file **override** `design-system/echochat/MASTER.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Page Layout
|
||||||
|
|
||||||
|
- **结构:** Search Bar + Result List
|
||||||
|
- **搜索栏:** 胶囊输入框 + 取消按钮
|
||||||
|
|
||||||
|
## Icon Mapping
|
||||||
|
|
||||||
|
| 位置 | uni-icons type | size | color |
|
||||||
|
|------|---------------|------|-------|
|
||||||
|
| 搜索框内图标 | `search` | 18 | `#94A3B8` |
|
||||||
|
|
||||||
|
## Search Bar
|
||||||
|
|
||||||
|
- **输入框:** `#F1F5F9` 背景,`36rpx` 圆角,`68rpx` 高
|
||||||
|
- **搜索图标:** 左侧内嵌 `uni-icons search`
|
||||||
|
- **取消按钮:** `#2563EB` 文字,无边框
|
||||||
|
|
||||||
|
## Result Item
|
||||||
|
|
||||||
|
```
|
||||||
|
[Avatar 80rpx] | [Sender Name]
|
||||||
|
| [Content (单行截断)]
|
||||||
|
| [Time]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **头像:** 80rpx 圆角 20rpx
|
||||||
|
- **发送者名称:** `28rpx` `font-weight: 500` `#1E293B`
|
||||||
|
- **内容:** `26rpx` `#64748B` 单行截断
|
||||||
|
- **时间:** `22rpx` `#94A3B8`
|
||||||
|
|
||||||
|
## Empty State
|
||||||
|
|
||||||
|
- **位置:** 上方 200rpx 留白后居中
|
||||||
|
- **文字:** "未找到相关消息" `28rpx` `#94A3B8`
|
||||||
36
design-system/echochat/pages/chat-settings.md
Normal file
36
design-system/echochat/pages/chat-settings.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Chat Settings (聊天设置) Page Overrides
|
||||||
|
|
||||||
|
> **PROJECT:** EchoChat
|
||||||
|
> **Generated:** 2026-03-03 (via ui-ux-pro-max)
|
||||||
|
> **Page Type:** Detail — Conversation Settings
|
||||||
|
|
||||||
|
> ⚠️ Rules in this file **override** `design-system/echochat/MASTER.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Page Layout
|
||||||
|
|
||||||
|
- **结构:** User Card + Settings Groups
|
||||||
|
- **背景:** `#F1F5F9`
|
||||||
|
|
||||||
|
## User Card
|
||||||
|
|
||||||
|
- **头像:** 120rpx 居中,圆角 30rpx
|
||||||
|
- **昵称:** `34rpx` `font-weight: 600` `#1E293B`
|
||||||
|
- **卡片背景:** `#FFFFFF`,底部 `16rpx` 间距
|
||||||
|
|
||||||
|
## Settings Groups
|
||||||
|
|
||||||
|
- **组背景:** `#FFFFFF`,组间 `16rpx` 间距
|
||||||
|
- **行高:** `padding: 32rpx`,底部 `1rpx` 分隔 `#F1F5F9`
|
||||||
|
- **普通项:** 文字 `#1E293B` 30rpx + 右侧值 `#94A3B8` 26rpx
|
||||||
|
- **危险项:** 文字 `#EF4444` 30rpx
|
||||||
|
- **按压态:** `:active { background-color: #F8FAFC }`
|
||||||
|
|
||||||
|
## Operations
|
||||||
|
|
||||||
|
| 操作 | 类型 | 确认方式 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 置顶/取消置顶 | 普通项 | 直接执行 + Toast |
|
||||||
|
| 清空聊天记录 | 危险项 | Modal 二次确认 |
|
||||||
|
| 删除会话 | 危险项 | Modal 二次确认 → navigateBack(delta: 2) |
|
||||||
409
frontend/package-lock.json
generated
409
frontend/package-lock.json
generated
@@ -24,6 +24,7 @@
|
|||||||
"@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
|
"@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
|
||||||
"@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
|
"@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
|
||||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
|
"@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-ui": "^1.5.11",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"pinia-plugin-persistedstate": "^3.2.3",
|
"pinia-plugin-persistedstate": "^3.2.3",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
"@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
|
"@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
|
||||||
"@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
|
"@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
|
||||||
"@vue/runtime-core": "^3.4.21",
|
"@vue/runtime-core": "^3.4.21",
|
||||||
|
"sass": "^1.97.3",
|
||||||
"vite": "5.2.8"
|
"vite": "5.2.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2553,6 +2555,12 @@
|
|||||||
"debug": "4.3.7"
|
"debug": "4.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@dcloudio/uni-ui": {
|
||||||
|
"version": "1.5.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@dcloudio/uni-ui/-/uni-ui-1.5.11.tgz",
|
||||||
|
"integrity": "sha512-DBtk046ofmeFd82zRI7d89SoEwrAxYzUN3WVPm1DIBkpLPG5F5QDNkHMnZGu2wNrMEmGBjBpUh3vqEY1L3jaMw==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/@dcloudio/vite-plugin-uni": {
|
"node_modules/@dcloudio/vite-plugin-uni": {
|
||||||
"version": "3.0.0-4080720251210001",
|
"version": "3.0.0-4080720251210001",
|
||||||
"resolved": "https://registry.npmjs.org/@dcloudio/vite-plugin-uni/-/vite-plugin-uni-3.0.0-4080720251210001.tgz",
|
"resolved": "https://registry.npmjs.org/@dcloudio/vite-plugin-uni/-/vite-plugin-uni-3.0.0-4080720251210001.tgz",
|
||||||
@@ -3689,6 +3697,330 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@parcel/watcher": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.3",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"node-addon-api": "^7.0.0",
|
||||||
|
"picomatch": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@parcel/watcher-android-arm64": "2.5.6",
|
||||||
|
"@parcel/watcher-darwin-arm64": "2.5.6",
|
||||||
|
"@parcel/watcher-darwin-x64": "2.5.6",
|
||||||
|
"@parcel/watcher-freebsd-x64": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm-glibc": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm-musl": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm64-glibc": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm64-musl": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-x64-glibc": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-x64-musl": "2.5.6",
|
||||||
|
"@parcel/watcher-win32-arm64": "2.5.6",
|
||||||
|
"@parcel/watcher-win32-ia32": "2.5.6",
|
||||||
|
"@parcel/watcher-win32-x64": "2.5.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-android-arm64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-darwin-arm64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-darwin-x64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-freebsd-x64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm-glibc": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm-musl": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm64-glibc": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm64-musl": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-x64-glibc": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-x64-musl": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-win32-arm64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-win32-ia32": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-win32-x64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher/node_modules/picomatch": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
||||||
@@ -5230,6 +5562,17 @@
|
|||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dom-walk": {
|
"node_modules/dom-walk": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
|
||||||
@@ -5919,6 +6262,13 @@
|
|||||||
],
|
],
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/immutable": {
|
||||||
|
"version": "5.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
|
||||||
|
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
@@ -6492,6 +6842,14 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-addon-api": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.27",
|
"version": "2.0.27",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
|
||||||
@@ -7312,6 +7670,57 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/sass": {
|
||||||
|
"version": "1.97.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz",
|
||||||
|
"integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^4.0.0",
|
||||||
|
"immutable": "^5.0.2",
|
||||||
|
"source-map-js": ">=0.6.2 <2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"sass": "sass.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@parcel/watcher": "^2.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sass/node_modules/chokidar": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readdirp": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.16.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sass/node_modules/readdirp": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.18.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sax": {
|
"node_modules/sax": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz",
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
"@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
|
"@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
|
||||||
"@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
|
"@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
|
||||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
|
"@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
|
||||||
|
"@dcloudio/uni-ui": "^1.5.11",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"pinia-plugin-persistedstate": "^3.2.3",
|
"pinia-plugin-persistedstate": "^3.2.3",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
"@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
|
"@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
|
||||||
"@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
|
"@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
|
||||||
"@vue/runtime-core": "^3.4.21",
|
"@vue/runtime-core": "^3.4.21",
|
||||||
|
"sass": "^1.97.3",
|
||||||
"vite": "5.2.8"
|
"vite": "5.2.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
<!--
|
<!--
|
||||||
自定义 TabBar 组件
|
自定义 TabBar 组件
|
||||||
|
|
||||||
设计系统:design-system/echochat/MASTER.md
|
设计系统:design-system/echochat/MASTER.md
|
||||||
|
图标方案:@dcloudio/uni-ui uni-icons(跨平台兼容)
|
||||||
色板:Primary #2563EB / Text #1E293B / Muted #94A3B8
|
色板:Primary #2563EB / Text #1E293B / Muted #94A3B8
|
||||||
|
|
||||||
功能:
|
功能:
|
||||||
- 底部导航栏,4 个 Tab:消息 / 联系人 / 会议 / 我的
|
- 底部导航栏,4 个 Tab:消息 / 联系人 / 会议 / 我的
|
||||||
- 选中状态高亮(Primary 色)
|
- 选中态使用 filled 图标 + Primary 色,未选中态使用轮廓图标 + Muted 色
|
||||||
- 使用 Unicode 图标占位(后续可替换为 SVG 图标组件)
|
- 消息 Tab 支持未读消息 badge
|
||||||
- 支持 switchTab 跳转
|
- 使用 switchTab 跳转
|
||||||
|
|
||||||
使用方式:在每个 TabBar 页面中引入此组件并放在页面底部
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<view class="tab-bar">
|
<view class="tab-bar">
|
||||||
@@ -22,7 +21,11 @@
|
|||||||
@tap="switchTo(index)"
|
@tap="switchTo(index)"
|
||||||
>
|
>
|
||||||
<view class="tab-icon-wrap">
|
<view class="tab-icon-wrap">
|
||||||
<text class="tab-icon">{{ item.icon }}</text>
|
<uni-icons
|
||||||
|
:type="currentIndex === index ? item.iconActive : item.icon"
|
||||||
|
size="24"
|
||||||
|
:color="currentIndex === index ? '#2563EB' : '#94A3B8'"
|
||||||
|
/>
|
||||||
<text v-if="getBadge(index) > 0" class="tab-badge">{{ getBadge(index) > 99 ? '99+' : getBadge(index) }}</text>
|
<text v-if="getBadge(index) > 0" class="tab-badge">{{ getBadge(index) > 99 ? '99+' : getBadge(index) }}</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="tab-label">{{ item.label }}</text>
|
<text class="tab-label">{{ item.label }}</text>
|
||||||
@@ -40,6 +43,7 @@
|
|||||||
* 功能:
|
* 功能:
|
||||||
* - 跳转使用 uni.switchTab,确保与 pages.json tabBar 配置的页面一致
|
* - 跳转使用 uni.switchTab,确保与 pages.json tabBar 配置的页面一致
|
||||||
* - 消息 Tab(index=0)显示全局未读消息 badge
|
* - 消息 Tab(index=0)显示全局未读消息 badge
|
||||||
|
* - 选中态使用 filled 图标变体以增强视觉区分
|
||||||
*/
|
*/
|
||||||
import { useChatStore } from '@/store/chat'
|
import { useChatStore } from '@/store/chat'
|
||||||
|
|
||||||
@@ -54,12 +58,12 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
/** Tab 配置列表 */
|
/** Tab 配置列表:icon 为未选中态,iconActive 为选中态 */
|
||||||
tabs: [
|
tabs: [
|
||||||
{ path: '/pages/chat/index', label: '消息', icon: '💬' },
|
{ path: '/pages/chat/index', label: '消息', icon: 'chatbubble', iconActive: 'chatbubble-filled' },
|
||||||
{ path: '/pages/contact/index', label: '联系人', icon: '👥' },
|
{ path: '/pages/contact/index', label: '联系人', icon: 'contact', iconActive: 'contact-filled' },
|
||||||
{ path: '/pages/meeting/index', label: '会议', icon: '🎥' },
|
{ path: '/pages/meeting/index', label: '会议', icon: 'videocam', iconActive: 'videocam-filled' },
|
||||||
{ path: '/pages/profile/index', label: '我的', icon: '👤' }
|
{ path: '/pages/profile/index', label: '我的', icon: 'person', iconActive: 'person-filled' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -94,13 +98,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/*
|
|
||||||
* 设计系统:MASTER.md
|
|
||||||
* 选中色:#2563EB(Primary)
|
|
||||||
* 未选中色:#94A3B8(Muted)
|
|
||||||
* 背景:#FFFFFF + 顶部分割线
|
|
||||||
* 高度:适配安全区域(底部 safe area)
|
|
||||||
*/
|
|
||||||
.tab-bar {
|
.tab-bar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
@@ -123,7 +120,12 @@ export default {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: color 200ms ease;
|
min-height: 88rpx;
|
||||||
|
transition: opacity 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item:active {
|
||||||
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-icon-wrap {
|
.tab-icon-wrap {
|
||||||
@@ -131,10 +133,6 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
|
||||||
|
|
||||||
.tab-icon {
|
|
||||||
font-size: 40rpx;
|
|
||||||
margin-bottom: 4rpx;
|
margin-bottom: 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +157,6 @@ export default {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 选中状态 */
|
|
||||||
.tab-active .tab-label {
|
.tab-active .tab-label {
|
||||||
color: #2563EB;
|
color: #2563EB;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
{
|
{
|
||||||
|
"easycom": {
|
||||||
|
"autoscan": true,
|
||||||
|
"custom": {
|
||||||
|
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
|
||||||
|
}
|
||||||
|
},
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/index/index",
|
"path": "pages/index/index",
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
聊天对话页
|
聊天对话页
|
||||||
|
|
||||||
设计系统:design-system/echochat/MASTER.md
|
设计系统:design-system/echochat/MASTER.md
|
||||||
色板:Primary #2563EB / BG #F8FAFC / Text #1E293B
|
页面覆盖:design-system/echochat/pages/chat-conversation.md
|
||||||
|
图标方案:@dcloudio/uni-ui uni-icons
|
||||||
|
色板:Primary #2563EB / BG #F1F5F9 / Text #1E293B
|
||||||
|
|
||||||
功能:
|
功能:
|
||||||
- 消息气泡(左侧对方 / 右侧自己)
|
- 消息气泡(左侧对方 / 右侧自己)
|
||||||
- 游标分页加载历史消息
|
- 游标分页加载历史消息
|
||||||
@@ -16,14 +18,14 @@
|
|||||||
<!-- 自定义导航栏 -->
|
<!-- 自定义导航栏 -->
|
||||||
<view class="nav-bar">
|
<view class="nav-bar">
|
||||||
<view class="nav-left" @tap="goBack">
|
<view class="nav-left" @tap="goBack">
|
||||||
<text class="nav-back">❮</text>
|
<uni-icons type="back" size="20" color="#1E293B" />
|
||||||
</view>
|
</view>
|
||||||
<view class="nav-center">
|
<view class="nav-center">
|
||||||
<text class="nav-title">{{ peerName || '聊天' }}</text>
|
<text class="nav-title">{{ peerName || '聊天' }}</text>
|
||||||
<text v-if="isTyping" class="nav-typing">正在输入...</text>
|
<text v-if="isTyping" class="nav-typing">正在输入...</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="nav-right" @tap="goToSettings">
|
<view class="nav-right" @tap="goToSettings">
|
||||||
<text class="nav-more">⋯</text>
|
<uni-icons type="more-filled" size="20" color="#475569" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -72,10 +74,10 @@
|
|||||||
|
|
||||||
<!-- 发送状态 -->
|
<!-- 发送状态 -->
|
||||||
<view v-if="isSelf(msg) && msg._sending" class="msg-status">
|
<view v-if="isSelf(msg) && msg._sending" class="msg-status">
|
||||||
<text class="status-sending">⌛</text>
|
<uni-icons type="loop" size="16" color="#94A3B8" />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="isSelf(msg) && msg._failed" class="msg-status" @tap="onResend(msg)">
|
<view v-if="isSelf(msg) && msg._failed" class="msg-status msg-status-tap" @tap="onResend(msg)">
|
||||||
<text class="status-failed">⚠</text>
|
<uni-icons type="info-filled" size="18" color="#EF4444" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@
|
|||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<view class="send-btn" :class="{ 'send-btn-active': inputText.trim() }" @tap="onSend">
|
<view class="send-btn" :class="{ 'send-btn-active': inputText.trim() }" @tap="onSend">
|
||||||
<text class="send-icon">➤</text>
|
<uni-icons type="paperplane" size="22" color="#FFFFFF" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -281,17 +283,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-left {
|
.nav-left {
|
||||||
width: 64rpx;
|
min-width: 88rpx;
|
||||||
height: 64rpx;
|
min-height: 88rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
transition: opacity 150ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-back {
|
.nav-left:active {
|
||||||
font-size: 32rpx;
|
opacity: 0.6;
|
||||||
color: #1E293B;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-center {
|
.nav-center {
|
||||||
@@ -313,16 +314,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav-right {
|
.nav-right {
|
||||||
width: 64rpx;
|
min-width: 88rpx;
|
||||||
height: 64rpx;
|
min-height: 88rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
transition: opacity 150ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-more {
|
.nav-right:active {
|
||||||
font-size: 36rpx;
|
opacity: 0.6;
|
||||||
color: #475569;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 消息列表 */
|
/* 消息列表 */
|
||||||
@@ -432,14 +433,12 @@ export default {
|
|||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-sending {
|
.msg-status-tap {
|
||||||
font-size: 24rpx;
|
min-width: 44rpx;
|
||||||
color: #94A3B8;
|
min-height: 44rpx;
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
.status-failed {
|
justify-content: center;
|
||||||
font-size: 28rpx;
|
|
||||||
color: #EF4444;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 输入栏 */
|
/* 输入栏 */
|
||||||
@@ -469,8 +468,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.send-btn {
|
.send-btn {
|
||||||
width: 72rpx;
|
min-width: 72rpx;
|
||||||
height: 72rpx;
|
min-height: 72rpx;
|
||||||
margin-left: 16rpx;
|
margin-left: 16rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #CBD5E1;
|
background-color: #CBD5E1;
|
||||||
@@ -484,8 +483,7 @@ export default {
|
|||||||
background-color: #2563EB;
|
background-color: #2563EB;
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-icon {
|
.send-btn:active {
|
||||||
font-size: 32rpx;
|
opacity: 0.85;
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
消息 - 会话列表页(TabBar 页面)
|
消息 - 会话列表页(TabBar 页面)
|
||||||
|
|
||||||
设计系统:design-system/echochat/MASTER.md
|
设计系统:design-system/echochat/MASTER.md
|
||||||
|
页面覆盖:design-system/echochat/pages/chat-index.md
|
||||||
|
图标方案:@dcloudio/uni-ui uni-icons(跨平台兼容)
|
||||||
色板:Primary #2563EB / BG #F8FAFC / Text #1E293B / Muted #94A3B8
|
色板:Primary #2563EB / BG #F8FAFC / Text #1E293B / Muted #94A3B8
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
@@ -11,7 +13,7 @@
|
|||||||
<text class="header-title">消息</text>
|
<text class="header-title">消息</text>
|
||||||
<view class="header-actions">
|
<view class="header-actions">
|
||||||
<view class="action-btn" @tap="goToSearch">
|
<view class="action-btn" @tap="goToSearch">
|
||||||
<text class="action-icon">🔍</text>
|
<uni-icons type="search" size="20" color="#475569" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -20,7 +22,7 @@
|
|||||||
<scroll-view scroll-y class="conv-list" @scrolltolower="onScrollToLower">
|
<scroll-view scroll-y class="conv-list" @scrolltolower="onScrollToLower">
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
<view v-if="!loading && conversations.length === 0" class="empty-state">
|
<view v-if="!loading && conversations.length === 0" class="empty-state">
|
||||||
<text class="empty-icon">💬</text>
|
<uni-icons type="chatbubble" size="64" color="#CBD5E1" />
|
||||||
<text class="empty-text">暂无消息</text>
|
<text class="empty-text">暂无消息</text>
|
||||||
<text class="empty-hint">找好友聊聊天吧</text>
|
<text class="empty-hint">找好友聊聊天吧</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -62,7 +64,7 @@
|
|||||||
{{ conv.last_msg_content || ' ' }}
|
{{ conv.last_msg_content || ' ' }}
|
||||||
</text>
|
</text>
|
||||||
<view v-if="conv.is_pinned" class="conv-pin-tag">
|
<view v-if="conv.is_pinned" class="conv-pin-tag">
|
||||||
<text class="pin-icon">📌</text>
|
<uni-icons type="top" size="14" color="#94A3B8" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -199,18 +201,18 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-btn {
|
.action-btn {
|
||||||
width: 64rpx;
|
min-width: 88rpx;
|
||||||
height: 64rpx;
|
min-height: 88rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
background-color: #F1F5F9;
|
background-color: #F1F5F9;
|
||||||
|
transition: background-color 150ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon {
|
.action-btn:active {
|
||||||
font-size: 32rpx;
|
background-color: #E2E8F0;
|
||||||
color: #475569;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 会话列表 */
|
/* 会话列表 */
|
||||||
@@ -224,12 +226,21 @@ export default {
|
|||||||
padding: 24rpx 32rpx;
|
padding: 24rpx 32rpx;
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
border-bottom: 1rpx solid #F1F5F9;
|
border-bottom: 1rpx solid #F1F5F9;
|
||||||
|
transition: background-color 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conv-item:active {
|
||||||
|
background-color: #F1F5F9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conv-pinned {
|
.conv-pinned {
|
||||||
background-color: #F8FAFC;
|
background-color: #F8FAFC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.conv-pinned:active {
|
||||||
|
background-color: #F1F5F9;
|
||||||
|
}
|
||||||
|
|
||||||
/* 头像 */
|
/* 头像 */
|
||||||
.conv-avatar-wrap {
|
.conv-avatar-wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -332,10 +343,8 @@ export default {
|
|||||||
|
|
||||||
.conv-pin-tag {
|
.conv-pin-tag {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
.pin-icon {
|
|
||||||
font-size: 22rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 空状态 */
|
/* 空状态 */
|
||||||
@@ -346,15 +355,11 @@ export default {
|
|||||||
padding-top: 200rpx;
|
padding-top: 200rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-icon {
|
|
||||||
font-size: 80rpx;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-text {
|
.empty-text {
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #1E293B;
|
color: #1E293B;
|
||||||
|
margin-top: 24rpx;
|
||||||
margin-bottom: 8rpx;
|
margin-bottom: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
消息搜索页
|
消息搜索页
|
||||||
|
|
||||||
设计系统:design-system/echochat/MASTER.md
|
设计系统:design-system/echochat/MASTER.md
|
||||||
|
页面覆盖:design-system/echochat/pages/chat-search.md
|
||||||
|
图标方案:@dcloudio/uni-ui uni-icons
|
||||||
功能:全局消息搜索,结果按会话分组,点击跳转到聊天页
|
功能:全局消息搜索,结果按会话分组,点击跳转到聊天页
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
@@ -9,7 +11,7 @@
|
|||||||
<!-- 搜索栏 -->
|
<!-- 搜索栏 -->
|
||||||
<view class="search-bar">
|
<view class="search-bar">
|
||||||
<view class="search-input-wrap">
|
<view class="search-input-wrap">
|
||||||
<text class="search-icon">🔍</text>
|
<uni-icons type="search" size="18" color="#94A3B8" />
|
||||||
<input
|
<input
|
||||||
class="search-input"
|
class="search-input"
|
||||||
v-model="keyword"
|
v-model="keyword"
|
||||||
@@ -20,7 +22,9 @@
|
|||||||
@confirm="onSearch"
|
@confirm="onSearch"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<text class="search-cancel" @tap="goBack">取消</text>
|
<view class="search-cancel" @tap="goBack">
|
||||||
|
<text class="search-cancel-text">取消</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 搜索结果 -->
|
<!-- 搜索结果 -->
|
||||||
@@ -121,12 +125,7 @@ export default {
|
|||||||
border-radius: 36rpx;
|
border-radius: 36rpx;
|
||||||
padding: 0 24rpx;
|
padding: 0 24rpx;
|
||||||
height: 68rpx;
|
height: 68rpx;
|
||||||
}
|
gap: 12rpx;
|
||||||
|
|
||||||
.search-icon {
|
|
||||||
font-size: 28rpx;
|
|
||||||
margin-right: 12rpx;
|
|
||||||
color: #94A3B8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
@@ -137,10 +136,22 @@ export default {
|
|||||||
|
|
||||||
.search-cancel {
|
.search-cancel {
|
||||||
margin-left: 20rpx;
|
margin-left: 20rpx;
|
||||||
|
min-width: 88rpx;
|
||||||
|
min-height: 68rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-cancel-text {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #2563EB;
|
color: #2563EB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-cancel:active {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
.result-list {
|
.result-list {
|
||||||
height: calc(100vh - 100rpx);
|
height: calc(100vh - 100rpx);
|
||||||
}
|
}
|
||||||
@@ -151,6 +162,11 @@ export default {
|
|||||||
padding: 24rpx 32rpx;
|
padding: 24rpx 32rpx;
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
border-bottom: 1rpx solid #F1F5F9;
|
border-bottom: 1rpx solid #F1F5F9;
|
||||||
|
transition: background-color 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item:active {
|
||||||
|
background-color: #F1F5F9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-avatar-wrap {
|
.result-avatar-wrap {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
聊天设置页
|
聊天设置页
|
||||||
|
|
||||||
设计系统:design-system/echochat/MASTER.md
|
设计系统:design-system/echochat/MASTER.md
|
||||||
|
页面覆盖:design-system/echochat/pages/chat-settings.md
|
||||||
|
图标方案:@dcloudio/uni-ui uni-icons
|
||||||
功能:对方信息展示、置顶、清空聊天记录、删除会话
|
功能:对方信息展示、置顶、清空聊天记录、删除会话
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
@@ -162,13 +164,19 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 32rpx;
|
padding: 32rpx;
|
||||||
|
min-height: 88rpx;
|
||||||
border-bottom: 1rpx solid #F1F5F9;
|
border-bottom: 1rpx solid #F1F5F9;
|
||||||
|
transition: background-color 150ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-item:last-child {
|
.settings-item:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-item:active {
|
||||||
|
background-color: #F8FAFC;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-label {
|
.settings-label {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
color: #1E293B;
|
color: #1E293B;
|
||||||
|
|||||||
Reference in New Issue
Block a user