Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ bin/

### IntelliJ IDEA ###
.idea
.kotlin
*.iws
*.iml
*.ipr
*.log
out/
!**/src/main/**/out/
!**/src/test/**/out/
Expand Down
11 changes: 10 additions & 1 deletion cloudapi-web/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ kotlin {
}

repositories {
maven { setUrl("https://maven.aliyun.com/repository/central") }
maven { setUrl("https://maven.aliyun.com/repository/jcenter") }
maven { setUrl("https://maven.aliyun.com/repository/google") }
maven { setUrl("https://maven.aliyun.com/repository/gradle-plugin") }
maven { setUrl("https://maven.aliyun.com/repository/public") }
maven { setUrl("https://jitpack.io") }
gradlePluginPortal()
google()
mavenCentral()
maven(url = "https://jitpack.io")
}

dependencies {
Expand All @@ -43,6 +50,8 @@ dependencies {
implementation("io.ktor:ktor-server-status-pages:$ktor_version")
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
testImplementation("io.ktor:ktor-server-test-host-jvm:$ktor_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.7.3")
implementation("ch.qos.logback:logback-classic:1.4.11")

// Redis
implementation("io.lettuce:lettuce-core:6.1.5.RELEASE")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* cloudapi_v2
* buaa scs cloud api v2
*
* The version of the OpenAPI document: 2.0
* Contact: loheagn@icloud.com
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package cn.edu.buaa.scs.controller.models

/**
*
* @param chatId
* @param stream
* @param detail
* @param messages
* @param customUid
*/
data class ChatCompletionRequest(
val chatId: kotlin.String,
val stream: kotlin.Boolean,
val detail: kotlin.Boolean,
val messages: kotlin.collections.List<ChatCompletionRequestMessagesInner>,
val customUid: kotlin.String? = null
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* cloudapi_v2
* buaa scs cloud api v2
*
* The version of the OpenAPI document: 2.0
* Contact: loheagn@icloud.com
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package cn.edu.buaa.scs.controller.models


/**
*
* @param role
* @param content
*/
data class ChatCompletionRequestMessagesInner(
val role: kotlin.String,
val content: kotlin.String
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* cloudapi_v2
* buaa scs cloud api v2
*
* The version of the OpenAPI document: 2.0
* Contact: loheagn@icloud.com
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package cn.edu.buaa.scs.controller.models


/**
*
* @param id
* @param chatId
* @param updateTime
* @param title
* @param top
*/
data class ChatHistoryItem(
val id: kotlin.Int? = null,
val chatId: kotlin.String? = null,
val updateTime: kotlin.Long? = null,
val title: kotlin.String? = null,
val top: kotlin.Boolean? = null
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* cloudapi_v2
* buaa scs cloud api v2
*
* The version of the OpenAPI document: 2.0
* Contact: loheagn@icloud.com
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package cn.edu.buaa.scs.controller.models


/**
*
* @param chatId
* @param appId
* @param offset
* @param pageSize
* @param loadCustomFeedbacks
*/
data class GetChatRecordsRequest(
val chatId: kotlin.String,
val appId: kotlin.String? = null,
val offset: kotlin.Int? = null,
val pageSize: kotlin.Int? = null,
val loadCustomFeedbacks: kotlin.Boolean? = null
)

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fun Application.configureMonitoring() {
pathDescription = "",
headers = call.request.headers.toMap(),
version = version,
realIp = call.request.headers["X-Custom-Remote-Addr"] ?: call.request.origin.host,
realIp = call.request.headers["X-Custom-Remote-Addr"] ?: call.request.origin.localHost,
userAgent = userAgent,
)
val logRecordResp = LogRecordResp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fun Application.configureRouting() {
route("/api/v2") {
authRoute()
userRoute()
chatRoute()
courseRoute()
experimentRoute()
fileRoute()
Expand Down
34 changes: 34 additions & 0 deletions cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/model/ChatHistory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cn.edu.buaa.scs.model

import org.ktorm.database.Database
import org.ktorm.entity.Entity
import org.ktorm.entity.sequenceOf
import org.ktorm.schema.*

interface ChatHistory : Entity<ChatHistory>, IEntity {
var id: Int
var userId: String
var chatId: String
var updateTime: Long
var title: String
var top: Boolean

companion object : Entity.Factory<ChatHistory>()

override fun entityId(): IntOrString {
return IntOrString(this.id)
}
}

object ChatHistories : Table<ChatHistory>("chat_history") {
val id = int("id").primaryKey().bindTo { it.id }
val userId = varchar("userId").bindTo { it.userId }
val chatId = varchar("chatId").bindTo { it.chatId }
val updateTime = long("updateTime").bindTo { it.updateTime }
val title = varchar("title").bindTo { it.title }
val top = boolean("top").bindTo { it.top }
}

@Suppress("unused")
val Database.chatHistory
get() = this.sequenceOf(ChatHistories)
32 changes: 32 additions & 0 deletions cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/route/Chat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cn.edu.buaa.scs.route

import cn.edu.buaa.scs.controller.models.ChatHistoryItem
import cn.edu.buaa.scs.controller.models.GetChatRecordsRequest
import cn.edu.buaa.scs.service.chat
import cn.edu.buaa.scs.utils.userId
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun Route.chatRoute() {
route("/chat") {
route("/history") {
get {
call.respond(call.chat.getChatHistoryByUserId(call.userId()))
}

post {
val chatHistoryItem = call.receive<ChatHistoryItem>()
call.chat.createChatHistory(call.userId(), chatHistoryItem)
call.respond("OK")
}
}

post("/records") {
val requestBody = call.receive<GetChatRecordsRequest>()
val records = call.chat.getChatRecords(requestBody)
call.respond(records)
}
}
}
78 changes: 78 additions & 0 deletions cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/service/Chat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package cn.edu.buaa.scs.service

import cn.edu.buaa.scs.controller.models.ChatHistoryItem
import cn.edu.buaa.scs.controller.models.GetChatRecordsRequest
import cn.edu.buaa.scs.model.*
import cn.edu.buaa.scs.storage.mysql
import cn.edu.buaa.scs.utils.HttpClientWrapper
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.serialization.jackson.*
import io.ktor.server.application.*
import org.ktorm.dsl.*
import org.ktorm.entity.*

val ApplicationCall.chat
get() = ChatService.getSvc(this) { ChatService(this) }

class ChatService(val call: ApplicationCall) : IService {
companion object : IService.Caller<ChatService>()

internal val client by lazy {
HttpClientWrapper(
HttpClient(CIO) {
install(ContentNegotiation) { // 确保 JSON 序列化功能可用
jackson()
}
defaultRequest {
header(HttpHeaders.Authorization, "Bearer fastgpt-sbHq9MGmKbijSJZe3l43BcFWUxNlkcISo1SSBqAHKsqXv8bGQoSIGh28Vw4Dryeu")
}
},
basePath = "http://10.251.254.178:3000/api"
)
}

// 获取指定用户的聊天记录
fun getChatHistoryByUserId(userId: String): List<ChatHistoryItem> {
return mysql.chatHistory.filter { it.userId eq userId }
.map { convertToChatHistoryItem(it) }.toList()
}

// 创建新的聊天记录
fun createChatHistory(userId: String, chatHistoryItem: ChatHistoryItem): Int {
return mysql.insertAndGenerateKey(ChatHistories) {
set(ChatHistories.userId, userId)
set(ChatHistories.chatId, chatHistoryItem.chatId)
set(ChatHistories.updateTime, chatHistoryItem.updateTime)
set(ChatHistories.title, chatHistoryItem.title)
set(ChatHistories.top, chatHistoryItem.top)
} as Int
}

// 获取聊天记录
suspend fun getChatRecords(request: GetChatRecordsRequest): String {
val body = GetChatRecordsRequest(
chatId = request.chatId,
appId = "679e3b3b5fbd929e37095abc",
offset = 0,
pageSize = 30,
loadCustomFeedbacks = false,
)
val response = client.post<String>("/core/chat/getPaginationRecords", body)
return response.getOrThrow()
}

private fun convertToChatHistoryItem(chatHistory: ChatHistory): ChatHistoryItem {
return ChatHistoryItem(
id = chatHistory.id,
chatId = chatHistory.chatId,
updateTime = chatHistory.updateTime,
title = chatHistory.title,
top = chatHistory.top
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
package cn.edu.buaa.scs.utils

import cn.edu.buaa.scs.model.User
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.plugins.*
import io.ktor.server.plugins.callid.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.utils.io.*

fun ApplicationCall.headerString(key: String): String =
this.request.header(key) ?: throw BadRequestException("missing header: $key")
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
kotlin_version=1.7.10
kotlin.code.style=official
org.gradle.jvmargs=-Xmx4g
Loading