index.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <!-- dall3 -->
  2. <template>
  3. <div class="prompt">
  4. <el-text tag="b">画面描述</el-text>
  5. <el-text tag="p">建议使用“形容词+动词+风格”的格式,使用“,”隔开</el-text>
  6. <el-input
  7. v-model="prompt"
  8. maxlength="1024"
  9. rows="5"
  10. class="w-100% mt-15px"
  11. input-style="border-radius: 7px;"
  12. placeholder="例如:童话里的小屋应该是什么样子?"
  13. show-word-limit
  14. type="textarea"
  15. />
  16. </div>
  17. <div class="hot-words">
  18. <div>
  19. <el-text tag="b">随机热词</el-text>
  20. </div>
  21. <el-space wrap class="word-list">
  22. <el-button
  23. round
  24. class="btn"
  25. :type="selectHotWord === hotWord ? 'primary' : 'default'"
  26. v-for="hotWord in ImageHotWords"
  27. :key="hotWord"
  28. @click="handleHotWordClick(hotWord)"
  29. >
  30. {{ hotWord }}
  31. </el-button>
  32. </el-space>
  33. </div>
  34. <div class="group-item">
  35. <div>
  36. <el-text tag="b">平台</el-text>
  37. </div>
  38. <el-space wrap class="group-item-body">
  39. <el-select
  40. v-model="otherPlatform"
  41. placeholder="Select"
  42. size="large"
  43. class="!w-350px"
  44. @change="handlerPlatformChange"
  45. >
  46. <el-option
  47. v-for="item in OtherPlatformEnum"
  48. :key="item.key"
  49. :label="item.name"
  50. :value="item.key"
  51. />
  52. </el-select>
  53. </el-space>
  54. </div>
  55. <div class="group-item">
  56. <div>
  57. <el-text tag="b">模型</el-text>
  58. </div>
  59. <el-space wrap class="group-item-body">
  60. <el-select v-model="model" placeholder="Select" size="large" class="!w-350px">
  61. <el-option v-for="item in models" :key="item.key" :label="item.name" :value="item.key" />
  62. </el-select>
  63. </el-space>
  64. </div>
  65. <div class="group-item">
  66. <div>
  67. <el-text tag="b">图片尺寸</el-text>
  68. </div>
  69. <el-space wrap class="group-item-body">
  70. <el-input v-model="width" type="number" class="w-170px" placeholder="图片宽度" />
  71. <el-input v-model="height" type="number" class="w-170px" placeholder="图片高度" />
  72. </el-space>
  73. </div>
  74. <div class="btns">
  75. <el-button type="primary" size="large" round :loading="drawIn" @click="handleGenerateImage">
  76. {{ drawIn ? '生成中' : '生成内容' }}
  77. </el-button>
  78. </div>
  79. </template>
  80. <script setup lang="ts">
  81. import { ImageApi, ImageDrawReqVO, ImageVO } from '@/api/ai/image'
  82. import {
  83. AiPlatformEnum,
  84. ChatGlmModels,
  85. ImageHotWords,
  86. ImageModelVO,
  87. OtherPlatformEnum,
  88. QianFanModels,
  89. TongYiWanXiangModels
  90. } from '@/views/ai/utils/constants'
  91. const message = useMessage() // 消息弹窗
  92. // 定义属性
  93. const drawIn = ref<boolean>(false) // 生成中
  94. const selectHotWord = ref<string>('') // 选中的热词
  95. // 表单
  96. const prompt = ref<string>('') // 提示词
  97. const width = ref<number>(512) // 图片宽度
  98. const height = ref<number>(512) // 图片高度
  99. const otherPlatform = ref<string>(AiPlatformEnum.TONG_YI) // 平台
  100. const models = ref<ImageModelVO[]>(TongYiWanXiangModels) // 模型 TongYiWanXiangModels、QianFanModels
  101. const model = ref<string>(models.value[0].key) // 模型
  102. const emits = defineEmits(['onDrawStart', 'onDrawComplete']) // 定义 emits
  103. /** 选择热词 */
  104. const handleHotWordClick = async (hotWord: string) => {
  105. // 情况一:取消选中
  106. if (selectHotWord.value == hotWord) {
  107. selectHotWord.value = ''
  108. return
  109. }
  110. // 情况二:选中
  111. selectHotWord.value = hotWord // 选中
  112. prompt.value = hotWord // 替换提示词
  113. }
  114. /** 图片生成 */
  115. const handleGenerateImage = async () => {
  116. // 二次确认
  117. await message.confirm(`确认生成内容?`)
  118. try {
  119. // 加载中
  120. drawIn.value = true
  121. // 回调
  122. emits('onDrawStart', AiPlatformEnum.STABLE_DIFFUSION)
  123. // 发送请求
  124. const form = {
  125. platform: otherPlatform.value,
  126. model: model.value, // 模型
  127. prompt: prompt.value, // 提示词
  128. width: width.value, // 图片宽度
  129. height: height.value, // 图片高度
  130. options: {}
  131. } as unknown as ImageDrawReqVO
  132. await ImageApi.drawImage(form)
  133. } finally {
  134. // 回调
  135. emits('onDrawComplete', AiPlatformEnum.STABLE_DIFFUSION)
  136. // 加载结束
  137. drawIn.value = false
  138. }
  139. }
  140. /** 填充值 */
  141. const settingValues = async (detail: ImageVO) => {
  142. prompt.value = detail.prompt
  143. width.value = detail.width
  144. height.value = detail.height
  145. }
  146. /** 平台切换 */
  147. const handlerPlatformChange = async (platform: string) => {
  148. // 切换平台,切换模型、风格
  149. if (AiPlatformEnum.TONG_YI === platform) {
  150. models.value = TongYiWanXiangModels
  151. } else if (AiPlatformEnum.YI_YAN === platform) {
  152. models.value = QianFanModels
  153. } else if (AiPlatformEnum.ZHI_PU === platform) {
  154. models.value = ChatGlmModels
  155. } else {
  156. models.value = []
  157. }
  158. // 切换平台,默认选择一个风格
  159. if (models.value.length > 0) {
  160. model.value = models.value[0].key
  161. } else {
  162. model.value = ''
  163. }
  164. }
  165. /** 暴露组件方法 */
  166. defineExpose({ settingValues })
  167. </script>
  168. <style scoped lang="scss">
  169. // 提示词
  170. .prompt {
  171. }
  172. // 热词
  173. .hot-words {
  174. display: flex;
  175. flex-direction: column;
  176. margin-top: 30px;
  177. .word-list {
  178. display: flex;
  179. flex-direction: row;
  180. flex-wrap: wrap;
  181. justify-content: start;
  182. margin-top: 15px;
  183. .btn {
  184. margin: 0;
  185. }
  186. }
  187. }
  188. // 模型
  189. .group-item {
  190. margin-top: 30px;
  191. .group-item-body {
  192. margin-top: 15px;
  193. width: 100%;
  194. }
  195. }
  196. .btns {
  197. display: flex;
  198. justify-content: center;
  199. margin-top: 50px;
  200. }
  201. </style>