Files
shanxia2.0/miniprogram/pages/crm/pool/list.vue
T
2026-07-18 09:14:02 +08:00

138 lines
4.2 KiB
Vue
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.
<script setup>
import { ref } from 'vue'
import { onShow, onReachBottom } from '@dcloudio/uni-app'
import { listPoolCustomer, claimCustomer, getCustomer } from '@/api/crm'
import { labelOf, dash } from '@/utils/crmLabels'
import { PAGE_PATHS } from '@/config/api'
const keyword = ref('')
const list = ref([])
const page = ref(1)
const total = ref(0)
const loading = ref(false)
const finished = ref(false)
const claimingId = ref('')
const pageSize = 20
const goBack = () => {
uni.navigateBack({
fail: () => uni.switchTab({ url: PAGE_PATHS.workbench })
})
}
const levelLabel = (s) => labelOf('level', s)
const loadList = async (reset = false) => {
if (loading.value) return
if (reset) {
page.value = 1
finished.value = false
list.value = []
}
if (finished.value) return
loading.value = true
try {
const query = {
pageNum: page.value,
pageSize,
customerName: keyword.value.trim() || undefined,
keyword: keyword.value.trim() || undefined
}
const res = await listPoolCustomer(query)
const rows = res.rows || []
list.value = reset ? rows : list.value.concat(rows)
total.value = res.total || 0
if (list.value.length >= total.value || rows.length < pageSize) finished.value = true
else page.value += 1
} catch (e) {
uni.showToast({ title: e.message || '加载失败', icon: 'none' })
} finally {
loading.value = false
}
}
const onClaim = (row) => {
uni.showModal({
title: '领取客户',
content: `确认领取「${row.customerName || ''}」?`,
success: async (r) => {
if (!r.confirm) return
claimingId.value = row.id
try {
await claimCustomer(row.id)
uni.showToast({ title: '领取成功', icon: 'success' })
loadList(true)
} catch (e) {
uni.showToast({ title: e.message || '领取失败', icon: 'none' })
} finally {
claimingId.value = ''
}
}
})
}
const goDetail = async (row) => {
try {
await getCustomer(row.id)
uni.navigateTo({ url: `${PAGE_PATHS.crmCustomerDetail}?id=${row.id}` })
} catch (e) {
uni.showToast({ title: e.message || '暂无法查看详情', icon: 'none' })
}
}
onShow(() => loadList(true))
onReachBottom(() => loadList(false))
</script>
<template>
<view class="mp-page mp-page--sub">
<view class="mp-header">
<text class="mp-subpage-back" @click="goBack">← 工作台</text>
<text class="mp-header__title" style="margin-top: 16rpx">公海池</text>
<view class="mp-header__search">
<view class="mp-header__search-dot" />
<input
v-model="keyword"
class="mp-header__search-input"
placeholder="搜索客户名称"
confirm-type="search"
@confirm="loadList(true)"
/>
</view>
</view>
<view class="mp-section">
<mp-empty v-if="!list.length && !loading" title="公海暂无客户" />
<view v-else class="mp-list">
<view v-for="row in list" :key="row.id" class="mp-card">
<view class="mp-card__head" @click="goDetail(row)">
<view>
<text class="mp-card__title">{{ dash(row.customerName) }}</text>
<text class="mp-card__sub">入池:{{ dash(row.poolTime || row.updateTime) }}</text>
</view>
<text class="mp-tag mp-tag--muted">{{ levelLabel(row.level).text }}</text>
</view>
<view class="mp-card__row">
<text>来源</text>
<text class="mp-card__row-val">{{ dash(row.source) }}</text>
</view>
<view class="mp-card__row">
<text>原负责人</text>
<text class="mp-card__row-val">{{ dash(row.ownerUserName || row.prevOwnerName) }}</text>
</view>
<view class="mp-card__foot">
<view
class="mp-btn mp-btn--primary mp-btn--sm"
@click.stop="onClaim(row)"
>
{{ claimingId === row.id ? '领取中…' : '领取' }}
</view>
</view>
</view>
</view>
<view v-if="loading" class="mp-list-loading">加载中…</view>
<view v-else-if="finished && list.length" class="mp-list-end">已加载全部</view>
</view>
</view>
</template>