feat: 我的数据页面新增日期筛选+搜索+分页

- 本周/本月/本年/全部 四个时间范围筛选(默认本月)
- 关键词搜索所有内容
- el-pagination 分页(25/50/100条每页)
- 每个Tab独立分页状态

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-13 00:25:21 +08:00
parent ff07e9c470
commit d6dec7f9af
@@ -13,11 +13,34 @@ const activeTab = ref('visits')
const loading = ref(false)
const allManagers = ref<any[]>([])
// Period filter
const period = ref('month')
const searchText = ref('')
const pageSize = ref(25)
const visits = ref<any[]>([])
const workPlans = ref<any[]>([])
const miniBusiness = ref<any[]>([])
const dailyNotes = ref<any[]>([])
const keyVisits = ref<any[]>([])
// Pagination per tab
const page = ref<Record<string, number>>({ visits: 1, notes: 1, plans: 1, mini: 1, key: 1 })
const total = ref<Record<string, number>>({ visits: 0, notes: 0, plans: 0, mini: 0, key: 0 })
function getDateRange() {
const now = new Date()
const today = now.toISOString().slice(0, 10)
if (period.value === 'week') {
const d = new Date(now); d.setDate(d.getDate() - d.getDay() + 1)
return { from: d.toISOString().slice(0, 10), to: today }
} else if (period.value === 'month') {
return { from: `${now.getFullYear()}-${String(now.getMonth()+1).padStart(2,'0')}-01`, to: today }
} else if (period.value === 'year') {
return { from: `${now.getFullYear()}-01-01`, to: today }
}
return { from: '', to: '' }
}
const customers = ref<any[]>([])
const allUsers = ref<any[]>([])
const plannedVisitors = ref<string[]>([])
@@ -92,18 +115,39 @@ async function handleQuickCreate() {
}
}
function buildParams(tabKey: string) {
const { from, to } = getDateRange()
const params: any = { page: page.value[tabKey] || 1, page_size: pageSize.value }
if (from) { params.date_from = from; params.date_to = to }
if (searchText.value) params.search = searchText.value
return params
}
async function loadAll() {
loading.value = true
try {
const [v, w, m, d, k] = await Promise.all([
api.get('/visits/'), api.get('/work-plans/'),
api.get('/mini-business/'), api.get('/daily-notes/'),
api.get('/key-visits/'),
const [v, d] = await Promise.all([
api.get('/visits/', { params: buildParams('visits') }),
api.get('/daily-notes/', { params: buildParams('notes') }),
])
visits.value = v.data; workPlans.value = w.data
miniBusiness.value = m.data; dailyNotes.value = d.data
keyVisits.value = k.data
// Load photo previews
visits.value = Array.isArray(v.data) ? v.data : (v.data.items || [])
dailyNotes.value = Array.isArray(d.data) ? d.data : (d.data.items || [])
total.value.visits = v.data.total || visits.value.length
total.value.notes = d.data.total || dailyNotes.value.length
const [w, m, k] = await Promise.all([
api.get('/work-plans/', { params: buildParams('plans') }),
api.get('/mini-business/', { params: buildParams('mini') }),
api.get('/key-visits/', { params: buildParams('key') }),
])
workPlans.value = Array.isArray(w.data) ? w.data : (w.data.items || [])
miniBusiness.value = Array.isArray(m.data) ? m.data : (m.data.items || [])
keyVisits.value = Array.isArray(k.data) ? k.data : (k.data.items || [])
total.value.plans = w.data.total || workPlans.value.length
total.value.mini = m.data.total || miniBusiness.value.length
total.value.key = k.data.total || keyVisits.value.length
// Load photo previews for visits
for (const visit of visits.value) {
if (visit.photos?.length) {
for (const key of visit.photos) {
@@ -120,6 +164,11 @@ async function loadAll() {
finally { loading.value = false }
}
function onTabChange(tab: string) { activeTab.value = tab; loadAll() }
function onPeriodChange() { Object.keys(page.value).forEach(k => page.value[k] = 1); loadAll() }
function onPageChange(tabKey: string, p: number) { page.value[tabKey] = p; loadAll() }
function onSizeChange() { Object.keys(page.value).forEach(k => page.value[k] = 1); loadAll() }
function openCreate(type: string) {
dialogMode.value = 'create'; dialogType.value = type
dialogTimeRange.value = null
@@ -308,8 +357,23 @@ const notesByDate = computed(() => {
<div class="page-rule"></div>
</div>
<!-- Filter Bar -->
<div class="filter-bar">
<div class="filter-row">
<el-radio-group v-model="period" @change="onPeriodChange" size="small">
<el-radio-button value="week">本周</el-radio-button>
<el-radio-button value="month">本月</el-radio-button>
<el-radio-button value="year">本年</el-radio-button>
<el-radio-button value="all">全部</el-radio-button>
</el-radio-group>
<el-input v-model="searchText" placeholder="搜索..." clearable size="small" style="width:200px" @keyup.enter="onPeriodChange" @clear="onPeriodChange">
<template #append><el-button @click="onPeriodChange" :icon="'Search'">🔍</el-button></template>
</el-input>
</div>
</div>
<el-card>
<el-tabs v-model="activeTab">
<el-tabs v-model="activeTab" @tab-change="onTabChange">
<!-- 拜访记录 -->
<el-tab-pane label="拜访记录" name="visits">
<div style="margin-bottom:12px"><el-button type="primary" size="small" @click="openCreate('visit')">+ 新建拜访</el-button></div>
@@ -469,6 +533,18 @@ const notesByDate = computed(() => {
</el-table>
<div v-if="!keyVisits.length" class="empty">暂无数据</div>
</el-tab-pane>
<div style="margin-top:16px;display:flex;align-items:center;gap:12px">
<el-pagination
v-model:current-page="page[activeTab === 'notes' ? 'notes' : activeTab === 'plans' ? 'plans' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visits']"
:page-size="pageSize"
:total="total[activeTab === 'notes' ? 'notes' : activeTab === 'plans' ? 'plans' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visits']"
:page-sizes="[25, 50, 100]"
layout="total, sizes, prev, pager, next"
small
@current-change="(p: number) => onPageChange(activeTab === 'notes' ? 'notes' : activeTab === 'plans' ? 'plans' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visits', p)"
@size-change="onSizeChange"
/>
</div>
</el-tabs>
</el-card>