fix: 修复合同筛选问题
This commit is contained in:
@@ -9,10 +9,13 @@
|
||||
<input v-model="search" class="search" placeholder="搜索姓名 / 昵称 / 手机号 / 合同编号" confirm-type="search" @input="onSearchInput" />
|
||||
</view>
|
||||
|
||||
<view v-if="candidates.length" class="legacy">
|
||||
<text class="legacy-title">{{ candidates.length }} 张存量会员卡需补录实付金额</text>
|
||||
<text class="legacy-copy">这些会员卡由后台直接开通,没有支付订单。填写学员实际支付的金额后,系统会生成待签署的补签合同。</text>
|
||||
<view v-for="item in candidates" :key="item.membershipId" class="legacy-item">
|
||||
<view v-if="showLegacyCandidates" class="legacy">
|
||||
<view class="legacy-heading" @tap="legacyExpanded = !legacyExpanded">
|
||||
<text class="legacy-title">{{ candidates.length }} 张存量会员卡需补录实付金额</text>
|
||||
<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; }
|
||||
|
||||
Reference in New Issue
Block a user