index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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 v-model="otherPlatform" placeholder="Select" size="large" class="!w-350px" @change="handlerPlatformChange">
  40. <el-option
  41. v-for="item in OtherPlatformEnum"
  42. :key="item.key"
  43. :label="item.name"
  44. :value="item.key"
  45. />
  46. </el-select>
  47. </el-space>
  48. </div>
  49. <div class="group-item">
  50. <div>
  51. <el-text tag="b">模型</el-text>
  52. </div>
  53. <el-space wrap class="group-item-body">
  54. <el-select v-model="model" placeholder="Select" size="large" class="!w-350px">
  55. <el-option
  56. v-for="item in models"
  57. :key="item.key"
  58. :label="item.name"
  59. :value="item.key"
  60. />
  61. </el-select>
  62. </el-space>
  63. </div>
  64. <div class="group-item">
  65. <div>
  66. <el-text tag="b">图片尺寸</el-text>
  67. </div>
  68. <el-space wrap class="group-item-body">
  69. <el-input v-model="width" type="number" class="w-170px" placeholder="图片宽度" />
  70. <el-input v-model="height" type="number" class="w-170px" placeholder="图片高度" />
  71. </el-space>
  72. </div>
  73. <div class="btns">
  74. <el-button type="primary" size="large" round :loading="drawIn" @click="handleGenerateImage">
  75. {{ drawIn ? '生成中' : '生成内容' }}
  76. </el-button>
  77. </div>
  78. </template>
  79. <script setup lang="ts">
  80. import {ImageApi, ImageDrawReqVO, ImageVO} from '@/api/ai/image'
  81. import {
  82. AiPlatformEnum,
  83. ImageHotWords,
  84. ImageModelVO,
  85. OtherPlatformEnum,
  86. TongYiWanXiangModels
  87. } from '@/views/ai/utils/constants'
  88. const message = useMessage() // 消息弹窗
  89. // 定义属性
  90. const drawIn = ref<boolean>(false) // 生成中
  91. const selectHotWord = ref<string>('') // 选中的热词
  92. // 表单
  93. const prompt = ref<string>('') // 提示词
  94. const width = ref<number>(512) // 图片宽度
  95. const height = ref<number>(512) // 图片高度
  96. const otherPlatform = ref<string>(AiPlatformEnum.TONG_YI) // 平台
  97. const models = ref<ImageModelVO[]>(TongYiWanXiangModels) // 模型
  98. const model = ref<string>(models.value[0].key) // 模型
  99. const emits = defineEmits(['onDrawStart', 'onDrawComplete']) // 定义 emits
  100. /** 选择热词 */
  101. const handleHotWordClick = async (hotWord: string) => {
  102. // 情况一:取消选中
  103. if (selectHotWord.value == hotWord) {
  104. selectHotWord.value = ''
  105. return
  106. }
  107. // 情况二:选中
  108. selectHotWord.value = hotWord // 选中
  109. prompt.value = hotWord // 替换提示词
  110. }
  111. /** 图片生成 */
  112. const handleGenerateImage = async () => {
  113. // 二次确认
  114. await message.confirm(`确认生成内容?`)
  115. try {
  116. // 加载中
  117. drawIn.value = true
  118. // 回调
  119. emits('onDrawStart', AiPlatformEnum.STABLE_DIFFUSION)
  120. // 发送请求
  121. const form = {
  122. platform: otherPlatform.value,
  123. model: model.value, // 模型
  124. prompt: prompt.value, // 提示词
  125. width: width.value, // 图片宽度
  126. height: height.value, // 图片高度
  127. options: {
  128. }
  129. } as ImageDrawReqVO
  130. await ImageApi.drawImage(form)
  131. } finally {
  132. // 回调
  133. emits('onDrawComplete', AiPlatformEnum.STABLE_DIFFUSION)
  134. // 加载结束
  135. drawIn.value = false
  136. }
  137. }
  138. /** 填充值 */
  139. const settingValues = async (detail: ImageVO) => {
  140. prompt.value = detail.prompt
  141. width.value = detail.width
  142. height.value = detail.height
  143. }
  144. /** 平台切换 */
  145. const handlerPlatformChange = async (platform) => {
  146. // 切换平台,切换模型、风格
  147. if (AiPlatformEnum.YI_YAN === platform) {
  148. models.value = TongYiWanXiangModels
  149. } else {
  150. models.value = []
  151. }
  152. // 切换平台,默认选择一个风格
  153. if (models.value.length > 0) {
  154. model.value = models.value[0].key
  155. } else {
  156. model.value = ''
  157. }
  158. }
  159. /** 暴露组件方法 */
  160. defineExpose({ settingValues })
  161. </script>
  162. <style scoped lang="scss">
  163. // 提示词
  164. .prompt {
  165. }
  166. // 热词
  167. .hot-words {
  168. display: flex;
  169. flex-direction: column;
  170. margin-top: 30px;
  171. .word-list {
  172. display: flex;
  173. flex-direction: row;
  174. flex-wrap: wrap;
  175. justify-content: start;
  176. margin-top: 15px;
  177. .btn {
  178. margin: 0;
  179. }
  180. }
  181. }
  182. // 模型
  183. .group-item {
  184. margin-top: 30px;
  185. .group-item-body {
  186. margin-top: 15px;
  187. width: 100%;
  188. }
  189. }
  190. .btns {
  191. display: flex;
  192. justify-content: center;
  193. margin-top: 50px;
  194. }
  195. </style>