index.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. QianFanModels,
  87. TongYiWanXiangModels
  88. } from '@/views/ai/utils/constants'
  89. const message = useMessage() // 消息弹窗
  90. // 定义属性
  91. const drawIn = ref<boolean>(false) // 生成中
  92. const selectHotWord = ref<string>('') // 选中的热词
  93. // 表单
  94. const prompt = ref<string>('') // 提示词
  95. const width = ref<number>(512) // 图片宽度
  96. const height = ref<number>(512) // 图片高度
  97. const otherPlatform = ref<string>(AiPlatformEnum.TONG_YI) // 平台
  98. const models = ref<ImageModelVO[]>(TongYiWanXiangModels) // 模型 TongYiWanXiangModels、QianFanModels
  99. const model = ref<string>(models.value[0].key) // 模型
  100. const emits = defineEmits(['onDrawStart', 'onDrawComplete']) // 定义 emits
  101. /** 选择热词 */
  102. const handleHotWordClick = async (hotWord: string) => {
  103. // 情况一:取消选中
  104. if (selectHotWord.value == hotWord) {
  105. selectHotWord.value = ''
  106. return
  107. }
  108. // 情况二:选中
  109. selectHotWord.value = hotWord // 选中
  110. prompt.value = hotWord // 替换提示词
  111. }
  112. /** 图片生成 */
  113. const handleGenerateImage = async () => {
  114. // 二次确认
  115. await message.confirm(`确认生成内容?`)
  116. try {
  117. // 加载中
  118. drawIn.value = true
  119. // 回调
  120. emits('onDrawStart', AiPlatformEnum.STABLE_DIFFUSION)
  121. // 发送请求
  122. const form = {
  123. platform: otherPlatform.value,
  124. model: model.value, // 模型
  125. prompt: prompt.value, // 提示词
  126. width: width.value, // 图片宽度
  127. height: height.value, // 图片高度
  128. options: {
  129. }
  130. } as ImageDrawReqVO
  131. await ImageApi.drawImage(form)
  132. } finally {
  133. // 回调
  134. emits('onDrawComplete', AiPlatformEnum.STABLE_DIFFUSION)
  135. // 加载结束
  136. drawIn.value = false
  137. }
  138. }
  139. /** 填充值 */
  140. const settingValues = async (detail: ImageVO) => {
  141. prompt.value = detail.prompt
  142. width.value = detail.width
  143. height.value = detail.height
  144. }
  145. /** 平台切换 */
  146. const handlerPlatformChange = async (platform) => {
  147. // 切换平台,切换模型、风格
  148. if (AiPlatformEnum.TONG_YI === platform) {
  149. models.value = TongYiWanXiangModels
  150. } else if (AiPlatformEnum.YI_YAN === platform) {
  151. models.value = QianFanModels
  152. } else {
  153. models.value = []
  154. }
  155. // 切换平台,默认选择一个风格
  156. if (models.value.length > 0) {
  157. model.value = models.value[0].key
  158. } else {
  159. model.value = ''
  160. }
  161. }
  162. /** 暴露组件方法 */
  163. defineExpose({ settingValues })
  164. </script>
  165. <style scoped lang="scss">
  166. // 提示词
  167. .prompt {
  168. }
  169. // 热词
  170. .hot-words {
  171. display: flex;
  172. flex-direction: column;
  173. margin-top: 30px;
  174. .word-list {
  175. display: flex;
  176. flex-direction: row;
  177. flex-wrap: wrap;
  178. justify-content: start;
  179. margin-top: 15px;
  180. .btn {
  181. margin: 0;
  182. }
  183. }
  184. }
  185. // 模型
  186. .group-item {
  187. margin-top: 30px;
  188. .group-item-body {
  189. margin-top: 15px;
  190. width: 100%;
  191. }
  192. }
  193. .btns {
  194. display: flex;
  195. justify-content: center;
  196. margin-top: 50px;
  197. }
  198. </style>