Files
Neo-ZQYY/apps/miniprogram/miniprogram/pages/notes/notes.ts
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

136 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* AI_CHANGELOG
| 日期 | Prompt | 变更 |
|------|--------|------|
| 2026-03-23 | 角色路由+页面权限守卫 | onShow 添加 checkPageAccess 权限守卫 |
*/
import { checkPageAccess } from '../../utils/auth-guard'
import { fetchNotes, deleteNote } from '../../services/api'
import type { Note } from '../../utils/mock-data'
import { formatRelativeTime } from '../../utils/time'
/** 带展示时间的备注项 */
interface NoteDisplay extends Note {
timeLabel: string
}
/** 每页条数 */
const PAGE_SIZE = 20
Page({
data: {
pageState: 'loading' as 'loading' | 'empty' | 'error' | 'normal',
notes: [] as NoteDisplay[],
/** 系统状态栏高度px用于自定义导航栏顶部偏移 */
statusBarHeight: 20,
/** 当前页码 */
page: 1,
/** 是否正在加载更多 */
isLoadingMore: false,
/** 是否还有更多数据 */
hasMore: true,
},
onLoad() {
const sysInfo = wx.getWindowInfo()
this.setData({ statusBarHeight: sysInfo.statusBarHeight || 20 })
this.loadData()
},
onShow() {
// 权限守卫:检查登录状态、账号禁用、角色权限
checkPageAccess('pages/notes/notes')
},
/** 首次加载 / 刷新:重置分页,从第 1 页开始 */
async loadData() {
this.setData({ pageState: 'loading', page: 1, hasMore: true })
wx.showLoading({ title: '加载中...', mask: true })
try {
const res = await fetchNotes({ page: 1, pageSize: PAGE_SIZE })
const notes: NoteDisplay[] = res.notes.map((n) => ({
...n,
timeLabel: formatRelativeTime(n.createdAt),
}))
const hasMore = res.hasMore !== false && notes.length >= PAGE_SIZE
this.setData({
pageState: notes.length > 0 ? 'normal' : 'empty',
notes,
hasMore,
})
} catch {
this.setData({ pageState: 'error' })
} finally {
wx.hideLoading()
}
},
/** 触底加载更多 */
async onReachBottom() {
if (this.data.isLoadingMore || !this.data.hasMore) return
const nextPage = this.data.page + 1
this.setData({ isLoadingMore: true })
try {
const res = await fetchNotes({ page: nextPage, pageSize: PAGE_SIZE })
const newNotes: NoteDisplay[] = res.notes.map((n) => ({
...n,
timeLabel: formatRelativeTime(n.createdAt),
}))
const hasMore = res.hasMore !== false && newNotes.length >= PAGE_SIZE
this.setData({
notes: [...this.data.notes, ...newNotes],
page: nextPage,
hasMore,
isLoadingMore: false,
})
} catch {
// 加载更多失败时不改变页面状态,仅停止 loading
this.setData({ isLoadingMore: false })
wx.showToast({ title: '加载失败', icon: 'none' })
}
},
/** 返回上一页 */
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: async (res) => {
if (res.confirm) {
try {
await deleteNote(noteId)
} catch {
// 静默mock 阶段可能失败,不影响 UI
}
const notes = this.data.notes.filter((n) => n.id !== noteId)
this.setData({
notes,
pageState: notes.length > 0 ? 'normal' : 'empty',
})
wx.showToast({ title: '已删除', icon: 'success' })
}
},
})
},
/** 下拉刷新:重置分页重新加载 */
async onPullDownRefresh() {
await this.loadData()
wx.stopPullDownRefresh()
},
})