瀏覽代碼

【代码优化】AI:绘图 index.vue 代码梳理 60%(StableDiffusion.vue)

YunaiV 11 月之前
父節點
當前提交
61bf6fb85b

+ 3 - 3
src/api/ai/image/index.ts

@@ -12,11 +12,11 @@ export interface ImageVO {
   publicStatus: boolean // 公开状态
   picUrl: string // 任务地址
   errorMessage: string // 错误信息
-  options: object // 配置 Map<string, string>
+  options: any // 配置 Map<string, string>
   taskId: number // 任务编号
   buttons: ImageMidjourneyButtonsVO[] // mj 操作按钮
-  createTime: string // 创建时间
-  finishTime: string // 完成时间
+  createTime: Date // 创建时间
+  finishTime: Date // 完成时间
 }
 
 export interface ImageDrawReqVO {

+ 75 - 7
src/views/ai/image/index/components/ImageDetail.vue

@@ -20,8 +20,8 @@
     <div class="item">
       <div class="tip">时间</div>
       <div class="body">
-        <div>提交时间:{{ detail.createTime }}</div>
-        <div>生成时间:{{ detail.finishTime }}</div>
+        <div>提交时间:{{ formatTime(detail.createTime, 'yyyy-MM-dd HH:mm:ss') }}</div>
+        <div>生成时间:{{ formatTime(detail.finishTime, 'yyyy-MM-dd HH:mm:ss') }}</div>
       </div>
     </div>
     <!-- 模型 -->
@@ -43,13 +43,73 @@
         {{ detail.picUrl }}
       </div>
     </div>
-    <!-- 风格 -->
-    <div class="item" v-if="detail?.options?.style">
+    <!-- StableDiffusion 专属区域 -->
+    <div
+      class="item"
+      v-if="detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.sampler"
+    >
+      <div class="tip">采样方法</div>
+      <div class="body">
+        {{
+          StableDiffusionSamplers.find(
+            (item: ImageModelVO) => item.key === detail?.options?.sampler
+          )?.name
+        }}
+      </div>
+    </div>
+    <div
+      class="item"
+      v-if="
+        detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.clipGuidancePreset
+      "
+    >
+      <div class="tip">CLIP</div>
+      <div class="body">
+        {{
+          StableDiffusionClipGuidancePresets.find(
+            (item: ImageModelVO) => item.key === detail?.options?.clipGuidancePreset
+          )?.name
+        }}
+      </div>
+    </div>
+    <div
+      class="item"
+      v-if="detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.stylePreset"
+    >
       <div class="tip">风格</div>
       <div class="body">
-        <!-- TODO @fan:貌似需要把 imageStyleList 搞到 api/image/index.ts 枚举起来? -->
-        <!-- TODO @fan:这里的展示,可能需要按照平台做区分 -->
-        {{ detail?.options?.style }}
+        {{
+          StableDiffusionStylePresets.find(
+            (item: ImageModelVO) => item.key === detail?.options?.stylePreset
+          )?.name
+        }}
+      </div>
+    </div>
+    <div
+      class="item"
+      v-if="detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.steps"
+    >
+      <div class="tip">迭代步数</div>
+      <div class="body">
+        {{ detail?.options?.steps }}
+      </div>
+    </div>
+    <div
+      class="item"
+      v-if="detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.scale"
+    >
+      <div class="tip">引导系数</div>
+      <div class="body">
+        {{ detail?.options?.scale }}
+      </div>
+    </div>
+    <div
+      class="item"
+      v-if="detail.platform === AiPlatformEnum.STABLE_DIFFUSION && detail?.options?.seed"
+    >
+      <div class="tip">随机因子</div>
+      <div class="body">
+        {{ detail?.options?.seed }}
       </div>
     </div>
   </el-drawer>
@@ -58,6 +118,14 @@
 <script setup lang="ts">
 import { ImageApi, ImageVO } from '@/api/ai/image'
 import ImageCard from './ImageCard.vue'
+import {
+  AiPlatformEnum,
+  ImageModelVO,
+  StableDiffusionClipGuidancePresets,
+  StableDiffusionSamplers,
+  StableDiffusionStylePresets
+} from '@/views/ai/utils/constants'
+import { formatTime } from '@/utils'
 
 const showDrawer = ref<boolean>(false) // 是否显示
 const detail = ref<ImageVO>({} as ImageVO) // 图片详细信息

+ 271 - 0
src/views/ai/image/index/components/stableDiffusion/index.vue

@@ -0,0 +1,271 @@
+<!-- dall3 -->
+<template>
+  <div class="prompt">
+    <el-text tag="b">画面描述</el-text>
+    <el-text tag="p">建议使用“形容词+动词+风格”的格式,使用“,”隔开</el-text>
+    <el-input
+      v-model="prompt"
+      maxlength="1024"
+      rows="5"
+      class="w-100% mt-15px"
+      input-style="border-radius: 7px;"
+      placeholder="例如:童话里的小屋应该是什么样子?"
+      show-word-limit
+      type="textarea"
+    />
+  </div>
+  <div class="hot-words">
+    <div>
+      <el-text tag="b">随机热词</el-text>
+    </div>
+    <el-space wrap class="word-list">
+      <el-button
+        round
+        class="btn"
+        :type="selectHotWord === hotWord ? 'primary' : 'default'"
+        v-for="hotWord in ImageHotEnglishWords"
+        :key="hotWord"
+        @click="handleHotWordClick(hotWord)"
+      >
+        {{ hotWord }}
+      </el-button>
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">采样方法</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-select v-model="sampler" placeholder="Select" size="large" class="!w-350px">
+        <el-option
+          v-for="item in StableDiffusionSamplers"
+          :key="item.key"
+          :label="item.name"
+          :value="item.key"
+        />
+      </el-select>
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">CLIP</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-select v-model="clipGuidancePreset" placeholder="Select" size="large" class="!w-350px">
+        <el-option
+          v-for="item in StableDiffusionClipGuidancePresets"
+          :key="item.key"
+          :label="item.name"
+          :value="item.key"
+        />
+      </el-select>
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">风格</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-select v-model="stylePreset" placeholder="Select" size="large" class="!w-350px">
+        <el-option
+          v-for="item in StableDiffusionStylePresets"
+          :key="item.key"
+          :label="item.name"
+          :value="item.key"
+        />
+      </el-select>
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">图片尺寸</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-input v-model="width" class="w-170px" placeholder="图片宽度" />
+      <el-input v-model="height" class="w-170px" placeholder="图片高度" />
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">迭代步数</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-input
+        v-model="steps"
+        type="number"
+        size="large"
+        class="!w-350px"
+        placeholder="Please input"
+      />
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">引导系数</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-input
+        v-model="scale"
+        type="number"
+        size="large"
+        class="!w-350px"
+        placeholder="Please input"
+      />
+    </el-space>
+  </div>
+  <div class="group-item">
+    <div>
+      <el-text tag="b">随机因子</el-text>
+    </div>
+    <el-space wrap class="group-item-body">
+      <el-input
+        v-model="seed"
+        type="number"
+        size="large"
+        class="!w-350px"
+        placeholder="Please input"
+      />
+    </el-space>
+  </div>
+  <div class="btns">
+    <el-button type="primary" size="large" round :loading="drawIn" @click="handleGenerateImage">
+      {{ drawIn ? '生成中' : '生成内容' }}
+    </el-button>
+  </div>
+</template>
+<script setup lang="ts">
+import { ImageApi, ImageDrawReqVO, ImageVO } from '@/api/ai/image'
+import { hasChinese } from '@/views/ai/utils/utils'
+import {
+  ImageHotEnglishWords,
+  StableDiffusionClipGuidancePresets,
+  StableDiffusionSamplers,
+  StableDiffusionStylePresets
+} from '@/views/ai/utils/constants'
+
+const message = useMessage() // 消息弹窗
+
+// 定义属性
+const drawIn = ref<boolean>(false) // 生成中
+const selectHotWord = ref<string>('') // 选中的热词
+// 表单
+const prompt = ref<string>('') // 提示词
+const width = ref<number>(512) // 图片宽度
+const height = ref<number>(512) // 图片高度
+const sampler = ref<string>('DDIM') // 采样方法
+const steps = ref<number>(20) // 迭代步数
+const seed = ref<number>(42) // 控制生成图像的随机性
+const scale = ref<number>(7.5) // 引导系数
+const clipGuidancePreset = ref<string>('NONE') // 文本提示相匹配的图像(clip_guidance_preset) 简称 CLIP
+const stylePreset = ref<string>('3d-model') // 风格
+
+const emits = defineEmits(['onDrawStart', 'onDrawComplete']) // 定义 emits
+
+/** 选择热词 */
+const handleHotWordClick = async (hotWord: string) => {
+  // 情况一:取消选中
+  if (selectHotWord.value == hotWord) {
+    selectHotWord.value = ''
+    return
+  }
+
+  // 情况二:选中
+  selectHotWord.value = hotWord // 选中
+  prompt.value = hotWord // 替换提示词
+}
+
+/** 图片生成 */
+const handleGenerateImage = async () => {
+  // 二次确认
+  if (hasChinese(prompt.value)) {
+    message.alert('暂不支持中文!')
+    return
+  }
+  await message.confirm(`确认生成内容?`)
+
+  try {
+    // 加载中
+    drawIn.value = true
+    // 回调
+    emits('onDrawStart', 'StableDiffusion')
+    // 发送请求
+    const form = {
+      platform: 'StableDiffusion',
+      model: 'stable-diffusion-v1-6',
+      prompt: prompt.value, // 提示词
+      width: width.value, // 图片宽度
+      height: height.value, // 图片高度
+      options: {
+        seed: seed.value, // 随机种子
+        steps: steps.value, // 图片生成步数
+        scale: scale.value, // 引导系数
+        sampler: sampler.value, // 采样算法
+        clipGuidancePreset: clipGuidancePreset.value, // 文本提示相匹配的图像 CLIP
+        stylePreset: stylePreset.value // 风格
+      }
+    } as ImageDrawReqVO
+    await ImageApi.drawImage(form)
+  } finally {
+    // 回调
+    emits('onDrawComplete', 'StableDiffusion')
+    // 加载结束
+    drawIn.value = false
+  }
+}
+
+/** 填充值 */
+const settingValues = async (detail: ImageVO) => {
+  prompt.value = detail.prompt
+  width.value = detail.width
+  height.value = detail.height
+  seed.value = detail.options?.seed
+  steps.value = detail.options?.steps
+  scale.value = detail.options?.scale
+  sampler.value = detail.options?.sampler
+  clipGuidancePreset.value = detail.options?.clipGuidancePreset
+  stylePreset.value = detail.options?.stylePreset
+}
+
+/** 暴露组件方法 */
+defineExpose({ settingValues })
+</script>
+<style scoped lang="scss">
+// 提示词
+.prompt {
+}
+
+// 热词
+.hot-words {
+  display: flex;
+  flex-direction: column;
+  margin-top: 30px;
+
+  .word-list {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    justify-content: start;
+    margin-top: 15px;
+
+    .btn {
+      margin: 0;
+    }
+  }
+}
+
+// 模型
+.group-item {
+  margin-top: 30px;
+
+  .group-item-body {
+    margin-top: 15px;
+    width: 100%;
+  }
+}
+
+.btns {
+  display: flex;
+  justify-content: center;
+  margin-top: 50px;
+}
+</style>

+ 3 - 3
src/views/ai/image/index/index.vue

@@ -27,12 +27,12 @@
 </template>
 
 <script setup lang="ts">
-import Dall3 from './dall3/index.vue'
-import Midjourney from './midjourney/index.vue'
-import StableDiffusion from './stable-diffusion/index.vue'
 import ImageList from './components/ImageList.vue'
 import { AiPlatformEnum } from '@/views/ai/utils/constants'
 import { ImageVO } from '@/api/ai/image'
+import Dall3 from './dall3/index.vue'
+import Midjourney from './midjourney/index.vue'
+import StableDiffusion from './components/stableDiffusion/index.vue'
 
 const imageListRef = ref<any>() // image 列表 ref
 const dall3Ref = ref<any>() // openai ref

+ 0 - 437
src/views/ai/image/index/stable-diffusion/index.vue

@@ -1,437 +0,0 @@
-<!-- dall3 -->
-<template>
-  <div class="prompt">
-    <el-text tag="b">画面描述</el-text>
-    <el-text tag="p">建议使用“形容词+动词+风格”的格式,使用“,”隔开</el-text>
-    <!-- TODO @fan:style 看看能不能哟 unocss 替代 -->
-    <el-input
-      v-model="prompt"
-      maxlength="1024"
-      rows="5"
-      style="width: 100%; margin-top: 15px"
-      input-style="border-radius: 7px;"
-      placeholder="例如:童话里的小屋应该是什么样子?"
-      show-word-limit
-      type="textarea"
-    />
-  </div>
-  <div class="hot-words">
-    <div>
-      <el-text tag="b">随机热词</el-text>
-    </div>
-    <el-space wrap class="word-list">
-      <el-button
-        round
-        class="btn"
-        :type="selectHotWord === hotWord ? 'primary' : 'default'"
-        v-for="hotWord in hotWords"
-        :key="hotWord"
-        @click="handleHotWordClick(hotWord)"
-      >
-        {{ hotWord }}
-      </el-button>
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">采样方法</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-select v-model="selectSampler" placeholder="Select" size="large" style="width: 350px">
-        <el-option v-for="item in sampler" :key="item.key" :label="item.name" :value="item.key" />
-      </el-select>
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">CLIP</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-select
-        v-model="selectClipGuidancePreset"
-        placeholder="Select"
-        size="large"
-        style="width: 350px"
-      >
-        <el-option
-          v-for="item in clipGuidancePresets"
-          :key="item.key"
-          :label="item.name"
-          :value="item.key"
-        />
-      </el-select>
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">风格</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-select v-model="selectStylePreset" placeholder="Select" size="large" style="width: 350px">
-        <el-option
-          v-for="item in stylePresets"
-          :key="item.key"
-          :label="item.name"
-          :value="item.key"
-        />
-      </el-select>
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">图片尺寸</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-input v-model="imageWidth" style="width: 170px" placeholder="图片宽度" />
-      <el-input v-model="imageHeight" style="width: 170px" placeholder="图片高度" />
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">迭代步数</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-input
-        v-model="steps"
-        type="number"
-        size="large"
-        style="width: 350px"
-        placeholder="Please input"
-      />
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">引导系数</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-input
-        v-model="scale"
-        type="number"
-        size="large"
-        style="width: 350px"
-        placeholder="Please input"
-      />
-    </el-space>
-  </div>
-  <div class="group-item">
-    <div>
-      <el-text tag="b">随机因子</el-text>
-    </div>
-    <el-space wrap class="group-item-body">
-      <el-input
-        v-model="seed"
-        type="number"
-        size="large"
-        style="width: 350px"
-        placeholder="Please input"
-      />
-    </el-space>
-  </div>
-  <div class="btns">
-    <el-button type="primary" size="large" round :loading="drawIn" @click="handleGenerateImage">
-      {{ drawIn ? '生成中' : '生成内容' }}
-    </el-button>
-  </div>
-</template>
-<script setup lang="ts">
-import { ImageApi, ImageDrawReqVO, ImageVO } from '@/api/ai/image'
-import { hasChinese } from '@/views/ai/utils/utils'
-
-// image 模型
-interface ImageModelVO {
-  key: string
-  name: string
-}
-
-// 定义属性
-const prompt = ref<string>('') // 提示词
-const drawIn = ref<boolean>(false) // 生成中
-const selectHotWord = ref<string>('') // 选中的热词
-const imageWidth = ref<number>(512) // 图片宽度
-const imageHeight = ref<number>(512) // 图片高度
-
-const hotWords = ref<string[]>([
-  '中国旗袍',
-  '古装美女',
-  '卡通头像',
-  '机甲战士',
-  '童话小屋',
-  '中国长城'
-]) // 热词
-// message
-const message = useMessage()
-
-// 采样方法
-const selectSampler = ref<string>('DDIM') // 模型
-// DDIM DDPM K_DPMPP_2M K_DPMPP_2S_ANCESTRAL K_DPM_2 K_DPM_2_ANCESTRAL K_EULER K_EULER_ANCESTRAL K_HEUN K_LMS
-const sampler = ref<ImageModelVO[]>([
-  {
-    key: 'DDIM',
-    name: 'DDIM'
-  },
-  {
-    key: 'DDPM',
-    name: 'DDPM'
-  },
-  {
-    key: 'K_DPMPP_2M',
-    name: 'K_DPMPP_2M'
-  },
-  {
-    key: 'K_DPMPP_2S_ANCESTRAL',
-    name: 'K_DPMPP_2S_ANCESTRAL'
-  },
-  {
-    key: 'K_DPM_2',
-    name: 'K_DPM_2'
-  },
-  {
-    key: 'K_DPM_2_ANCESTRAL',
-    name: 'K_DPM_2_ANCESTRAL'
-  },
-  {
-    key: 'K_EULER',
-    name: 'K_EULER'
-  },
-  {
-    key: 'K_EULER_ANCESTRAL',
-    name: 'K_EULER_ANCESTRAL'
-  },
-  {
-    key: 'K_HEUN',
-    name: 'K_HEUN'
-  },
-  {
-    key: 'K_LMS',
-    name: 'K_LMS'
-  }
-])
-
-// 风格
-// 3d-model analog-film anime cinematic comic-book digital-art enhance fantasy-art isometric
-// line-art low-poly modeling-compound neon-punk origami photographic pixel-art tile-texture
-const selectStylePreset = ref<string>('3d-model') // 模型
-const stylePresets = ref<ImageModelVO[]>([
-  {
-    key: '3d-model',
-    name: '3d-model'
-  },
-  {
-    key: 'analog-film',
-    name: 'analog-film'
-  },
-  {
-    key: 'anime',
-    name: 'anime'
-  },
-  {
-    key: 'cinematic',
-    name: 'cinematic'
-  },
-  {
-    key: 'comic-book',
-    name: 'comic-book'
-  },
-  {
-    key: 'digital-art',
-    name: 'digital-art'
-  },
-  {
-    key: 'enhance',
-    name: 'enhance'
-  },
-  {
-    key: 'fantasy-art',
-    name: 'fantasy-art'
-  },
-  {
-    key: 'isometric',
-    name: 'isometric'
-  },
-  {
-    key: 'line-art',
-    name: 'line-art'
-  },
-  {
-    key: 'low-poly',
-    name: 'low-poly'
-  },
-  {
-    key: 'modeling-compound',
-    name: 'modeling-compound'
-  },
-  // neon-punk origami photographic pixel-art tile-texture
-  {
-    key: 'neon-punk',
-    name: 'neon-punk'
-  },
-  {
-    key: 'origami',
-    name: 'origami'
-  },
-  {
-    key: 'photographic',
-    name: 'photographic'
-  },
-  {
-    key: 'pixel-art',
-    name: 'pixel-art'
-  },
-  {
-    key: 'tile-texture',
-    name: 'tile-texture'
-  }
-])
-
-// 文本提示相匹配的图像(clip_guidance_preset) 简称 CLIP
-// https://platform.stability.ai/docs/api-reference#tag/SDXL-and-SD1.6/operation/textToImage
-// FAST_BLUE FAST_GREEN NONE SIMPLE SLOW SLOWER SLOWEST
-const selectClipGuidancePreset = ref<string>('NONE') // 模型
-const clipGuidancePresets = ref<ImageModelVO[]>([
-  {
-    key: 'NONE',
-    name: 'NONE'
-  },
-  {
-    key: 'FAST_BLUE',
-    name: 'FAST_BLUE'
-  },
-  {
-    key: 'FAST_GREEN',
-    name: 'FAST_GREEN'
-  },
-  {
-    key: 'SIMPLE',
-    name: 'SIMPLE'
-  },
-  {
-    key: 'SLOW',
-    name: 'SLOW'
-  },
-  {
-    key: 'SLOWER',
-    name: 'SLOWER'
-  },
-  {
-    key: 'SLOWEST',
-    name: 'SLOWEST'
-  }
-])
-
-const steps = ref<number>(20) // 迭代步数
-const seed = ref<number>(42) // 控制生成图像的随机性
-const scale = ref<number>(7.5) // 引导系数
-
-// 定义 Props
-const props = defineProps({})
-// 定义 emits
-const emits = defineEmits(['onDrawStart', 'onDrawComplete'])
-
-/** 热词 - click  */
-const handleHotWordClick = async (hotWord: string) => {
-  // 取消选中
-  if (selectHotWord.value == hotWord) {
-    selectHotWord.value = ''
-    return
-  }
-  // 选中
-  selectHotWord.value = hotWord
-  // 替换提示词
-  prompt.value = hotWord
-}
-
-/**  图片生产  */
-const handleGenerateImage = async () => {
-  // 二次确认
-  await message.confirm(`确认生成内容?`)
-  if (await hasChinese(prompt.value)) {
-    message.alert('暂不支持中文!')
-    return
-  }
-  try {
-    // 加载中
-    drawIn.value = true
-    // 回调
-    emits('onDrawStart', 'StableDiffusion')
-    // 发送请求
-    const form = {
-      platform: 'StableDiffusion',
-      model: 'stable-diffusion-v1-6',
-      prompt: prompt.value, // 提示词
-      width: imageWidth.value, // 图片宽度
-      height: imageHeight.value, // 图片高度
-      options: {
-        seed: seed.value, // 随机种子
-        steps: steps.value, // 图片生成步数
-        scale: scale.value, // 引导系数
-        sampler: selectSampler.value, // 采样算法
-        clipGuidancePreset: selectClipGuidancePreset.value, // 文本提示相匹配的图像 CLIP
-        stylePreset: selectStylePreset.value // 风格
-      }
-    } as ImageDrawReqVO
-    await ImageApi.drawImage(form)
-  } finally {
-    // 回调
-    emits('onDrawComplete', 'StableDiffusion')
-    // 加载结束
-    drawIn.value = false
-  }
-}
-
-/** 填充值 */
-const settingValues = async (imageDetail: ImageVO) => {
-  prompt.value = imageDetail.prompt
-  imageWidth.value = imageDetail.width
-  imageHeight.value = imageDetail.height
-  seed.value = imageDetail.options?.seed
-  steps.value = imageDetail.options?.steps
-  scale.value = imageDetail.options?.scale
-  selectSampler.value = imageDetail.options?.sampler
-  selectClipGuidancePreset.value = imageDetail.options?.clipGuidancePreset
-  selectStylePreset.value = imageDetail.options?.stylePreset
-}
-
-/** 暴露组件方法 */
-defineExpose({ settingValues })
-</script>
-<style scoped lang="scss">
-// 提示词
-.prompt {
-}
-
-// 热词
-.hot-words {
-  display: flex;
-  flex-direction: column;
-  margin-top: 30px;
-
-  .word-list {
-    display: flex;
-    flex-direction: row;
-    flex-wrap: wrap;
-    justify-content: start;
-    margin-top: 15px;
-
-    .btn {
-      margin: 0;
-    }
-  }
-}
-
-// 模型
-.group-item {
-  margin-top: 30px;
-
-  .group-item-body {
-    margin-top: 15px;
-    width: 100%;
-  }
-}
-
-.btns {
-  display: flex;
-  justify-content: center;
-  margin-top: 50px;
-}
-</style>

+ 170 - 0
src/views/ai/utils/constants.ts

@@ -40,3 +40,173 @@ export const AiMusicStatusEnum = {
   SUCCESS: 20, // 已完成
   FAIL: 30 // 已失败
 }
+
+// ========== 【图片 UI】相关的枚举 ==========
+export const ImageHotWords = [
+  '中国旗袍',
+  '古装美女',
+  '卡通头像',
+  '机甲战士',
+  '童话小屋',
+  '中国长城'
+] // 图片热词
+
+export const ImageHotEnglishWords = [
+  'Chinese Cheongsam',
+  'Ancient Beauty',
+  'Cartoon Avatar',
+  'Mech Warrior',
+  'Fairy Tale Cottage',
+  'The Great Wall of China'
+] // 图片热词(英文)
+
+export interface ImageModelVO {
+  key: string
+  name: string
+}
+
+export const StableDiffusionSamplers = ref<ImageModelVO[]>([
+  {
+    key: 'DDIM',
+    name: 'DDIM'
+  },
+  {
+    key: 'DDPM',
+    name: 'DDPM'
+  },
+  {
+    key: 'K_DPMPP_2M',
+    name: 'K_DPMPP_2M'
+  },
+  {
+    key: 'K_DPMPP_2S_ANCESTRAL',
+    name: 'K_DPMPP_2S_ANCESTRAL'
+  },
+  {
+    key: 'K_DPM_2',
+    name: 'K_DPM_2'
+  },
+  {
+    key: 'K_DPM_2_ANCESTRAL',
+    name: 'K_DPM_2_ANCESTRAL'
+  },
+  {
+    key: 'K_EULER',
+    name: 'K_EULER'
+  },
+  {
+    key: 'K_EULER_ANCESTRAL',
+    name: 'K_EULER_ANCESTRAL'
+  },
+  {
+    key: 'K_HEUN',
+    name: 'K_HEUN'
+  },
+  {
+    key: 'K_LMS',
+    name: 'K_LMS'
+  }
+])
+
+export const StableDiffusionStylePresets = ref<ImageModelVO[]>([
+  {
+    key: '3d-model',
+    name: '3d-model'
+  },
+  {
+    key: 'analog-film',
+    name: 'analog-film'
+  },
+  {
+    key: 'anime',
+    name: 'anime'
+  },
+  {
+    key: 'cinematic',
+    name: 'cinematic'
+  },
+  {
+    key: 'comic-book',
+    name: 'comic-book'
+  },
+  {
+    key: 'digital-art',
+    name: 'digital-art'
+  },
+  {
+    key: 'enhance',
+    name: 'enhance'
+  },
+  {
+    key: 'fantasy-art',
+    name: 'fantasy-art'
+  },
+  {
+    key: 'isometric',
+    name: 'isometric'
+  },
+  {
+    key: 'line-art',
+    name: 'line-art'
+  },
+  {
+    key: 'low-poly',
+    name: 'low-poly'
+  },
+  {
+    key: 'modeling-compound',
+    name: 'modeling-compound'
+  },
+  // neon-punk origami photographic pixel-art tile-texture
+  {
+    key: 'neon-punk',
+    name: 'neon-punk'
+  },
+  {
+    key: 'origami',
+    name: 'origami'
+  },
+  {
+    key: 'photographic',
+    name: 'photographic'
+  },
+  {
+    key: 'pixel-art',
+    name: 'pixel-art'
+  },
+  {
+    key: 'tile-texture',
+    name: 'tile-texture'
+  }
+])
+
+export const StableDiffusionClipGuidancePresets = ref<ImageModelVO[]>([
+  {
+    key: 'NONE',
+    name: 'NONE'
+  },
+  {
+    key: 'FAST_BLUE',
+    name: 'FAST_BLUE'
+  },
+  {
+    key: 'FAST_GREEN',
+    name: 'FAST_GREEN'
+  },
+  {
+    key: 'SIMPLE',
+    name: 'SIMPLE'
+  },
+  {
+    key: 'SLOW',
+    name: 'SLOW'
+  },
+  {
+    key: 'SLOWER',
+    name: 'SLOWER'
+  },
+  {
+    key: 'SLOWEST',
+    name: 'SLOWEST'
+  }
+])

+ 1 - 1
src/views/ai/utils/utils.ts

@@ -8,6 +8,6 @@
  */
 
 /**  判断字符串是否包含中文  */
-export const hasChinese = async (str) => {
+export const hasChinese = (str: string) => {
   return /[\u4e00-\u9fa5]/.test(str)
 }