Category接口;Agent卡片组件背景颜色

This commit is contained in:
2025-09-11 18:14:54 +08:00
parent f8be622ba6
commit 8154a0ddc4
3 changed files with 185 additions and 16 deletions

View File

@@ -271,6 +271,44 @@ data class RemoveAccountRequestBody(
val password: String, val password: String,
) )
data class CategoryTemplate(
@SerializedName("id")
val id: Int,
@SerializedName("name")
val name: String,
@SerializedName("description")
val description: String,
@SerializedName("avatar")
val avatar: String,
@SerializedName("parentId")
val parentId: Int?,
@SerializedName("parent")
val parent: CategoryTemplate?,
@SerializedName("children")
val children: List<CategoryTemplate>?,
@SerializedName("sort")
val sort: Int,
@SerializedName("isActive")
val isActive: Boolean,
@SerializedName("promptCount")
val promptCount: Int?,
@SerializedName("createdAt")
val createdAt: String,
@SerializedName("updatedAt")
val updatedAt: String
)
data class CategoryListResponse(
@SerializedName("page")
val page: Int,
@SerializedName("pageSize")
val pageSize: Int,
@SerializedName("total")
val total: Int,
@SerializedName("list")
val list: List<CategoryTemplate>
)
interface RaveNowAPI { interface RaveNowAPI {
@GET("membership/config") @GET("membership/config")
@retrofit2.http.Headers("X-Requires-Auth: true") @retrofit2.http.Headers("X-Requires-Auth: true")
@@ -552,6 +590,7 @@ interface RaveNowAPI {
@Query("pageSize") pageSize: Int = 20, @Query("pageSize") pageSize: Int = 20,
@Query("withWorkflow") withWorkflow: Int = 1, @Query("withWorkflow") withWorkflow: Int = 1,
@Query("authorId") authorId: Int? = null, @Query("authorId") authorId: Int? = null,
@Query("categoryIds") categoryIds: List<Int>? = null,
): Response<DataContainer<ListContainer<Agent>>> ): Response<DataContainer<ListContainer<Agent>>>
@GET("outside/my/prompts") @GET("outside/my/prompts")
@@ -605,7 +644,38 @@ interface RaveNowAPI {
suspend fun joinRoom(@Body body: JoinGroupChatRequestBody, suspend fun joinRoom(@Body body: JoinGroupChatRequestBody,
): Response<DataContainer<Room>> ): Response<DataContainer<Room>>
@GET("outside/categories")
suspend fun getCategories(
@Query("page") page: Int? = null,
@Query("pageSize") pageSize: Int? = null,
@Query("parentId") parentId: Int? = null,
@Query("isActive") isActive: Boolean? = null,
@Query("name") name: String? = null,
@Query("withChildren") withChildren: Boolean? = null,
@Query("withParent") withParent: Boolean? = null,
@Query("withCount") withCount: Boolean? = null,
@Query("hideEmpty") hideEmpty: Boolean? = null
): Response<DataContainer<CategoryListResponse>>
@GET("outside/categories/tree")
suspend fun getCategoryTree(
@Query("withCount") withCount: Boolean? = null,
@Query("hideEmpty") hideEmpty: Boolean? = null
): Response<DataContainer<List<CategoryTemplate>>>
@GET("outside/categories/{id}")
suspend fun getCategoryById(
@Path("id") id: Int
): Response<DataContainer<CategoryTemplate>>
@GET("outside/prompts")
suspend fun getPromptsByCategory(
@Query("categoryIds") categoryIds: List<Int>? = null,
@Query("categoryName") categoryName: String? = null,
@Query("uncategorized") uncategorized: String? = null,
@Query("page") page: Int? = null,
@Query("pageSize") pageSize: Int? = null
): Response<ListContainer<Agent>>
} }

View File

