chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<view class="agent-conversation-history h-full">
|
||||
<scroll-view
|
||||
class="h-full"
|
||||
scroll-y
|
||||
@scrolltolower="handleLoadMore"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="refreshing"
|
||||
@refresherrefresh="handleRefresh"
|
||||
:show-scrollbar="false"
|
||||
>
|
||||
<!-- 会话列表 -->
|
||||
<template v-if="conversationList?.length">
|
||||
<view class="list-wrapper">
|
||||
<view
|
||||
class="conversation-item"
|
||||
hover-class="hover-class"
|
||||
hover-start-time="50"
|
||||
v-for="item in conversationList"
|
||||
:key="item.id"
|
||||
@click="onConversationClick(item)"
|
||||
>
|
||||
<text class="conversation-title text-ellipsis">{{
|
||||
item.topic || t("Mobile.Conversation.unnamed")
|
||||
}}</text>
|
||||
<text class="conversation-date">{{
|
||||
formatDate(item.modified)
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- loading状态或刷新状态时隐藏空状态 -->
|
||||
<template v-else-if="!loading && !refreshing">
|
||||
<view class="empty-state h-full">
|
||||
<empty-state />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 刷新状态时隐藏加载状态 -->
|
||||
<template v-else-if="!refreshing">
|
||||
<view class="loading-state">
|
||||
<text class="loading-text">{{ t("Mobile.Page.loadingMore") }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 没有更多数据提示 -->
|
||||
<template v-if="showNoMore">
|
||||
<view class="no-more-state">
|
||||
<text class="no-more-text">{{ t("Mobile.Common.noMoreData") }}</text>
|
||||
</view>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import type {
|
||||
ConversationInfo,
|
||||
ConversationListParams,
|
||||
} from "@/types/interfaces/conversationInfo";
|
||||
import { formatDate } from "@/utils/system";
|
||||
import { jumpToAgentDetailPage } from "@/utils/commonBusiness";
|
||||
import { apiAgentConversationList } from "@/servers/conversation";
|
||||
import { SUCCESS_CODE } from "@/constants/codes.constants.uts";
|
||||
import { useI18n } from "@/utils/i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
interface Props {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
// 接收组件属性
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
// 会话列表
|
||||
const conversationList = ref<ConversationInfo[]>([]);
|
||||
// 加载状态
|
||||
const loading = ref<boolean>(false);
|
||||
// 刷新状态
|
||||
const refreshing = ref<boolean>(false);
|
||||
// 是否还有更多
|
||||
const hasMore = ref<boolean>(true);
|
||||
// 最后一条记录ID
|
||||
const lastId = ref<number | null>(null);
|
||||
|
||||
// 是否显示没有更多数据
|
||||
const showNoMore = computed(() => {
|
||||
return (
|
||||
!loading.value && !hasMore.value && conversationList.value?.length > 0
|
||||
);
|
||||
});
|
||||
|
||||
// 获取会话列表
|
||||
const fetchConversationList = async (isLoadMore: boolean = false) => {
|
||||
try {
|
||||
const params: ConversationListParams = {
|
||||
agentId: props.agentId,
|
||||
lastId: isLoadMore ? lastId.value : null,
|
||||
limit: 20,
|
||||
} as ConversationListParams;
|
||||
|
||||
const res = await apiAgentConversationList(params);
|
||||
loading.value = false;
|
||||
|
||||
const { code, data } = res || {};
|
||||
if (code === SUCCESS_CODE) {
|
||||
const newList = (data || []) as ConversationInfo[];
|
||||
|
||||
if (isLoadMore) {
|
||||
// 追加数据
|
||||
conversationList.value = [...conversationList.value, ...newList];
|
||||
} else {
|
||||
// 替换数据
|
||||
conversationList.value = newList;
|
||||
}
|
||||
|
||||
// 更新lastId和hasMore
|
||||
if (data && data.length > 0) {
|
||||
lastId.value = data[data.length - 1].id;
|
||||
hasMore.value = newList.length >= 20;
|
||||
} else {
|
||||
hasMore.value = false;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
} catch (error) {
|
||||
loading.value = false;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 下拉刷新
|
||||
const handleRefresh = async () => {
|
||||
if (refreshing.value) {
|
||||
return;
|
||||
}
|
||||
refreshing.value = true;
|
||||
lastId.value = null;
|
||||
hasMore.value = true;
|
||||
|
||||
await fetchConversationList(false);
|
||||
|
||||
setTimeout(() => {
|
||||
refreshing.value = false;
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// 加载更多
|
||||
const handleLoadMore = () => {
|
||||
if (hasMore.value && !loading.value) {
|
||||
loading.value = true;
|
||||
fetchConversationList(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 会话项点击处理
|
||||
const onConversationClick = (item: ConversationInfo) => {
|
||||
// 跳转到智能体详情页面,并传递消息数据
|
||||
jumpToAgentDetailPage(item.agentId, item.id);
|
||||
};
|
||||
|
||||
// 组件挂载时加载数据
|
||||
onMounted(() => {
|
||||
loading.value = true;
|
||||
fetchConversationList(false);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.agent-conversation-history {
|
||||
.list-wrapper {
|
||||
padding: 16rpx;
|
||||
|
||||
.conversation-item {
|
||||
height: 76rpx;
|
||||
padding: 0 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: background-color 0.2s;
|
||||
gap: 32rpx;
|
||||
border-radius: 16rpx;
|
||||
|
||||
&.hover-class {
|
||||
background-color: rgba(12, 20, 102, 0.04);
|
||||
}
|
||||
|
||||
.conversation-title {
|
||||
color: #000;
|
||||
font-size: 28rpx;
|
||||
font-weight: 400;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.conversation-date {
|
||||
text-align: right;
|
||||
font-size: 24rpx;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-state {
|
||||
width: 100%;
|
||||
padding: 40rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border: 4rpx solid #e8e8e8;
|
||||
border-top: 4rpx solid #8b5cf6;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 没有更多数据状态 */
|
||||
.no-more-state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40rpx;
|
||||
|
||||
.no-more-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user