调整ktor后端:取消api前缀;去除无用代码;oss对象使用临时地址返回;
This commit is contained in:
@@ -101,5 +101,6 @@ dependencies {
|
|||||||
// 数据库迁移
|
// 数据库迁移
|
||||||
// implementation("org.flywaydb:flyway-core:10.13.0")
|
// implementation("org.flywaydb:flyway-core:10.13.0")
|
||||||
|
|
||||||
implementation("ai.koog:koog-agents:0.3.0")
|
// implementation("ai.koog:koog-agents:0.3.0")
|
||||||
|
implementation("io.minio:minio:8.5.17")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.google.gson.Gson
|
|||||||
import ink.snowflake.server.controller.User
|
import ink.snowflake.server.controller.User
|
||||||
import ink.snowflake.server.controller.chat
|
import ink.snowflake.server.controller.chat
|
||||||
import ink.snowflake.server.utils.plugins.configureSockets
|
import ink.snowflake.server.utils.plugins.configureSockets
|
||||||
import ink.snowflake.server.controller.LLM
|
|
||||||
import ink.snowflake.server.controller.ImageAnalytics
|
import ink.snowflake.server.controller.ImageAnalytics
|
||||||
import ink.snowflake.server.controller.RemoteDebug
|
import ink.snowflake.server.controller.RemoteDebug
|
||||||
import ink.snowflake.server.controller.VideoAnalytics
|
import ink.snowflake.server.controller.VideoAnalytics
|
||||||
@@ -29,12 +28,6 @@ const val VIDEO_INPUT_PATH = "C:/tmp/"
|
|||||||
* ADB 秦朗FRP地址
|
* ADB 秦朗FRP地址
|
||||||
*/
|
*/
|
||||||
const val SERVER_PATH_FRP = "s3.ronsunny.cn" // 171.212.101.201
|
const val SERVER_PATH_FRP = "s3.ronsunny.cn" // 171.212.101.201
|
||||||
/**
|
|
||||||
* 服务器地址
|
|
||||||
* OSS 对象存储服务器地址
|
|
||||||
*/
|
|
||||||
const val SERVER_PATH_OSS = "s1.ronsunny.cn" // 171.212.101.199
|
|
||||||
|
|
||||||
val gson = Gson()
|
val gson = Gson()
|
||||||
|
|
||||||
fun main(args: Array<String>): Unit = EngineMain.main(args)
|
fun main(args: Array<String>): Unit = EngineMain.main(args)
|
||||||
@@ -72,6 +65,4 @@ fun Application.module() {
|
|||||||
VideoAnalyticsJetson()
|
VideoAnalyticsJetson()
|
||||||
// 业务-图片分析
|
// 业务-图片分析
|
||||||
ImageAnalytics()
|
ImageAnalytics()
|
||||||
// 业务-AI
|
|
||||||
LLM()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import io.ktor.server.response.*
|
|||||||
|
|
||||||
fun Application.ImageAnalytics() {
|
fun Application.ImageAnalytics() {
|
||||||
routing {
|
routing {
|
||||||
route("/api/sca") {
|
route("/sca") {
|
||||||
// 上传分析结果
|
// 上传分析结果
|
||||||
post("/saveImageAnalyticsData") {
|
post("/saveImageAnalyticsData") {
|
||||||
val request = call.receive<ImageAnalyticsRequest>()
|
val request = call.receive<ImageAnalyticsRequest>()
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
package ink.snowflake.server.controller
|
|
||||||
|
|
||||||
import ai.koog.agents.core.agent.AIAgent
|
|
||||||
import ai.koog.prompt.executor.llms.all.simpleOllamaAIExecutor
|
|
||||||
import ai.koog.prompt.llm.LLMCapability
|
|
||||||
import ai.koog.prompt.llm.LLMProvider
|
|
||||||
import ai.koog.prompt.llm.LLModel
|
|
||||||
import ink.snowflake.server.SERVER_PATH_OSS
|
|
||||||
import ink.snowflake.server.model.response.AiListForUserResponse
|
|
||||||
import ink.snowflake.server.model.response.BaseResponse
|
|
||||||
import ink.snowflake.server.model.response.SessionListResponse
|
|
||||||
import ink.snowflake.server.utils.TokenUtils.getUserIdByToken
|
|
||||||
import ink.snowflake.server.utils.dao.AIDao
|
|
||||||
import io.ktor.server.application.Application
|
|
||||||
import io.ktor.server.auth.authenticate
|
|
||||||
import io.ktor.server.response.respond
|
|
||||||
import io.ktor.server.routing.get
|
|
||||||
import io.ktor.server.routing.route
|
|
||||||
import io.ktor.server.routing.routing
|
|
||||||
import kotlinx.html.Entities
|
|
||||||
|
|
||||||
fun Application.LLM() {
|
|
||||||
|
|
||||||
routing {
|
|
||||||
route("/api/llm") {
|
|
||||||
// authenticate {
|
|
||||||
// get("/getAiList") {
|
|
||||||
// val allAIProfile = AIDao.getAllAIProfiles().map {
|
|
||||||
// AiListForUserResponse(
|
|
||||||
// id = it.id,
|
|
||||||
// name = it.name ?: "",
|
|
||||||
// welcomeWords = it.welcome_words ?: ""
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// call.respond(BaseResponse(data = allAIProfile))
|
|
||||||
// }
|
|
||||||
// get("/getSessions") {
|
|
||||||
// val userId = getUserIdByToken(call)
|
|
||||||
// val sessionList = AIDao.getSessionList(userId)
|
|
||||||
// call.respond(BaseResponse(data = sessionList))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,6 @@ fun Application.RemoteDebug() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
route("/api") {
|
|
||||||
authenticate {
|
authenticate {
|
||||||
route("/remote") {
|
route("/remote") {
|
||||||
get("/connect") {
|
get("/connect") {
|
||||||
@@ -101,7 +100,6 @@ fun Application.RemoteDebug() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
webSocket("/logStream") {
|
webSocket("/logStream") {
|
||||||
send("日志系统连接成功")
|
send("日志系统连接成功")
|
||||||
|
|
||||||
@@ -155,7 +153,6 @@ fun Application.RemoteDebug() {
|
|||||||
clients.remove(this)
|
clients.remove(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import kotlin.text.Charsets.UTF_8
|
|||||||
// 配置和初始化 Redis 客户端
|
// 配置和初始化 Redis 客户端
|
||||||
fun setupRedis(): RedissonClient {
|
fun setupRedis(): RedissonClient {
|
||||||
val config = Config()
|
val config = Config()
|
||||||
config.useSingleServer().setAddress("redis://localhost:6379")
|
config.useSingleServer().setAddress("redis://10.10.10.9:6379")
|
||||||
return Redisson.create(config)
|
return Redisson.create(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ fun Application.User(config: AppConfig) {
|
|||||||
// 初始化 Redis 连接
|
// 初始化 Redis 连接
|
||||||
val redisClient: RedissonClient = setupRedis()
|
val redisClient: RedissonClient = setupRedis()
|
||||||
routing {
|
routing {
|
||||||
route("/api/user") {
|
route("/user") {
|
||||||
post("/login") {
|
post("/login") {
|
||||||
val loginRequest = call.receive<LoginRequest>()
|
val loginRequest = call.receive<LoginRequest>()
|
||||||
val email = loginRequest.account
|
val email = loginRequest.account
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package ink.snowflake.server.controller
|
package ink.snowflake.server.controller
|
||||||
|
|
||||||
import ink.snowflake.server.SERVER_PATH_OSS
|
|
||||||
import ink.snowflake.server.VIDEO_INPUT_PATH
|
import ink.snowflake.server.VIDEO_INPUT_PATH
|
||||||
|
import ink.snowflake.server.model.database.ScaImagesTable
|
||||||
import ink.snowflake.server.utils.dao.VideoDao
|
import ink.snowflake.server.utils.dao.VideoDao
|
||||||
import ink.snowflake.server.model.database.VideosTable
|
import ink.snowflake.server.model.database.VideosTable
|
||||||
import ink.snowflake.server.model.database.VideosTable.vAAverageMaskedRatio
|
import ink.snowflake.server.model.database.VideosTable.vAAverageMaskedRatio
|
||||||
@@ -15,6 +15,7 @@ import ink.snowflake.server.model.response.*
|
|||||||
import ink.snowflake.server.utils.CommandUtils.runCommand
|
import ink.snowflake.server.utils.CommandUtils.runCommand
|
||||||
import ink.snowflake.server.utils.MyUtils
|
import ink.snowflake.server.utils.MyUtils
|
||||||
import ink.snowflake.server.utils.MyUtils.getFriendlyActionName
|
import ink.snowflake.server.utils.MyUtils.getFriendlyActionName
|
||||||
|
import ink.snowflake.server.utils.OSSUtils
|
||||||
import ink.snowflake.server.utils.WebSocketManager.broadcastMessage
|
import ink.snowflake.server.utils.WebSocketManager.broadcastMessage
|
||||||
import io.ktor.http.content.*
|
import io.ktor.http.content.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
@@ -38,7 +39,7 @@ val clients = Collections.synchronizedList<WebSocketServerSession>(ArrayList())
|
|||||||
|
|
||||||
fun Application.VideoAnalytics() {
|
fun Application.VideoAnalytics() {
|
||||||
routing {
|
routing {
|
||||||
route("/api/iva") {
|
route("/iva") {
|
||||||
// 上传分析结果
|
// 上传分析结果
|
||||||
post("/saveVideoAnalyticsData") {
|
post("/saveVideoAnalyticsData") {
|
||||||
val request = call.receive<VideoAnalyticsRequest>()
|
val request = call.receive<VideoAnalyticsRequest>()
|
||||||
@@ -218,7 +219,7 @@ fun Application.VideoAnalytics() {
|
|||||||
data = VideoAnalyticsDetail(
|
data = VideoAnalyticsDetail(
|
||||||
v_id = vId,
|
v_id = vId,
|
||||||
v_name = video[VideosTable.vName],
|
v_name = video[VideosTable.vName],
|
||||||
v_video_play_path = "http://${SERVER_PATH_OSS}:9000/video/" + video[VideosTable.vObjectName],
|
v_video_play_path = OSSUtils.getPresignedUrl("video",video[VideosTable.vObjectName]),
|
||||||
v_file_name = video[VideosTable.vFileName],
|
v_file_name = video[VideosTable.vFileName],
|
||||||
v_duration = video[VideosTable.vDuration],
|
v_duration = video[VideosTable.vDuration],
|
||||||
v_size = video[VideosTable.vSize],
|
v_size = video[VideosTable.vSize],
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ fun Application.VideoAnalyticsJetson() {
|
|||||||
webSocket("/handleState1") {
|
webSocket("/handleState1") {
|
||||||
}
|
}
|
||||||
|
|
||||||
route("/api") {
|
|
||||||
static("/camera/stream") {
|
static("/camera/stream") {
|
||||||
// files("camera/stream") // 确保 FFmpeg 输出的 HLS 片段和 m3u8 文件存放在这里
|
// files("camera/stream") // 确保 FFmpeg 输出的 HLS 片段和 m3u8 文件存放在这里
|
||||||
files(File(streamFile))
|
files(File(streamFile))
|
||||||
@@ -66,7 +65,6 @@ fun Application.VideoAnalyticsJetson() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 确保应用退出时清理所有 FFmpeg 进程
|
// 确保应用退出时清理所有 FFmpeg 进程
|
||||||
Runtime.getRuntime().addShutdownHook(Thread {
|
Runtime.getRuntime().addShutdownHook(Thread {
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package ink.snowflake.server.utils
|
||||||
|
import io.minio.MinioClient
|
||||||
|
import io.minio.PutObjectArgs
|
||||||
|
import io.minio.GetPresignedObjectUrlArgs
|
||||||
|
import io.minio.http.Method
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
object OSSUtils {
|
||||||
|
|
||||||
|
private val client: MinioClient = MinioClient.builder()
|
||||||
|
.endpoint("http://10.10.10.9:9000") // 你的MinIO地址
|
||||||
|
.credentials("minioadmin", "minioadmin") // 账号密码
|
||||||
|
.build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param bucket 桶名
|
||||||
|
* @param objName 对象名(路径也放这里,例如 "images/test.png")
|
||||||
|
* @param input 输入流
|
||||||
|
* @param size 文件大小(字节)
|
||||||
|
* @param contentType 文件MIME类型,比如 "image/png"
|
||||||
|
*/
|
||||||
|
fun uploadFile(bucket: String, objName: String, input: InputStream, size: Long, contentType: String) {
|
||||||
|
client.putObject(
|
||||||
|
PutObjectArgs.builder()
|
||||||
|
.bucket(bucket)
|
||||||
|
.`object`(objName)
|
||||||
|
.stream(input, size, -1) // -1 表示不限制分片大小,MinIO自己切
|
||||||
|
.contentType(contentType)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取临时访问地址
|
||||||
|
* @param bucket 桶名
|
||||||
|
* @param objName 对象名
|
||||||
|
* @param expiryMinutes 过期时间,分钟
|
||||||
|
*/
|
||||||
|
fun getPresignedUrl(bucket: String, objName: String, expiryMinutes: Int = 15): String {
|
||||||
|
return client.getPresignedObjectUrl(
|
||||||
|
GetPresignedObjectUrlArgs.builder()
|
||||||
|
.method(Method.GET)
|
||||||
|
.bucket(bucket)
|
||||||
|
.`object`(objName)
|
||||||
|
.expiry(expiryMinutes, TimeUnit.MINUTES)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package ink.snowflake.server.utils.dao
|
package ink.snowflake.server.utils.dao
|
||||||
|
|
||||||
import ink.snowflake.server.SERVER_PATH_OSS
|
|
||||||
import ink.snowflake.server.model.request.ImageAnalyticsRequest
|
import ink.snowflake.server.model.request.ImageAnalyticsRequest
|
||||||
import ink.snowflake.server.model.database.ScaImagesTable
|
import ink.snowflake.server.model.database.ScaImagesTable
|
||||||
import ink.snowflake.server.utils.MyUtils.formatLocalDateTimeToString
|
import ink.snowflake.server.utils.MyUtils.formatLocalDateTimeToString
|
||||||
|
import ink.snowflake.server.utils.OSSUtils
|
||||||
import kotlinx.datetime.toKotlinLocalDateTime
|
import kotlinx.datetime.toKotlinLocalDateTime
|
||||||
import org.jetbrains.exposed.v1.core.SortOrder
|
import org.jetbrains.exposed.v1.core.SortOrder
|
||||||
import org.jetbrains.exposed.v1.jdbc.insert
|
import org.jetbrains.exposed.v1.jdbc.insert
|
||||||
@@ -43,8 +43,8 @@ object ImageDao {
|
|||||||
name = it[ScaImagesTable.name],
|
name = it[ScaImagesTable.name],
|
||||||
upload_datetime = formatLocalDateTimeToString(it[ScaImagesTable.upload_datetime]),
|
upload_datetime = formatLocalDateTimeToString(it[ScaImagesTable.upload_datetime]),
|
||||||
file_name = it[ScaImagesTable.file_name],
|
file_name = it[ScaImagesTable.file_name],
|
||||||
image_pre = "http://${SERVER_PATH_OSS}:9000/image-sca/raw/" + it[ScaImagesTable.image_pre],
|
image_pre = OSSUtils.getPresignedUrl("image-sca","raw/" + it[ScaImagesTable.image_pre]),
|
||||||
image_after = "http://${SERVER_PATH_OSS}:9000/image-sca/ai/" + it[ScaImagesTable.image_after],
|
image_after = OSSUtils.getPresignedUrl("image-sca","ai/" + it[ScaImagesTable.image_after]),
|
||||||
resolution = it[ScaImagesTable.resolution],
|
resolution = it[ScaImagesTable.resolution],
|
||||||
size = it[ScaImagesTable.size],
|
size = it[ScaImagesTable.size],
|
||||||
cocoon_count = it[ScaImagesTable.cocoon_count],
|
cocoon_count = it[ScaImagesTable.cocoon_count],
|
||||||
|
|||||||
Reference in New Issue
Block a user