feat(金币代理收支明细页面): 调整接口并新增上拉加载功能
This commit is contained in:
parent
2c9c63ca52
commit
60468f1d70
@ -124,10 +124,17 @@ export function freightRecharge(data) {
|
|||||||
* @param {string} data
|
* @param {string} data
|
||||||
* @returns {Promise} 返回交易流水记录
|
* @returns {Promise} 返回交易流水记录
|
||||||
*/
|
*/
|
||||||
export function getFreightWaterFlow(data) {
|
export const getFreightWaterFlow = async (data) => {
|
||||||
return get(
|
try {
|
||||||
`/wallet/freight/balance/running/water/client/flowByUserId?userId=${data.userId}&type=${data.type}&searchId=${data.searchId}`
|
const response = await get(
|
||||||
)
|
`/wallet/freight/balance/running/water/client/flowByUserId?userId=${data.userId}&type=${data.type}&searchId=${data.searchId}&lastId=${data.lastId}`
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch bank card list:', error)
|
||||||
|
console.error('error:' + error.response.errorMsg)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
v-for="tab in tabs"
|
v-for="tab in tabs"
|
||||||
:key="tab.id"
|
:key="tab.id"
|
||||||
ref="tabItems"
|
ref="tabItems"
|
||||||
@click="switchTab(tab.id)"
|
@click="switchTab(tab)"
|
||||||
:style="{
|
:style="{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: '8px 16px',
|
padding: '8px 16px',
|
||||||
@ -63,7 +63,7 @@
|
|||||||
border: 'none',
|
border: 'none',
|
||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
color: activeTabId === tab.id ? '#8B5CF6' : 'rgba(0, 0, 0, 0.6)',
|
color: selectedTab.id === tab.id ? '#8B5CF6' : 'rgba(0, 0, 0, 0.6)',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
transition: 'all 0.3s',
|
transition: 'all 0.3s',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
<!-- 用户列表(加载中...) -->
|
<!-- 用户列表(加载中...) -->
|
||||||
<div
|
<div
|
||||||
v-if="loading"
|
v-if="loading && !records.length"
|
||||||
style="
|
style="
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -125,6 +125,7 @@
|
|||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<!-- 头像 -->
|
<!-- 头像 -->
|
||||||
@ -155,6 +156,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 个人资料 -->
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -214,6 +216,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 收入列表触发加载功能 -->
|
||||||
|
<div
|
||||||
|
ref="incomeLoadmore"
|
||||||
|
v-show="incomeRecords.length != 0 && selectedTab?.langKey === 'income'"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<!-- 支出列表触发加载功能 -->
|
||||||
|
<div
|
||||||
|
ref="expenditureLoadmore"
|
||||||
|
v-show="expenditureRecords.length != 0 && selectedTab?.langKey === 'expenditure'"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 用户列表(加载完且列表为空) -->
|
<!-- 用户列表(加载完且列表为空) -->
|
||||||
@ -240,28 +254,46 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed, nextTick } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import GeneralHeader from '@/components/GeneralHeader.vue'
|
import { setDocumentDirection } from '@/locales/i18n'
|
||||||
import { getFreightWaterFlow } from '@/api/wallet.js'
|
|
||||||
import { formatUTCCustom } from '@/utils/utcFormat.js'
|
import { formatUTCCustom } from '@/utils/utcFormat.js'
|
||||||
import { getUserId } from '@/utils/userStore.js'
|
import { getUserId } from '@/utils/userStore.js'
|
||||||
import { setDocumentDirection } from '@/locales/i18n'
|
|
||||||
import { handleAvatarImageError } from '@/utils/imageHandler.js'
|
import { handleAvatarImageError } from '@/utils/imageHandler.js'
|
||||||
|
import { useDebounce, useThrottle } from '@/utils/useDebounce'
|
||||||
|
|
||||||
|
import { getFreightWaterFlow } from '@/api/wallet.js'
|
||||||
|
|
||||||
|
import GeneralHeader from '@/components/GeneralHeader.vue'
|
||||||
|
|
||||||
const { t, locale } = useI18n()
|
const { t, locale } = useI18n()
|
||||||
|
|
||||||
// 监听语言变化并设置文档方向
|
// 监听语言变化并设置文档方向
|
||||||
locale.value && setDocumentDirection(locale.value)
|
locale.value && setDocumentDirection(locale.value)
|
||||||
|
|
||||||
|
const userId = ref(getUserId())
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const records = ref([])
|
|
||||||
|
const incomeRecords = ref([]) //收入记录
|
||||||
|
const expenditureRecords = ref([]) //支出记录
|
||||||
|
const records = computed(() => {
|
||||||
|
if (selectedTab.value.langKey === 'income') {
|
||||||
|
return incomeRecords.value
|
||||||
|
} else {
|
||||||
|
return expenditureRecords.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取底部加载div
|
||||||
|
const incomeLoadmore = ref(null)
|
||||||
|
const expenditureLoadmore = ref(null)
|
||||||
|
|
||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
const searchResults = ref([])
|
const searchResults = ref([]) //搜索结果
|
||||||
const isSearching = ref(false)
|
const isSearching = ref(false)
|
||||||
const hasSearched = ref(false)
|
const hasSearched = ref(false)
|
||||||
|
|
||||||
const activeTabId = ref(0)
|
const selectedTab = ref({ id: 0, langKey: 'income' })
|
||||||
const tabItems = ref([]) // 存储标签DOM引用
|
const tabItems = ref([]) // 存储标签DOM引用
|
||||||
// 标签页数据
|
// 标签页数据
|
||||||
const tabs = ref([
|
const tabs = ref([
|
||||||
@ -270,9 +302,11 @@ const tabs = ref([
|
|||||||
])
|
])
|
||||||
|
|
||||||
// 切换标签页
|
// 切换标签页
|
||||||
const switchTab = (tabId) => {
|
const switchTab = async (tab) => {
|
||||||
activeTabId.value = tabId
|
selectedTab.value = tab
|
||||||
fetchRecords()
|
|
||||||
|
await fetchRecords() //获取记录
|
||||||
|
reSetObserve() // 重新绑定观察器
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算下划线样式
|
// 计算下划线样式
|
||||||
@ -280,7 +314,7 @@ const underlineStyle = computed(() => {
|
|||||||
console.log('计算属性')
|
console.log('计算属性')
|
||||||
|
|
||||||
if (tabItems.value.length === 0) return {} //没有这个元素
|
if (tabItems.value.length === 0) return {} //没有这个元素
|
||||||
const activeTab = tabItems.value[activeTabId.value]
|
const activeTab = tabItems.value[selectedTab.value.id]
|
||||||
console.log('选中元素的左边距', activeTab.offsetLeft)
|
console.log('选中元素的左边距', activeTab.offsetLeft)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -298,43 +332,50 @@ const getAmountDisplay = (type, quantity) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取记录
|
// 获取记录
|
||||||
const fetchRecords = async () => {
|
const fetchRecords = async (lastId = '') => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 先获取用户ID
|
if (!userId.value) {
|
||||||
const userId = getUserId()
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
console.error('无法获取用户ID')
|
console.error('无法获取用户ID')
|
||||||
records.value = []
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换标签时,既不是下拉加载,也不是空列表,则不请求接口
|
||||||
|
if (records.value.length != 0 && lastId == '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接口参数
|
||||||
let data = {
|
let data = {
|
||||||
userId: userId,
|
userId: userId.value, //用户id
|
||||||
type: activeTabId.value,
|
type: selectedTab.value.id, //记录类型
|
||||||
searchId: searchQuery.value,
|
searchId: searchQuery.value, //目标用户id
|
||||||
|
lastId, //最后一条记录id
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await getFreightWaterFlow(data)
|
const response = await getFreightWaterFlow(data)
|
||||||
|
|
||||||
if (response && response.status && response.body) {
|
if (response && response.status && response.body) {
|
||||||
// 处理返回的数据
|
// 处理返回的数据
|
||||||
records.value = response.body.map((item) => ({
|
let records = response.body.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
|
|
||||||
amount: getAmountDisplay(item.type, item.quantity), //添加±号
|
amount: getAmountDisplay(item.type, item.quantity), //添加±号
|
||||||
time: formatUTCCustom(item.createTime), //格式化时间
|
time: formatUTCCustom(item.createTime), //格式化时间
|
||||||
}))
|
}))
|
||||||
} else {
|
|
||||||
records.value = []
|
if (selectedTab.value.id == 1) {
|
||||||
|
expenditureRecords.value.push(...records)
|
||||||
|
} else {
|
||||||
|
incomeRecords.value.push(...records)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取记录失败:', error)
|
console.error('获取记录失败:', error)
|
||||||
records.value = []
|
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
console.log('加载完毕')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,33 +383,92 @@ const fetchRecords = async () => {
|
|||||||
const clearSearch = () => {
|
const clearSearch = () => {
|
||||||
hasSearched.value = false
|
hasSearched.value = false
|
||||||
searchQuery.value = ''
|
searchQuery.value = ''
|
||||||
searchResults.value = members.value
|
searchResults.value = []
|
||||||
|
|
||||||
|
incomeRecords.value = [] //置空收入列表
|
||||||
|
expenditureRecords.value = [] //置空支出列表
|
||||||
|
fetchRecords() //重新获取记录
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行搜索
|
// 执行搜索
|
||||||
const performSearch = async () => {
|
const performSearch = useDebounce(
|
||||||
console.log('searchQuery.value:', searchQuery.value)
|
async () => {
|
||||||
|
console.log('searchQuery.value:', searchQuery.value)
|
||||||
|
|
||||||
if (!searchQuery.value.trim()) {
|
if (!searchQuery.value.trim()) {
|
||||||
searchResults.value = members.value
|
searchResults.value = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isSearching.value = true
|
isSearching.value = true
|
||||||
hasSearched.value = false
|
hasSearched.value = false
|
||||||
|
|
||||||
searchResults.value = []
|
searchResults.value = []
|
||||||
if (searchQuery.value.trim()) {
|
if (searchQuery.value.trim()) {
|
||||||
fetchRecords()
|
incomeRecords.value = [] //置空收入列表
|
||||||
}
|
expenditureRecords.value = [] //置空支出列表
|
||||||
|
await fetchRecords() //搜索记录
|
||||||
|
}
|
||||||
|
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
hasSearched.value = true
|
hasSearched.value = true
|
||||||
|
},
|
||||||
|
500,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
const throttleFetch = useThrottle((fetchFn) => {
|
||||||
|
fetchFn()
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
// IntersectionObserver配置
|
||||||
|
const obsever = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.intersectionRatio > 0) {
|
||||||
|
console.log('监控到底部')
|
||||||
|
let lastId = records.value[records.value.length - 1].id
|
||||||
|
console.log('lastId:', lastId)
|
||||||
|
if (entry.target === incomeLoadmore.value) {
|
||||||
|
console.log('incomeLoadmore')
|
||||||
|
throttleFetch(() => {
|
||||||
|
fetchRecords(lastId) //加载income新记录
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (entry.target === expenditureLoadmore.value) {
|
||||||
|
console.log('expenditureLoadmore')
|
||||||
|
throttleFetch(() => {
|
||||||
|
fetchRecords(lastId) //加载expenditure新记录
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 重新绑定观察器
|
||||||
|
const reSetObserve = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (incomeLoadmore.value) {
|
||||||
|
obsever.unobserve(incomeLoadmore.value)
|
||||||
|
obsever.observe(incomeLoadmore.value)
|
||||||
|
}
|
||||||
|
if (expenditureLoadmore.value) {
|
||||||
|
obsever.unobserve(expenditureLoadmore.value)
|
||||||
|
obsever.observe(expenditureLoadmore.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchRecords()
|
await fetchRecords()
|
||||||
underlineStyle.value // 触发计算属性更新
|
underlineStyle.value // 触发计算属性更新
|
||||||
|
|
||||||
|
if (incomeLoadmore.value) {
|
||||||
|
obsever.observe(incomeLoadmore.value) //监控收入加载标志
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expenditureLoadmore.value) {
|
||||||
|
obsever.observe(expenditureLoadmore.value) //监控支出加载标志
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user