fix: 修复合同筛选问题

This commit is contained in:
richarjiang
2026-10-29 08:36:40 +08:00
parent 9afdb60824
commit 0cba1a0840

View File

@@ -9,10 +9,13 @@
<input v-model="search" class="search" placeholder="搜索姓名 / 昵称 / 手机号 / 合同编号" confirm-type="search" @input="onSearchInput" />
</view>
<view v-if="candidates.length" class="legacy">
<view v-if="showLegacyCandidates" class="legacy">
<view class="legacy-heading" @tap="legacyExpanded = !legacyExpanded">
<text class="legacy-title">{{ candidates.length }} 张存量会员卡需补录实付金额</text>
<text class="legacy-copy">这些会员卡由后台直接开通,没有支付订单。填写学员实际支付的金额后,系统会生成待签署的补签合同。</text>
<view v-for="item in candidates" :key="item.membershipId" class="legacy-item">
<text class="legacy-toggle">{{ legacyExpanded ? '收起' : '展开' }}</text>
</view>
<text class="legacy-copy">这些会员卡尚未生成合同,补录金额后才会进入待签署列表。</text>
<view v-for="item in legacyExpanded ? candidates : []" :key="item.membershipId" class="legacy-item">
<view class="legacy-info">
<text class="legacy-name">{{ item.user.nickname || '未命名学员' }}{{ item.user.phone ? ' · ' + item.user.phone : '' }}</text>
<text class="legacy-meta">{{ item.cardName }} · {{ item.remainingTimes === null ? '不限次' : '剩余 ' + item.remainingTimes + ' 次' }} · 至 {{ formatChinaDate(item.expireDate) }}</text>
@@ -46,8 +49,8 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app'
import { computed, ref } from 'vue'
import { onLoad, onReachBottom, onShow, onUnload } from '@dcloudio/uni-app'
import {
MembershipContractSource,
MembershipContractStatus,
@@ -79,6 +82,8 @@ const hasMore = ref(true)
const loading = ref(false)
const error = ref('')
const candidates = ref<LegacyContractCandidate[]>([])
const legacyExpanded = ref(false)
const showLegacyCandidates = computed(() => status.value === undefined && !search.value.trim() && candidates.value.length > 0)
const amounts = ref<Record<string, string>>({})
const creating = ref('')
let sequence = 0
@@ -86,17 +91,18 @@ let searchTimer: ReturnType<typeof setTimeout> | undefined
let loaded = false
async function fetchPage(reset: boolean) {
if (!reset && (loading.value || !hasMore.value)) return
const seq = ++sequence
if (reset) { page.value = 1; hasMore.value = true }
if (!hasMore.value) return
if (reset) { page.value = 1; hasMore.value = true; items.value = [] }
const requestedPage = page.value
loading.value = true
error.value = ''
try {
const result = await adminStore.fetchAdminContracts({ page: page.value, limit: PAGE_SIZE, status: status.value, search: search.value.trim() || undefined })
const result = await adminStore.fetchAdminContracts({ page: requestedPage, limit: PAGE_SIZE, status: status.value, search: search.value.trim() || undefined })
if (seq !== sequence) return
items.value = reset ? [...result.items] : [...items.value, ...result.items]
hasMore.value = page.value * PAGE_SIZE < result.total
page.value += 1
hasMore.value = requestedPage * PAGE_SIZE < result.total
page.value = requestedPage + 1
} catch (err) {
if (seq === sequence) error.value = getErrorMessage(err, '加载失败,请重试')
} finally {
@@ -120,7 +126,9 @@ function reload() {
function selectTab(value?: MembershipContractStatus) {
if (status.value === value) return
if (searchTimer) clearTimeout(searchTimer)
status.value = value
legacyExpanded.value = false
reload()
}
@@ -189,6 +197,10 @@ onShow(() => {
onReachBottom(() => {
if (!loading.value && hasMore.value) void fetchPage(false)
})
onUnload(() => {
if (searchTimer) clearTimeout(searchTimer)
sequence++
})
</script>
<style lang="scss" scoped>
@@ -201,6 +213,8 @@ button::after { border: 0; }
.tab--active { background: #fffdf8; color: #4f6243; }
.search { margin-top: 18rpx; height: 76rpx; padding: 0 24rpx; border-radius: 16rpx; background: #fffdf9; border: 1rpx solid #e6e5d9; font-size: 25rpx; }
.legacy { margin: 18rpx 28rpx 0; padding: 26rpx; border-radius: 22rpx; background: #fbf0e8; border: 1rpx solid #efdccd; }
.legacy-heading { display: flex; align-items: center; justify-content: space-between; gap: 16rpx; }
.legacy-toggle { flex-shrink: 0; padding: 8rpx 0 8rpx 16rpx; font-size: 23rpx; color: #8f6450; }
.legacy-title { display: block; font-size: 27rpx; color: #8f6450; }
.legacy-copy { display: block; margin: 8rpx 0 12rpx; font-size: 22rpx; line-height: 1.7; color: #9a8073; }
.legacy-item { display: flex; align-items: center; gap: 14rpx; padding: 16rpx 0; border-top: 1rpx solid #f0e2d7; }