@@ -246,6 +246,7 @@ fun Agent() {
isSelected = selectedTabIndex == 0, isSelected = selectedTabIndex == 0,
onClick = { onClick = {
selectedTabIndex = 0 selectedTabIndex = 0
viewModel.loadAllAgents()
} }
) )
} }
@@ -254,6 +255,24 @@ fun Agent() {
TabSpacer() TabSpacer()
} }
// 动态添加分类标签
viewModel.categories.take(4).forEachIndexed { index, category ->
item {
CustomTabItem(
text = category.name,
isSelected = selectedTabIndex == index + 1,
onClick = {
selectedTabIndex = index + 1
viewModel.loadAgentsByCategory(category.id)
}
)
}
item {
TabSpacer()
}
}
item { item {
CustomTabItem( CustomTabItem(
text = "scenes", text = "scenes",
@@ -271,9 +290,9 @@ fun Agent() {
item { item {
CustomTabItem( CustomTabItem(
text = "voices", text = "voices",
isSelected = selectedTabIndex == 2, isSelected = selectedTabIndex == 6,
onClick = { onClick = {
selectedTabIndex = 2 selectedTabIndex = 6
} }
) )
} }
@@ -285,9 +304,9 @@ fun Agent() {
item { item {
CustomTabItem( CustomTabItem(
text = "anime", text = "anime",
isSelected = selectedTabIndex == 3, isSelected = selectedTabIndex == 7,
onClick = { onClick = {
selectedTabIndex = 3 selectedTabIndex = 7
} }
) )
} }
@@ -299,16 +318,19 @@ fun Agent() {
item { item {
CustomTabItem( CustomTabItem(
text = "assist", text = "assist",
isSelected = selectedTabIndex == 4, isSelected = selectedTabIndex == 8,
onClick = { onClick = {
selectedTabIndex = 4 selectedTabIndex = 8
} }
) )
} }
} }
when (selectedTabIndex) { when {
0 -> { selectedTabIndex == 0 -> {
AgentViewPagerSection(agentItems = viewModel.agentItems.take(15), viewModel)
}
selectedTabIndex in 1..viewModel.categories.size -> {
AgentViewPagerSection(agentItems = viewModel.agentItems.take(15), viewModel) AgentViewPagerSection(agentItems = viewModel.agentItems.take(15), viewModel)
} }
else -> { else -> {
@@ -341,7 +363,7 @@ fun Agent() {
) )
} }
Spacer(modifier = Modifier.height(50.dp)) Spacer(modifier = Modifier.height(16.dp))
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -352,7 +374,7 @@ fun Agent() {
columns = GridCells.Fixed(2), columns = GridCells.Fixed(2),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(50.dp) verticalArrangement = Arrangement.spacedBy(32.dp)
) { ) {
items(agentItems) { agentItem -> items(agentItems) { agentItem ->
AgentCardSquare( AgentCardSquare(
@@ -378,8 +400,9 @@ fun AgentCardSquare(agentItem: AgentItem, viewModel: AgentViewModel, navControll
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = avatarSize / 2)
.height(cardHeight) .height(cardHeight)
.background(Color(0xFFE0E0E0), RoundedCornerShape(12.dp)) // 灰色背景 .background(AppColors.nonActive, RoundedCornerShape(12.dp)) // 修改背景颜色
.clickable { .clickable {
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) { if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
viewModel.goToProfile(agentItem.openId, navController) viewModel.goToProfile(agentItem.openId, navController)

View File

@@ -6,7 +6,10 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.aiosman.ravenow.data.Agent
import com.aiosman.ravenow.data.ListContainer
import com.aiosman.ravenow.data.api.ApiClient import com.aiosman.ravenow.data.api.ApiClient
import com.aiosman.ravenow.data.api.CategoryTemplate
import com.aiosman.ravenow.data.api.RaveNowAPI import com.aiosman.ravenow.data.api.RaveNowAPI
import com.aiosman.ravenow.data.api.SingleChatRequestBody import com.aiosman.ravenow.data.api.SingleChatRequestBody
import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel.createGroup2ChatAi import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel.createGroup2ChatAi
@@ -22,6 +25,8 @@ object AgentViewModel: ViewModel() {
var agentItems by mutableStateOf<List<AgentItem>>(emptyList()) var agentItems by mutableStateOf<List<AgentItem>>(emptyList())
private set private set
var categories by mutableStateOf<List<CategoryItem>>(emptyList())
private set
var errorMessage by mutableStateOf<String?>(null) var errorMessage by mutableStateOf<String?>(null)
private set private set
@@ -35,16 +40,30 @@ object AgentViewModel: ViewModel() {
init { init {
loadAgentData() loadAgentData()
loadCategories()
} }
private fun loadAgentData() { private fun loadAgentData(categoryId: Int? = null) {
viewModelScope.launch { viewModelScope.launch {
isLoading = true isLoading = true
errorMessage = null errorMessage = null
try { try {
val response = apiClient.getAgent(page = 1, pageSize = 20, withWorkflow = 1) val response = if (categoryId != null) {
// 根据分类ID获取智能体
apiClient.getAgent(
page = 1,
pageSize = 20,
withWorkflow = 1,
categoryIds = listOf(categoryId)
)
} else {
// 获取所有智能体
apiClient.getAgent(page = 1, pageSize = 20, withWorkflow = 1)
}
if (response.isSuccessful) { if (response.isSuccessful) {
val agents = response.body()?.data?.list ?: emptyList() val agents = response.body()?.data?.list ?: emptyList<Agent>()
agentItems = agents.map { agent -> agentItems = agents.map { agent ->
AgentItem.fromAgent(agent) AgentItem.fromAgent(agent)
} }
@@ -58,6 +77,44 @@ object AgentViewModel: ViewModel() {
} }
} }
} }
private fun loadCategories() {
viewModelScope.launch {
try {
val response = apiClient.getCategories(
pageSize = 20,
withChildren = false,
withParent = false,
withCount = true,
hideEmpty = true
)
println("分类数据请求完成,响应成功: ${response.isSuccessful}")
if (response.isSuccessful) {
val categoryList = response.body()?.data?.list ?: emptyList()
println("获取到 ${categoryList.size} 个分类")
categories = categoryList.map { category ->
CategoryItem.fromCategoryTemplate(category)
}
println("成功处理并映射了 ${categories.size} 个分类")
} else {
errorMessage = "获取分类数据失败: ${response.code()}"
println("获取分类数据失败: ${response.code()}")
}
} catch (e: Exception) {
errorMessage = "获取分类数据失败: ${e.message}"
println("获取分类数据异常: ${e.message}")
e.printStackTrace()
}
}
}
fun loadAgentsByCategory(categoryId: Int) {
loadAgentData(categoryId)
}
fun loadAllAgents() {
loadAgentData()
}
fun createSingleChat( fun createSingleChat(
openId: String, openId: String,
) { ) {
@@ -122,3 +179,22 @@ object AgentViewModel: ViewModel() {
} }
} }
data class CategoryItem(
val id: Int,
val name: String,
val description: String,
val avatar: String,
val promptCount: Int?
) {
companion object {
fun fromCategoryTemplate(template: CategoryTemplate): CategoryItem {
return CategoryItem(
id = template.id,
name = template.name,
description = template.description,
avatar = "${ApiClient.BASE_API_URL}${template.avatar}",
promptCount = template.promptCount
)
}
}
}