chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<view class="container flex flex-col h-full">
|
||||
<custom-nav-bar :title="category?.name">
|
||||
<template v-slot:left>
|
||||
<text
|
||||
class="iconfont icon-a-Chevronleft"
|
||||
@tap="jumpNavigateBack"
|
||||
></text>
|
||||
</template>
|
||||
</custom-nav-bar>
|
||||
<scroll-view class="flex-1" direction="vertical" :show-scrollbar="false">
|
||||
<template v-if="loading">
|
||||
<view class="loading-state">
|
||||
<text class="loading-text">{{
|
||||
t("Mobile.Page.loadingMore")
|
||||
}}</text>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view
|
||||
v-for="item in categoryItems"
|
||||
:key="item.targetId"
|
||||
class="flex flex-row items-center item-card"
|
||||
hover-class="item-card-active"
|
||||
@click="handleAgentClick(item)"
|
||||
>
|
||||
<image
|
||||
class="item-card__icon"
|
||||
:src="getImageSrc(item.targetId, item.icon)"
|
||||
mode="aspectFill"
|
||||
:alt="item.name || t('Mobile.Common.agentIconAlt')"
|
||||
@error="handleImageError(item.targetId)"
|
||||
/>
|
||||
<view class="item-card__content">
|
||||
<text class="item-card__name text-ellipsis">{{ item.name }}</text>
|
||||
<text class="item-card__desc text-ellipsis">{{
|
||||
item.description
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import agentImage from "@/static/assets/agent_image.png";
|
||||
import { jumpToAgentDetailPage } from "@/utils/commonBusiness";
|
||||
// import { jumpNavigateBack } from '@/utils/common'
|
||||
import {
|
||||
SUCCESS_CODE,
|
||||
USER_NO_LOGIN,
|
||||
REDIRECT_LOGIN,
|
||||
} from "@/constants/codes.constants.uts";
|
||||
import { apiHomeCategoryList } from "@/servers/agentDev";
|
||||
import {
|
||||
CategoryInfo,
|
||||
CategoryItemInfo,
|
||||
} from "@/types/interfaces/agentConfig";
|
||||
import { onAddToFavorites } from "@dcloudio/uni-app";
|
||||
import { setCurrentPageNavigationBarTitle } from "@/utils/system.uts";
|
||||
import { useI18n } from "@/utils/i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const categoryKey = ref<string>(""); // 分类key
|
||||
// 分类信息
|
||||
const category = ref<CategoryInfo>(null);
|
||||
// 分类下的智能体列表
|
||||
const categoryItems = ref<CategoryItemInfo[]>([]);
|
||||
|
||||
// 记录加载失败的图片ID
|
||||
const failedImageIds = reactive<Set<string>>(new Set());
|
||||
|
||||
// 新增标志变量,用于区分首次加载
|
||||
const isFirstLoad = ref<boolean>(true);
|
||||
|
||||
const jumpNavigateBack = () => {
|
||||
uni.switchTab({ url: "/pages/agent-union-record/agent-union-record" });
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取图片源地址
|
||||
* @param id 智能体ID
|
||||
* @param originalIcon 原始图片地址
|
||||
* @returns 图片地址(加载失败则返回默认图片)
|
||||
*/
|
||||
const getImageSrc = (id: string, originalIcon: string): string => {
|
||||
return failedImageIds.has(id) ? agentImage : originalIcon;
|
||||
};
|
||||
|
||||
/**
|
||||
* 图片加载错误时触发,切换为默认图片
|
||||
* @param id 智能体ID
|
||||
*/
|
||||
const handleImageError = (id: string) => {
|
||||
failedImageIds.add(id);
|
||||
};
|
||||
|
||||
// 主页智能体列表接口
|
||||
const fetchHomeCategoryList = async () => {
|
||||
const response = await apiHomeCategoryList();
|
||||
loading.value = false;
|
||||
const { code, data, message } = response || {};
|
||||
if (code === SUCCESS_CODE) {
|
||||
if (data) {
|
||||
category.value = data.categories?.find(
|
||||
(item: CategoryInfo) => item.type === categoryKey.value,
|
||||
);
|
||||
categoryItems.value = data.categoryItems?.[categoryKey.value] || [];
|
||||
}
|
||||
} else if (code !== USER_NO_LOGIN && code !== REDIRECT_LOGIN) {
|
||||
uni.showToast({
|
||||
title: message || t("Mobile.AgentUnion.fetchHomeAgentListFailed"),
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onPageShow((options) => {
|
||||
if (isFirstLoad.value) {
|
||||
isFirstLoad.value = false;
|
||||
return;
|
||||
}
|
||||
fetchHomeCategoryList();
|
||||
});
|
||||
|
||||
onLoad((options: { categoryKey: string }) => {
|
||||
// 设置当前页面导航栏标题
|
||||
setCurrentPageNavigationBarTitle();
|
||||
const { categoryKey: _categoryKey } = options;
|
||||
categoryKey.value = _categoryKey;
|
||||
isFirstLoad.value = true;
|
||||
loading.value = true;
|
||||
fetchHomeCategoryList();
|
||||
});
|
||||
|
||||
// 点击智能体
|
||||
const handleAgentClick = (info: AgentInfo) => {
|
||||
const { lastConversationId, targetId, name, agentType } = info || {};
|
||||
|
||||
if (lastConversationId) {
|
||||
jumpToAgentDetailPage(targetId, lastConversationId);
|
||||
} else {
|
||||
jumpToAgentDetailPage(targetId, null, agentType, name);
|
||||
}
|
||||
};
|
||||
|
||||
// 收藏
|
||||
onAddToFavorites(() => {
|
||||
return {
|
||||
title: category.value?.name || t("Mobile.Common.appName"),
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
// padding-top: env(safe-area-inset-top);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* #endif */
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-state {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 32rpx;
|
||||
border-bottom: 1px solid rgba(12, 20, 102, 0.04);
|
||||
|
||||
&-active {
|
||||
background-color: rgba(12, 20, 102, 0.04);
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
&__content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&__desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
&__count {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user