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