Ver código fonte

智能绘画接口连通

liyanbo 1 ano atrás
pai
commit
92e49dccea
3 arquivos alterados com 148 adições e 47 exclusões
  1. 15 3
      src/api/questions.js
  2. BIN
      src/assets/images/xiaozhi.png
  3. 133 44
      src/views/AIPainting.vue

+ 15 - 3
src/api/questions.js

@@ -43,6 +43,16 @@ export async function sendChatMessageStream (
   })
 }
 
+
+/**
+ * AI 图像生成状态的枚举
+ */
+export const AiImageStatusEnum = {
+  IN_PROGRESS: 10, // 进行中
+  SUCCESS: 20, // 已完成
+  FAIL: 30 // 已失败
+}
+
 // 生成图片
 export function CreatePainting (data){
   return axios({
@@ -52,10 +62,12 @@ export function CreatePainting (data){
   })
 }
 // 绘画
-export function CreatePaintingGetMy (data){
+export function PaintingGetMys (ids){
+  const convertedIds = ids.map(id => String(Number(id)));
+  console.log(convertedIds);
   return axios({
-    url: "bjdxWeb/ai/painting-get-my",
+    url: "bjdxWeb/ai/painting-get-mys",
     method: 'get',
-    data
+    params: { ids: convertedIds.join(',') }
   })
 }

BIN
src/assets/images/xiaozhi.png


+ 133 - 44
src/views/AIPainting.vue

@@ -17,44 +17,58 @@
         <div class="chat-dialog">
           <!-- 对话消息列表 -->
           <div class="message-list">
-            <!-- 用户消息 -->
-            <div class="user-message">生成图片</div>
-            <!-- AI生成图片对话框 -->
-            <div class="ai-message">
-              接下来我将生成四张会飞的猪的图片。画面风格是写实风,主体是一只身体肥硕、粉色皮肤、小短腿的猪,它长着两只大耳朵和一条卷曲的尾巴,正扇动着一对白色的翅膀在空中飞行。<br />
-               <div class="image-list">
-                <el-image
-                  v-for="(image, index) in srcList"
-                  :key="index"
-                  style=" width: fit-content; height: 150px; margin: 10px;"
-                  :src="image"
-                  :preview-src-list="srcList"
-                  fit="cover"
-                  show-progress
-                >
-                  <template
-                    #toolbar="{ actions, prev, next, reset, activeIndex, setActiveItem }"
+            <div v-for="(item, index) in imageAllList" :key="index">
+
+              <!-- AI消息 -->
+              <div class="ai-message" v-if="item.type !== 'user'">
+                {{ item.content }}
+              </div>
+
+              <!-- 用户消息 -->
+              <div class="user-message" v-if="item.type === 'user'">
+                {{ item.content }}
+              </div>
+              <!-- AI生成图片对话框 -->
+              <div class="ai-message" v-if="item.type !== 'user'">
+
+                {{ item.content }}
+                {{item.imageList}}
+
+                <div class="image-list" v-if="item.imageList">
+                  <el-image
+                      v-for="(image, index) in item.imageList"
+                      :key="index"
+                      style=" width: fit-content; height: 150px; margin: 10px;"
+                      :src="image"
+                      :preview-src-list="item.imageList"
+                      fit="cover"
+                      show-progress
                   >
-                    <el-icon @click="prev"><Back /></el-icon>
-                    <el-icon @click="next"><Right /></el-icon>
-                    <el-icon @click="setActiveItem(srcList.length - 1)">
-                      <DArrowRight />
-                    </el-icon>
-                    <el-icon @click="actions('zoomOut')"><ZoomOut /></el-icon>
-                    <el-icon
-                      @click="actions('zoomIn', { enableTransition: false, zoomRate: 2 })">
-                      <ZoomIn />
-                    </el-icon>
-                    <el-icon
-                      @click="actions('clockwise', { rotateDeg: 180, enableTransition: false })">
-                      <RefreshRight />
-                    </el-icon>
-                    <el-icon @click="actions('anticlockwise')"><RefreshLeft /></el-icon>
-                    <el-icon @click="reset"><Refresh /></el-icon>
-                    <el-icon @click="download(activeIndex)"><Download /></el-icon>
-                  </template>
-                </el-image>
+                    <template
+                        #toolbar="{ actions, prev, next, reset, activeIndex, setActiveItem }"
+                    >
+                      <el-icon @click="prev"><Back /></el-icon>
+                      <el-icon @click="next"><Right /></el-icon>
+                      <el-icon @click="setActiveItem(item.imageList.length - 1)">
+                        <DArrowRight />
+                      </el-icon>
+                      <el-icon @click="actions('zoomOut')"><ZoomOut /></el-icon>
+                      <el-icon
+                          @click="actions('zoomIn', { enableTransition: false, zoomRate: 2 })">
+                        <ZoomIn />
+                      </el-icon>
+                      <el-icon
+                          @click="actions('clockwise', { rotateDeg: 180, enableTransition: false })">
+                        <RefreshRight />
+                      </el-icon>
+                      <el-icon @click="actions('anticlockwise')"><RefreshLeft /></el-icon>
+                      <el-icon @click="reset"><Refresh /></el-icon>
+                      <el-icon @click="download(activeIndex)"><Download /></el-icon>
+                    </template>
+                  </el-image>
+                </div>
               </div>
+
             </div>
           </div>
           <!-- 输入框和发送按钮 -->
@@ -73,8 +87,8 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from 'vue'
-import { CreatePainting,CreatePaintingGetMy} from '@/api/questions.js'
+import { ref, onMounted,onUnmounted} from 'vue'
+import {AiImageStatusEnum, CreatePainting, PaintingGetMys} from '@/api/questions.js'
 import { useRouter, useRoute } from 'vue-router'
 import {
   Document,
@@ -113,6 +127,33 @@ const sendMessage = () => {
   if (inputMessage.value.trim()) {
     messages.value.push(inputMessage.value.trim())
     inputMessage.value = ''
+
+    let content = inputMessage.value.trim();
+    console.log("-------",content)
+    content = "给我一个小妖怪";
+    console.log("-------",content)
+
+    imageAllList.value.push({
+      type: 'user',
+      content: content,
+    })
+    imageAllList.value.push({
+      type: 'ai',
+      content: "正在为您生成图片,请稍等...",
+    })
+
+
+    CreatePainting({
+      "modelId": 56,
+      "prompt":content,
+      "width":1024,
+      "height":1024
+    }).then(res=>{
+      console.log("生成图片",res)
+      //目前写死调用已生成的图片,全部通了后再改
+      // inProgressImageMap.value[res.data] = {}
+      inProgressImageMap.value[260] = {}
+    })
   }
 }
 
@@ -133,16 +174,64 @@ import {
 const url =
   'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
 const srcList = [
-  'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
-  'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
   'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
-  'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
-  'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
-  'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
-  'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
 ]
 
 
+const imageAllList = ref([]) // 对话的消息列表
+const imageList = ref([]) // image 列表
+// 图片轮询相关的参数(正在生成中的)
+const inProgressImageMap = ref({}) // 监听的 image 映射,一般是生成中(需要轮询),key 为 image 编号,value 为 image
+const inProgressTimer = ref() // 生成中的 image 定时器,轮询生成进展
+
+
+/** 轮询生成中的 image 列表 */
+const refreshWatchImages = async () => {
+  const imageIds = Object.keys(inProgressImageMap.value)
+  if (imageIds.length == 0) {
+    return
+  }
+  console.log("轮询生成中的 image 列表",imageIds)
+  const list = await PaintingGetMys(imageIds)
+  console.log("轮询生成中的 image 列表",list)
+  const newWatchImages = {}
+  list.data.forEach((image) => {
+    if (image.status === AiImageStatusEnum.IN_PROGRESS) {
+      newWatchImages[image.id] = image
+    } else {
+    //   const index = imageList.value.findIndex((oldImage) => image.id === oldImage.id)
+    //   if (index >= 0) {
+        // 更新 imageList
+        // imageList.value[index] = image
+
+        imageAllList.value.pop();
+        imageAllList.value.push({
+          type: 'ai',
+          content: "已为您生成图片:",
+          imageList: image.picUrl,
+        })
+      // }
+    }
+  })
+  console.log("================",imageAllList)
+  inProgressImageMap.value = newWatchImages
+}
+
+
+/** 组件挂在的时候 */
+onMounted(async () => {
+  // 自动刷新 image 列表
+  inProgressTimer.value = setInterval(async () => {
+    await refreshWatchImages()
+  }, 1000 * 3)
+})
+
+/** 组件取消挂在的时候 */
+onUnmounted(async () => {
+  if (inProgressTimer.value) {
+    clearInterval(inProgressTimer.value)
+  }
+})
 </script>
 
 <style scoped lang="scss">