feat: batch update - gift card breakdown spec, backend APIs, miniprogram pages, ETL finance recharge, docs & migrations
This commit is contained in:
220
apps/DEMO-miniprogram/miniprogram/pages/notes/DELETE_FEATURE.md
Normal file
220
apps/DEMO-miniprogram/miniprogram/pages/notes/DELETE_FEATURE.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# Notes 页面删除功能实现说明
|
||||
|
||||
## 更新日期
|
||||
2026-03-14
|
||||
|
||||
## 功能描述
|
||||
为每条备注添加删除按钮,放置在日期左侧,交互和逻辑参考任务详情页的备注删除处理方式。
|
||||
|
||||
---
|
||||
|
||||
## 实现细节
|
||||
|
||||
### 1. WXML 结构调整
|
||||
|
||||
#### 原结构
|
||||
```xml
|
||||
<view class="note-bottom">
|
||||
<text class="note-tag">{{item.tagLabel}}</text>
|
||||
<text class="note-time">{{item.createdAt}}</text>
|
||||
</view>
|
||||
```
|
||||
|
||||
#### 新结构
|
||||
```xml
|
||||
<view class="note-bottom">
|
||||
<view class="note-bottom-left">
|
||||
<view class="note-delete-btn" catchtap="onDeleteNote" data-id="{{item.id}}" hover-class="note-delete-btn--hover">
|
||||
<t-icon name="delete" size="20px" color="#a6a6a6" />
|
||||
</view>
|
||||
<text class="note-time">{{item.createdAt}}</text>
|
||||
</view>
|
||||
<text class="note-tag">{{item.tagLabel}}</text>
|
||||
</view>
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
- 使用 `catchtap` 而非 `bindtap`,阻止事件冒泡
|
||||
- 删除按钮放在左侧,日期紧随其后
|
||||
- 标签移到右侧
|
||||
- 通过 `data-id` 传递备注ID
|
||||
|
||||
### 2. WXSS 样式添加
|
||||
|
||||
```wxss
|
||||
/* 底部容器布局调整 */
|
||||
.note-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* 左侧容器(删除按钮 + 日期)*/
|
||||
.note-bottom-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 删除按钮样式 */
|
||||
.note-delete-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.note-delete-btn--hover {
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
```
|
||||
|
||||
**样式说明**:
|
||||
- 删除按钮尺寸:32px × 32px(符合最小点击区域44px的80%)
|
||||
- Icon尺寸:20px(与H5原型对齐)
|
||||
- Icon颜色:#a6a6a6(gray-6,次级文字颜色)
|
||||
- Hover效果:浅灰背景(#f3f3f3)
|
||||
- 按钮与日期间距:8px
|
||||
|
||||
### 3. TypeScript 逻辑实现
|
||||
|
||||
```typescript
|
||||
/** 删除备注 */
|
||||
onDeleteNote(e: WechatMiniprogram.BaseEvent) {
|
||||
const noteId = e.currentTarget.dataset.id as string
|
||||
wx.showModal({
|
||||
title: '删除备注',
|
||||
content: '确定要删除这条备注吗?删除后无法恢复。',
|
||||
confirmColor: '#e34d59',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
const notes = this.data.notes.filter((n) => n.id !== noteId)
|
||||
this.setData({ notes })
|
||||
wx.showToast({ title: '已删除', icon: 'success' })
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
**逻辑说明**:
|
||||
- 从 `dataset` 中获取备注ID
|
||||
- 使用 `wx.showModal` 显示确认弹窗
|
||||
- 确认按钮颜色:#e34d59(error色,警示作用)
|
||||
- 确认后过滤掉对应备注
|
||||
- 显示成功提示
|
||||
|
||||
---
|
||||
|
||||
## 参考实现
|
||||
|
||||
### 任务详情页删除逻辑
|
||||
位置:`apps/miniprogram/miniprogram/pages/task-detail/task-detail.ts`
|
||||
|
||||
```typescript
|
||||
/** 删除备注 */
|
||||
onDeleteNote(e: WechatMiniprogram.BaseEvent) {
|
||||
const noteId = e.currentTarget.dataset.id as string
|
||||
wx.showModal({
|
||||
title: '删除备注',
|
||||
content: '确定要删除这条备注吗?删除后无法恢复。',
|
||||
confirmColor: '#e34d59',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
const notes = this.data.sortedNotes.filter((n) => n.id !== noteId)
|
||||
this.setData({ sortedNotes: notes })
|
||||
wx.showToast({ title: '已删除', icon: 'success' })
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
**差异点**:
|
||||
- 任务详情页使用 `sortedNotes`,notes页使用 `notes`
|
||||
- 其他逻辑完全一致
|
||||
|
||||
---
|
||||
|
||||
## 交互流程
|
||||
|
||||
1. 用户点击删除按钮
|
||||
2. 显示确认弹窗:"确定要删除这条备注吗?删除后无法恢复。"
|
||||
3. 用户选择:
|
||||
- **确认**:删除备注,显示"已删除"提示
|
||||
- **取消**:关闭弹窗,不做任何操作
|
||||
|
||||
---
|
||||
|
||||
## 视觉效果
|
||||
|
||||
### 布局
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 备注内容文本... │
|
||||
│ │
|
||||
│ [🗑️] 2024-11-27 16:00 [客户:王先生] │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 尺寸对比
|
||||
| 元素 | 尺寸 | 说明 |
|
||||
|------|------|------|
|
||||
| 删除按钮容器 | 32px × 32px | 圆形点击区域 |
|
||||
| 删除icon | 20px | TDesign delete图标 |
|
||||
| 按钮与日期间距 | 8px | gap |
|
||||
| 日期字号 | 12px | text-xs |
|
||||
| 标签字号 | 12px | text-xs |
|
||||
|
||||
---
|
||||
|
||||
## 颜色规范
|
||||
|
||||
| 元素 | 颜色 | 色值 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 删除icon | gray-6 | #a6a6a6 | 次级文字颜色 |
|
||||
| Hover背景 | gray-1 | #f3f3f3 | 浅灰背景 |
|
||||
| 确认按钮 | error | #e34d59 | 警示色 |
|
||||
|
||||
---
|
||||
|
||||
## 测试清单
|
||||
|
||||
- [x] 删除按钮显示正确
|
||||
- [x] 删除按钮位置正确(日期左侧)
|
||||
- [x] 点击删除按钮显示确认弹窗
|
||||
- [x] 确认删除后备注消失
|
||||
- [x] 取消删除后备注保留
|
||||
- [x] 删除成功显示提示
|
||||
- [x] Hover效果正常
|
||||
- [x] 事件不冒泡(使用catchtap)
|
||||
- [x] 代码无linting错误
|
||||
|
||||
---
|
||||
|
||||
## 文件变更清单
|
||||
|
||||
1. **notes.wxml** - 添加删除按钮结构
|
||||
2. **notes.wxss** - 添加删除按钮样式
|
||||
3. **notes.ts** - 添加删除逻辑
|
||||
4. **DELETE_FEATURE.md** - 本文档
|
||||
|
||||
---
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **API集成**:当前为前端删除,需要对接后端API实现真实删除
|
||||
2. **撤销功能**:考虑添加"撤销删除"功能(3秒内可撤销)
|
||||
3. **批量删除**:如果需要,可以添加批量删除功能
|
||||
4. **权限控制**:根据用户角色控制删除权限
|
||||
|
||||
---
|
||||
|
||||
## 参考文档
|
||||
|
||||
- 桥文档:`docs/miniprogram-dev/h5-to-mp-bridge-v3.md`
|
||||
- 任务详情页:`apps/miniprogram/miniprogram/pages/task-detail/task-detail.ts`
|
||||
- TDesign图标:https://tdesign.tencent.com/miniprogram/components/icon
|
||||
185
apps/DEMO-miniprogram/miniprogram/pages/notes/MIGRATION_NOTES.md
Normal file
185
apps/DEMO-miniprogram/miniprogram/pages/notes/MIGRATION_NOTES.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Notes 页面迁移说明
|
||||
|
||||
## 迁移版本
|
||||
- **H5 原型基准**:`docs/h5_ui/pages/notes.html`
|
||||
- **桥文档版本**:v3.0
|
||||
- **迁移日期**:2026-03-14
|
||||
|
||||
---
|
||||
|
||||
## 样式调整清单
|
||||
|
||||
### 1. 单位转换规则
|
||||
遵循桥文档 §2.3 的混合单位策略:
|
||||
- **主要使用 `px`**:因为notes页面的尺寸需要与H5原型1:1对齐
|
||||
- **换算基准**:H5 CSS px → 小程序 px(412宽设备验收基准)
|
||||
|
||||
### 2. 导航栏(.custom-nav)
|
||||
|
||||
| 属性 | H5 值 | 小程序值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| height | 44px | 44px | 标准导航栏高度 |
|
||||
| padding | 0 16px | 0 16px | 左右内边距 |
|
||||
| border-bottom | 1px solid | 1px solid #eeeeee | 分割线 |
|
||||
|
||||
**icon 尺寸调整**:
|
||||
- H5: `w-5 h-5` (20px)
|
||||
- 小程序: `size="24px"` (考虑小程序点击区域最小44px)
|
||||
|
||||
### 3. 备注卡片(.note-card)
|
||||
|
||||
| 属性 | H5 值 | 小程序值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| border-radius | rounded-2xl (16px) | 16px | 圆角 |
|
||||
| padding | p-4 (16px) | 16px | 内边距 |
|
||||
| box-shadow | shadow-sm | 0 1px 2px rgba(0,0,0,0.05) | 阴影 |
|
||||
| margin-bottom | mb-3 (12px) | 12px | 卡片间距 |
|
||||
|
||||
### 4. 文本样式
|
||||
|
||||
#### 备注内容(.note-content)
|
||||
| 属性 | H5 值 | 小程序值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| font-size | text-sm (14px) | 14px | 正文字号 |
|
||||
| line-height | leading-relaxed (1.625) | 20px | 行高(按附录B标准) |
|
||||
| color | text-gray-13 | #242424 | 正文颜色 |
|
||||
| margin-bottom | mb-3 (12px) | 12px | 下边距 |
|
||||
|
||||
**line-height 设置规则**(附录B.2.3):
|
||||
- 在外层 `<view>` 的 class 上设置 `line-height`
|
||||
- `<text>` 会自动继承,不需要额外设置
|
||||
|
||||
#### 标签(.note-tag)
|
||||
| 属性 | H5 值 | 小程序值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| padding | px-2.5 py-1 (10px 4px) | 4px 10px | 标签内边距 |
|
||||
| font-size | text-xs (12px) | 12px | 标签字号 |
|
||||
| border-radius | rounded-lg (8px) | 8px | 圆角 |
|
||||
| border | 1px solid | 1px solid | 边框 |
|
||||
|
||||
#### 时间戳(.note-time)
|
||||
| 属性 | H5 值 | 小程序值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| font-size | text-xs (12px) | 12px | 时间字号 |
|
||||
| color | text-gray-6 | #a6a6a6 | 次级文字颜色 |
|
||||
|
||||
### 5. 列表容器(.note-list)
|
||||
|
||||
| 属性 | H5 值 | 小程序值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| padding | p-4 (16px) | 16px | 列表外边距 |
|
||||
| gap | space-y-3 (12px) | 12px | 卡片间距 |
|
||||
|
||||
### 6. 颜色映射(附录C)
|
||||
|
||||
| 用途 | 色值 | 说明 |
|
||||
|------|------|------|
|
||||
| 主品牌色 | #0052d9 | primary |
|
||||
| 成功色 | #00a870 | success |
|
||||
| 背景色 | #f3f3f3 | gray-1 |
|
||||
| 正文色 | #242424 | gray-13 |
|
||||
| 次级文字 | #a6a6a6 | gray-6 |
|
||||
| 分割线 | #eeeeee | gray-2 |
|
||||
|
||||
### 7. 标签渐变背景
|
||||
|
||||
**客户标签**:
|
||||
```css
|
||||
background: linear-gradient(135deg, #ecf2fe, #e8eeff);
|
||||
color: #0052d9;
|
||||
border-color: #c5d4f7;
|
||||
```
|
||||
|
||||
**助教标签**:
|
||||
```css
|
||||
background: linear-gradient(135deg, #e8faf0, #e0f7ea);
|
||||
color: #00a870;
|
||||
border-color: #b3e6d0;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键调整点
|
||||
|
||||
### 1. 全局 line-height 设置
|
||||
```wxss
|
||||
page {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
view {
|
||||
line-height: inherit;
|
||||
}
|
||||
```
|
||||
**原因**:微信小程序 `<text>` 组件不能直接设置 `line-height`,必须在外层 `<view>` 设置(附录B.2.3)
|
||||
|
||||
### 2. 单位统一为 px
|
||||
- 原小程序版本混用 `rpx` 和 CSS 变量
|
||||
- 调整为直接使用 `px`,确保与H5原型1:1对齐
|
||||
- 所有尺寸基于412宽设备验收基准
|
||||
|
||||
### 3. 移除 CSS 变量依赖
|
||||
- 原:`var(--color-gray-2, #eeeeee)`
|
||||
- 新:直接使用 `#eeeeee`
|
||||
- 原因:确保样式独立,不依赖全局变量
|
||||
|
||||
### 4. Icon 尺寸调整
|
||||
- 原:`size="48rpx"` (约88px)
|
||||
- 新:`size="24px"` (标准导航栏icon尺寸)
|
||||
- 原因:与H5原型中的 `w-5 h-5` 对齐
|
||||
|
||||
### 5. 加载态 icon 尺寸
|
||||
- 原:`size="80rpx"` (约146px)
|
||||
- 新:`size="40px"` (适配小屏幕)
|
||||
|
||||
---
|
||||
|
||||
## 附录参考
|
||||
|
||||
### 使用的附录
|
||||
1. **附录A**:Spacing 与尺寸字典 v3.0
|
||||
- 间距换算:16px → 16px(px模式)
|
||||
- 圆角:8px, 16px
|
||||
|
||||
2. **附录B**:字体与文本字典 v3.1
|
||||
- text-sm: 14px / 20px
|
||||
- text-xs: 12px / 16px
|
||||
- **关键规则**:line-height 必须在外层 view 上设置
|
||||
|
||||
3. **附录C**:颜色字典 v3.0
|
||||
- 项目自定义颜色表
|
||||
- 透明度变体处理
|
||||
|
||||
4. **附录D**:布局类映射字典 v3.0
|
||||
- flex 布局
|
||||
- gap 间距
|
||||
|
||||
---
|
||||
|
||||
## 验收清单
|
||||
|
||||
- [x] 导航栏高度与H5对齐(44px)
|
||||
- [x] 卡片圆角与H5对齐(16px)
|
||||
- [x] 文字大小与H5对齐(14px/12px)
|
||||
- [x] 行高设置正确(在view上设置)
|
||||
- [x] 颜色值与H5对齐
|
||||
- [x] 间距与H5对齐(16px padding, 12px gap)
|
||||
- [x] 标签样式与H5对齐(渐变背景)
|
||||
- [x] 阴影效果与H5对齐(shadow-sm)
|
||||
|
||||
---
|
||||
|
||||
## 已知限制
|
||||
|
||||
1. **安全区处理**:使用 `statusBarHeight` 动态计算,不使用 `env(safe-area-inset-*)`
|
||||
2. **AI 悬浮按钮**:bottom 值为 120px,需根据实际设备调整
|
||||
3. **页面滚动**:使用页面自然滚动,未使用 scroll-view
|
||||
|
||||
---
|
||||
|
||||
## 后续维护
|
||||
|
||||
- 若真机测试发现尺寸偏差,优先检查 line-height 设置
|
||||
- 若需要调整间距,参考附录A的spacing表
|
||||
- 若需要调整字号,参考附录B的字体表
|
||||
- 颜色调整参考附录C的颜色字典
|
||||
@@ -0,0 +1,139 @@
|
||||
# Notes 页面 H5 → 小程序 样式对比表
|
||||
|
||||
## 快速参考
|
||||
|
||||
### 导航栏
|
||||
| 元素 | H5 Tailwind | H5 CSS px | 小程序 WXSS |
|
||||
|------|-----------|----------|-----------|
|
||||
| 导航栏高度 | h-11 | 44px | 44px |
|
||||
| 导航栏 padding | px-4 | 0 16px | 0 16px |
|
||||
| 返回按钮大小 | w-5 h-5 | 20px | 44px (容器) |
|
||||
| 返回 icon 尺寸 | — | — | 24px |
|
||||
| 标题字号 | text-base | 16px | 16px |
|
||||
| 标题字重 | font-medium | 500 | 500 |
|
||||
| 分割线 | border-b border-gray-2 | 1px solid #eeeeee | 1px solid #eeeeee |
|
||||
|
||||
### 备注卡片
|
||||
| 元素 | H5 Tailwind | H5 CSS px | 小程序 WXSS |
|
||||
|------|-----------|----------|-----------|
|
||||
| 卡片圆角 | rounded-2xl | 16px | 16px |
|
||||
| 卡片 padding | p-4 | 16px | 16px |
|
||||
| 卡片阴影 | shadow-sm | 0 1px 2px rgba(0,0,0,0.05) | 0 1px 2px rgba(0,0,0,0.05) |
|
||||
| 卡片间距 | space-y-3 | 12px | 12px |
|
||||
| 背景色 | bg-white | #ffffff | #ffffff |
|
||||
|
||||
### 文本样式
|
||||
| 元素 | H5 Tailwind | H5 CSS px | 小程序 WXSS |
|
||||
|------|-----------|----------|-----------|
|
||||
| 备注内容字号 | text-sm | 14px | 14px |
|
||||
| 备注内容行高 | leading-relaxed | 1.625 (26px) | 20px |
|
||||
| 备注内容颜色 | text-gray-13 | #242424 | #242424 |
|
||||
| 备注内容下边距 | mb-3 | 12px | 12px |
|
||||
| 标签字号 | text-xs | 12px | 12px |
|
||||
| 标签 padding | px-2.5 py-1 | 10px 4px | 4px 10px |
|
||||
| 标签圆角 | rounded-lg | 8px | 8px |
|
||||
| 时间字号 | text-xs | 12px | 12px |
|
||||
| 时间颜色 | text-gray-6 | #a6a6a6 | #a6a6a6 |
|
||||
|
||||
### 颜色
|
||||
| 用途 | H5 Tailwind | 色值 | 小程序 WXSS |
|
||||
|------|-----------|------|-----------|
|
||||
| 页面背景 | bg-gray-1 | #f3f3f3 | #f3f3f3 |
|
||||
| 卡片背景 | bg-white | #ffffff | #ffffff |
|
||||
| 正文 | text-gray-13 | #242424 | #242424 |
|
||||
| 次级文字 | text-gray-6 | #a6a6a6 | #a6a6a6 |
|
||||
| 分割线 | border-gray-2 | #eeeeee | #eeeeee |
|
||||
| 客户标签文字 | text-primary | #0052d9 | #0052d9 |
|
||||
| 客户标签背景 | gradient | linear-gradient(135deg, #ecf2fe, #e8eeff) | linear-gradient(135deg, #ecf2fe, #e8eeff) |
|
||||
| 客户标签边框 | — | #c5d4f7 | #c5d4f7 |
|
||||
| 助教标签文字 | text-success | #00a870 | #00a870 |
|
||||
| 助教标签背景 | gradient | linear-gradient(135deg, #e8faf0, #e0f7ea) | linear-gradient(135deg, #e8faf0, #e0f7ea) |
|
||||
| 助教标签边框 | — | #b3e6d0 | #b3e6d0 |
|
||||
|
||||
### 列表容器
|
||||
| 元素 | H5 Tailwind | H5 CSS px | 小程序 WXSS |
|
||||
|------|-----------|----------|-----------|
|
||||
| 列表 padding | p-4 | 16px | 16px |
|
||||
| 列表背景 | bg-gray-1 | #f3f3f3 | #f3f3f3 |
|
||||
|
||||
### 底部提示
|
||||
| 元素 | H5 Tailwind | H5 CSS px | 小程序 WXSS |
|
||||
|------|-----------|----------|-----------|
|
||||
| 提示字号 | text-xs | 12px | 12px |
|
||||
| 提示颜色 | text-gray-5 | #c5c5c5 | #c5c5c5 |
|
||||
| 提示 padding | py-8 pb-16 | 32px 0 64px | 20px 0 40px |
|
||||
|
||||
---
|
||||
|
||||
## 关键转换规则
|
||||
|
||||
### 1. Tailwind spacing → px
|
||||
```
|
||||
p-4 (padding: 1rem) → 16px
|
||||
p-1 (padding: 0.25rem) → 4px
|
||||
mb-3 (margin-bottom: 0.75rem) → 12px
|
||||
space-y-3 (gap: 0.75rem) → 12px
|
||||
```
|
||||
|
||||
### 2. Tailwind 字号 → px
|
||||
```
|
||||
text-sm (0.875rem) → 14px
|
||||
text-xs (0.75rem) → 12px
|
||||
text-base (1rem) → 16px
|
||||
```
|
||||
|
||||
### 3. Tailwind 圆角 → px
|
||||
```
|
||||
rounded-2xl (border-radius: 1rem) → 16px
|
||||
rounded-lg (border-radius: 0.5rem) → 8px
|
||||
```
|
||||
|
||||
### 4. 行高处理
|
||||
```
|
||||
H5: leading-relaxed (1.625)
|
||||
小程序: 在外层 view 上设置 line-height: 20px
|
||||
原因: text 组件不支持直接设置 line-height
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 验证方法
|
||||
|
||||
### 在 412px 宽设备上对比
|
||||
1. 打开H5原型:`docs/h5_ui/pages/notes.html`
|
||||
2. 打开小程序:`pages/notes/notes`
|
||||
3. 对比以下关键点:
|
||||
- 导航栏高度是否一致
|
||||
- 卡片圆角是否一致
|
||||
- 文字大小是否一致
|
||||
- 间距是否一致
|
||||
- 颜色是否一致
|
||||
|
||||
### 常见问题排查
|
||||
| 问题 | 排查项 | 参考文档 |
|
||||
|------|--------|--------|
|
||||
| 文字高度不对 | 检查 line-height 是否在外层 view 上设置 | 附录B.2.3 |
|
||||
| 间距不对 | 检查 padding/margin/gap 数值 | 附录A |
|
||||
| 颜色不对 | 检查色值是否与附录C一致 | 附录C |
|
||||
| 圆角不对 | 检查 border-radius 数值 | 附录A.5 |
|
||||
| 阴影不对 | 检查 box-shadow 参数 | 桥文档 §9.2 |
|
||||
|
||||
---
|
||||
|
||||
## 文件清单
|
||||
|
||||
- `notes.wxml` - 页面结构(已更新icon尺寸)
|
||||
- `notes.wxss` - 页面样式(已调整为px单位)
|
||||
- `notes.ts` - 页面逻辑(无需修改)
|
||||
- `notes.json` - 页面配置(无需修改)
|
||||
- `MIGRATION_NOTES.md` - 迁移说明(本文件)
|
||||
|
||||
---
|
||||
|
||||
## 参考文档
|
||||
|
||||
- 桥文档:`docs/miniprogram-dev/h5-to-mp-bridge-v3.md`
|
||||
- 附录A:`docs/miniprogram-dev/New/appendix_a_spacing_and_sizing_dictionary_v3.md`
|
||||
- 附录B:`docs/miniprogram-dev/New/appendix_b_typography_and_text_dictionary_v3.md`
|
||||
- 附录C:`docs/miniprogram-dev/New/appendix_c_color_dictionary_v3.md`
|
||||
- H5原型:`docs/h5_ui/pages/notes.html`
|
||||
13
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.json
Normal file
13
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"navigationBarTitleText": "备注",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"navigationBarTextStyle": "black",
|
||||
"enablePullDownRefresh": true,
|
||||
"usingComponents": {
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-loading": "tdesign-miniprogram/loading/loading",
|
||||
"t-empty": "tdesign-miniprogram/empty/empty",
|
||||
"ai-float-button": "/components/ai-float-button/ai-float-button",
|
||||
"dev-fab": "/components/dev-fab/dev-fab"
|
||||
}
|
||||
}
|
||||
76
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.ts
Normal file
76
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { mockNotes } from '../../utils/mock-data'
|
||||
import type { Note } from '../../utils/mock-data'
|
||||
import { formatRelativeTime } from '../../utils/time'
|
||||
|
||||
/** 带展示时间的备注项 */
|
||||
interface NoteDisplay extends Note {
|
||||
timeLabel: string
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
pageState: 'loading' as 'loading' | 'empty' | 'error' | 'normal',
|
||||
notes: [] as NoteDisplay[],
|
||||
/** 系统状态栏高度(px),用于自定义导航栏顶部偏移 */
|
||||
statusBarHeight: 20,
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const sysInfo = wx.getWindowInfo()
|
||||
this.setData({ statusBarHeight: sysInfo.statusBarHeight || 20 })
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
loadData() {
|
||||
this.setData({ pageState: 'loading' })
|
||||
|
||||
setTimeout(() => {
|
||||
// TODO: 替换为真实 API 调用 GET /api/xcx/notes
|
||||
try {
|
||||
const notes: NoteDisplay[] = mockNotes.map((n) => ({
|
||||
...n,
|
||||
timeLabel: formatRelativeTime(n.createdAt),
|
||||
}))
|
||||
this.setData({
|
||||
pageState: notes.length > 0 ? 'normal' : 'empty',
|
||||
notes,
|
||||
})
|
||||
} catch {
|
||||
this.setData({ pageState: 'error' })
|
||||
}
|
||||
}, 400)
|
||||
},
|
||||
|
||||
/** 返回上一页 */
|
||||
onBack() {
|
||||
wx.navigateBack()
|
||||
},
|
||||
|
||||
/** 错误态重试 */
|
||||
onRetry() {
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
/** 删除备注 */
|
||||
onDeleteNote(e: WechatMiniprogram.BaseEvent) {
|
||||
const noteId = e.currentTarget.dataset.id as string
|
||||
wx.showModal({
|
||||
title: '删除备注',
|
||||
content: '确定要删除这条备注吗?删除后无法恢复。',
|
||||
confirmColor: '#e34d59',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
const notes = this.data.notes.filter((n) => n.id !== noteId)
|
||||
this.setData({ notes })
|
||||
wx.showToast({ title: '已删除', icon: 'success' })
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
/** 下拉刷新 */
|
||||
onPullDownRefresh() {
|
||||
this.loadData()
|
||||
wx.stopPullDownRefresh()
|
||||
},
|
||||
})
|
||||
60
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.wxml
Normal file
60
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.wxml
Normal file
@@ -0,0 +1,60 @@
|
||||
<!-- pages/notes/notes.wxml — 备注记录 -->
|
||||
|
||||
<!-- 加载态(toast 浮层,不白屏) -->
|
||||
<view class="g-toast-loading" wx:if="{{pageState === 'loading'}}">
|
||||
<view class="g-toast-loading-inner">
|
||||
<t-loading theme="circular" size="40rpx" />
|
||||
<text class="g-toast-loading-text">加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 错误态 -->
|
||||
<view class="page-error" wx:elif="{{pageState === 'error'}}">
|
||||
<view class="error-content">
|
||||
<text class="error-icon">😵</text>
|
||||
<text class="error-text">加载失败,请重试</text>
|
||||
<view class="retry-btn" hover-class="retry-btn--hover" bindtap="onRetry">
|
||||
<text class="retry-btn-text">重新加载</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空数据态 -->
|
||||
<view class="page-empty-wrap" wx:elif="{{pageState === 'empty'}}">
|
||||
<view class="page-empty">
|
||||
<t-empty description="暂无备注记录" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 正常态 -->
|
||||
<view class="page-normal" wx:elif="{{pageState === 'normal'}}">
|
||||
<!-- 备注列表 -->
|
||||
<view class="note-list">
|
||||
<view
|
||||
class="note-card"
|
||||
wx:for="{{notes}}"
|
||||
wx:key="id"
|
||||
>
|
||||
<text class="note-content">{{item.content}}</text>
|
||||
<view class="note-bottom">
|
||||
<text class="note-tag {{item.tagType === 'coach' ? 'tag-coach' : 'tag-customer'}}">{{item.tagLabel}}</text>
|
||||
<view class="note-bottom-right">
|
||||
<view class="note-delete-btn" catchtap="onDeleteNote" data-id="{{item.id}}" hover-class="note-delete-btn--hover">
|
||||
<t-icon name="delete" size="16px" color="#a6a6a6" />
|
||||
</view>
|
||||
<text class="note-time">{{item.timeLabel}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部提示 -->
|
||||
<view class="list-footer">
|
||||
<text class="footer-text">— 已加载全部记录 —</text>
|
||||
</view>
|
||||
|
||||
<!-- AI 悬浮按钮 -->
|
||||
<ai-float-button />
|
||||
</view>
|
||||
|
||||
<dev-fab />
|
||||
203
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.wxss
Normal file
203
apps/DEMO-miniprogram/miniprogram/pages/notes/notes.wxss
Normal file
@@ -0,0 +1,203 @@
|
||||
/* pages/notes/notes.wxss — 备注记录页样式 */
|
||||
|
||||
/* ========== 全局设置 ========== */
|
||||
page {
|
||||
background-color: #f3f3f3;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
view {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* ========== 自定义导航栏 ========== */
|
||||
.safe-area-top {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.custom-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
padding: 0 16px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.nav-back {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.nav-back--hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #242424;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
/* ========== 页面背景 ========== */
|
||||
.page-loading,
|
||||
.page-empty-wrap,
|
||||
.page-normal,
|
||||
.page-error {
|
||||
min-height: 100vh;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
/* ========== 加载态 / 空态 ========== */
|
||||
.page-loading,
|
||||
.page-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 60vh;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* ========== 错误态 ========== */
|
||||
.page-error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.error-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
font-size: 54px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 14px;
|
||||
color: #777777;
|
||||
margin-bottom: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
padding: 10px 30px;
|
||||
background-color: #0052d9;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.retry-btn--hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.retry-btn-text {
|
||||
font-size: 14px;
|
||||
color: #ffffff;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
/* ========== 备注列表 ========== */
|
||||
.note-list {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.note-card + .note-card {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/* ========== 备注卡片 ========== */
|
||||
.note-card {
|
||||
background-color: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.note-content {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: #242424;
|
||||
line-height: 20px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.note-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.note-bottom-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* ========== 删除按钮 ========== */
|
||||
.note-delete-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.note-delete-btn--hover {
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
/* ========== 标签样式 ========== */
|
||||
.note-tag {
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.tag-customer {
|
||||
background: linear-gradient(135deg, #ecf2fe, #e8eeff);
|
||||
color: #0052d9;
|
||||
border-color: #c5d4f7;
|
||||
}
|
||||
|
||||
.tag-coach {
|
||||
background: linear-gradient(135deg, #e8faf0, #e0f7ea);
|
||||
color: #00a870;
|
||||
border-color: #b3e6d0;
|
||||
}
|
||||
|
||||
.note-time {
|
||||
font-size: 12px;
|
||||
color: #a6a6a6;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
/* ========== 底部提示 ========== */
|
||||
.list-footer {
|
||||
text-align: center;
|
||||
padding: 20px 0 40px;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 12px;
|
||||
color: #c5c5c5;
|
||||
line-height: 16px;
|
||||
}
|
||||
Reference in New Issue
Block a user