提示:SpringBoot对接Midjourney Api
文章目录
目录
文章目录
后端代码
导包
controller层
工具类层
前端代码
申请API
测试结果
后端代码
导包
<!--添加hutool的依赖-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<!-- OkHttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<!-- Gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
controller层
@PostMapping("/createimage")
public Response createimage(String prompt){
System.out.println(prompt);
return new Response("0","success",ApiTestUtil.createImage(prompt));
}
@PostMapping("/fetch")
public Response fetch(String jobId){
String result = ApiTestUtil.fetch(jobId);
return new Response("0","success",result);
}
工具类层
public static String createImage(String prompt) {
Map<String, Object> map = new HashMap<>();
map.put("prompt", prompt);
map.put("mode", "fast");
map.put("hookUrl", "");
String result = HttpRequest.post("https://api.ttapi.io/midjourney/v1/imagine")
.body(JSONUtil.toJsonStr(map))
.header("TT-API-KEY", "请替换你自己的key")
.execute().body();
System.out.println("绘图请求响应:" + result);
return result;
}
public static String fetch(String jobId){
String result = HttpRequest.get("https://api.ttapi.io/midjourney/v1/fetch?jobId=" + jobId)
.header("TT-API-KEY", "请替换你自己的key")
.execute().body();
System.out.println("绘图结果:" + result);
return result;
}
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Chat Interface</title>
<!-- 引入 Vue 3 的 CDN -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- 引入 Font Awesome for avatars -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
/* 样式 */
body {
font-family: Avenir, Helvetica, Arial, sans-serif;
background-color: #f4f4f9;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.chat-container {
display: flex;
flex-direction: column;
height: 80vh;
width: 80vw;
max-width: 600px;
border: 1px solid #ccc;
border-radius: 10px;
overflow: hidden;
background-color: #fff;
}
.chat-window {
flex: 1;
padding: 10px;
overflow-y: auto;
background-color: #f4f4f9;
position: relative;
}
.chat-message {
display: flex;
margin-bottom: 10px;
align-items: flex-start;
}
.message-left {
flex-direction: row;
}
.message-right {
flex-direction: row-reverse;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #007bff;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-weight: bold;
margin: 0 10px;
font-size: 20px;
}
.message-bubble {
max-width: 70%;
padding: 10px;
border-radius: 20px;
background-color: #007bff;
color: white;
word-wrap: break-word;
}
.message-left .message-bubble {
background-color: #e4e6eb;
color: black;
}
.chat-input {
display: flex;
padding: 10px;
border-top: 1px solid #ccc;
background-color: #fff;
}
.chat-input input {
flex: 1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 20px;
outline: none;
}
.chat-input button {
margin-left: 10px;
padding: 10px 20px;
border: none;
background-color: #007bff;
color: white;
border-radius: 20px;
cursor: pointer;
outline: none;
}
.chat-input button:hover {
background-color: #0056b3;
}
.loading {
position: relative;
bottom: -20px;
display: flex;
align-items: center;
justify-content: center;
}
/* Loader animation styles */
.loader {
position: relative;
width: 2.5em;
height: 2.5em;
transform: rotate(165deg);
}
.loader:before, .loader:after {
content: "";
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0.5em;
height: 0.5em;
border-radius: 0.25em;
transform: translate(-50%, -50%);
}
.loader:before {
animation: before8 2s infinite;
}
.loader:after {
animation: after6 2s infinite;
}
@keyframes before8 {
0% {
width: 0.5em;
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
}
35% {
width: 2.5em;
box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);
}
70% {
width: 0.5em;
box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);
}
100% {
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
}
}
@keyframes after6 {
0% {
height: 0.5em;
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
}
35% {
height: 2.5em;
box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);
}
70% {
height: 0.5em;
box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);
}
100% {
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
}
}
</style>
</head>
<body>
<div id="app">
<div class="chat-container">
<div class="chat-window">
<div v-for="(message, index) in messages" :key="index" class="chat-message" :class="{'message-left': message.isUser, 'message-right': !message.isUser}">
<div class="avatar">
<i :class="message.isUser ? 'fas fa-user' : 'fas fa-robot'"></i>
</div>
<div class="message-bubble">
<img :src="imageUrl" alt="" style="width: 400px;height: 400px;">
</div>
</div>
<div class="loading" v-if="loading">
<div style="display: flex; align-items: center; justify-content: center;">
<div class="loader"></div>
<div style="margin-left: 10px; font-weight: bold; color: #e64c87;">加载中</div>
</div>
</div>
</div>
<div class="chat-input">
<input v-model="userInput" @keydown.enter="sendMessage" placeholder="Type your question..." />
<button @click="sendMessage">Send</button>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
userInput: '我需要你给我画一只猫',
messages: [
],
loading: false,
jobId:"",
imageUrl:""
};
},
methods: {
sendMessage() {
if (this.userInput.trim()) {
// 添加用户的消息
this.messages.push({ text: this.userInput, isUser: true });
// 模拟AI回复
this.simulateAIResponse(this.userInput);
// 清空输入框
this.userInput = '';
}
},
async simulateAIResponse(userText) {
this.loading = true;
try {
const res = await axios.post("http://localhost:8888/createimage", {
"prompt": this.userInput
}, { headers: { "Content-Type": "multipart/form-data" } });
if(res.data.code == 0){
this.jobId = JSON.parse(res.data.data).data.jobId;
const result = await axios.post("http://localhost:8888/fetch",{
"jobId": this.jobId
}, { headers: { "Content-Type": "multipart/form-data" }
});
if(result.data.code == 0){
this.imageUrl = JSON.parse(result.data.data).data.discordImage
this.loading = false;
}
}
} catch (error) {
console.error("Error fetching AI response:", error);
}
},
},
}).mount('#app');
</script>
</body>
</html>
申请API
https://ttapi.io/recharge
测试结果
这个主要对接了前一篇AI对话的博客,有需要自行去查找
参考博客地址:https://zhuanlan.zhihu.com/p/689296056
今日时间2024年8月29日,希望你天天开心,如有不会,请留言