chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -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>