feat:【antd】【ai】image 的代码优化

pull/264/head^2
YunaiV 2025-11-15 13:50:48 +08:00
parent 51fb4b479e
commit 7c7a843e94
8 changed files with 31 additions and 50 deletions

View File

@ -11,11 +11,11 @@ import { Segmented } from 'ant-design-vue';
import { getModelSimpleList } from '#/api/ai/model/model';
import Common from './components/common/index.vue';
import Dall3 from './components/dall3/index.vue';
import ImageList from './components/ImageList.vue';
import Midjourney from './components/midjourney/index.vue';
import StableDiffusion from './components/stableDiffusion/index.vue';
import Common from './modules/common/index.vue';
import Dall3 from './modules/dall3/index.vue';
import ImageList from './modules/list.vue';
import Midjourney from './modules/midjourney/index.vue';
import StableDiffusion from './modules/stable-diffusion/index.vue';
const imageListRef = ref<any>(); // image 列表 ref
const dall3Ref = ref<any>(); // dall3(openai) ref
@ -23,7 +23,6 @@ const midjourneyRef = ref<any>(); // midjourney ref
const stableDiffusionRef = ref<any>(); // stable diffusion ref
const commonRef = ref<any>(); // stable diffusion ref
// 定义属性
const selectPlatform = ref('common'); // 选中的平台
const platformOptions = [
{
@ -43,7 +42,6 @@ const platformOptions = [
value: AiPlatformEnum.STABLE_DIFFUSION,
},
];
const models = ref<AiModelModelApi.Model[]>([]); // 模型列表
/** 绘画 start */

View File

@ -11,8 +11,6 @@ import { IconifyIcon } from '@vben/icons';
import { Button, Card, Image, message } from 'ant-design-vue';
// 消息
const props = defineProps({
detail: {
type: Object as PropType<AiImageApi.Image>,
@ -32,7 +30,6 @@ async function handleButtonClick(type: string, detail: AiImageApi.Image) {
async function handleMidjourneyBtnClick(
button: AiImageApi.ImageMidjourneyButtons,
) {
// 确认窗体
await confirm(`确认操作 "${button.label} ${button.emoji}" ?`);
emits('onMjBtnClick', button, props.detail);
}
@ -43,6 +40,7 @@ watch(detail, async (newVal) => {
await handleLoading(newVal.status);
});
const loading = ref();
/** 处理加载状态 */
async function handleLoading(status: number) {
// 情况一:如果是生成中,则设置加载中的 loading
@ -50,10 +48,11 @@ async function handleLoading(status: number) {
loading.value = message.loading({
content: `生成中...`,
});
// 情况二:如果已经生成结束,则移除 loading
} else {
if (loading.value) setTimeout(loading.value, 100);
// 情况二:如果已经生成结束,则移除 loading
if (loading.value) {
setTimeout(loading.value, 100);
}
}
}

View File

@ -16,21 +16,17 @@ import { Button, InputNumber, Select, Space, Textarea } from 'ant-design-vue';
import { drawImage } from '#/api/ai/image';
// 消息弹窗
// 接收父组件传入的模型列表
const props = defineProps({
models: {
type: Array<AiModelModelApi.Model>,
default: () => [] as AiModelModelApi.Model[],
},
});
}); // 接收父组件传入的模型列表
const emits = defineEmits(['onDrawStart', 'onDrawComplete']);
// 定义属性
const drawIn = ref<boolean>(false); // 生成中
const selectHotWord = ref<string>(''); // 选中的热词
// 表单
const prompt = ref<string>(''); // 提示词
const width = ref<number>(512); // 图片宽度
const height = ref<number>(512); // 图片高度
@ -45,7 +41,6 @@ async function handleHotWordClick(hotWord: string) {
selectHotWord.value = '';
return;
}
// 情况二:选中
selectHotWord.value = hotWord; // 选中
prompt.value = hotWord; // 替换提示词
@ -91,11 +86,11 @@ async function handlerPlatformChange(platform: any) {
platformModels.value = props.models.filter(
(item: AiModelModelApi.Model) => item.platform === platform,
);
// 切换平台,默认选择一个模型
modelId.value =
platformModels.value.length > 0 && platformModels.value[0]
? platformModels.value[0].id
: undefined;
// 切换平台,默认选择一个模型
}
/** 监听 models 变化 */

View File

@ -20,16 +20,14 @@ import { Button, Image, message, Space, Textarea } from 'ant-design-vue';
import { drawImage } from '#/api/ai/image';
// 接收父组件传入的模型列表
const props = defineProps({
models: {
type: Array<AiModelModelApi.Model>,
default: () => [] as AiModelModelApi.Model[],
},
});
}); // 接收父组件传入的模型列表
const emits = defineEmits(['onDrawStart', 'onDrawComplete']);
// 定义属性
const prompt = ref<string>(''); // 提示词
const drawIn = ref<boolean>(false); // 生成中
const selectHotWord = ref<string>(''); // 选中的热词
@ -44,7 +42,6 @@ async function handleHotWordClick(hotWord: string) {
selectHotWord.value = '';
return;
}
// 情况二:选中
selectHotWord.value = hotWord;
prompt.value = hotWord;

View File

@ -16,16 +16,16 @@ import { Image } from 'ant-design-vue';
import { getImageMy } from '#/api/ai/image';
// 图片详细信息
const props = defineProps({
id: {
type: Number,
required: true,
},
});
const detail = ref<AiImageApi.Image>({} as AiImageApi.Image);
/** 获取图片详情 */
const detail = ref<AiImageApi.Image>({} as AiImageApi.Image); // 图片详细信息
/** 获取图片详情 */
async function getImageDetail(id: number) {
detail.value = await getImageMy(id);
}

View File

@ -18,10 +18,8 @@ import {
midjourneyAction,
} from '#/api/ai/image';
import ImageCard from './ImageCard.vue';
import ImageDetail from './ImageDetail.vue';
// 暴露组件方法
import ImageCard from './card.vue';
import ImageDetail from './detail.vue';
const emits = defineEmits(['onRegeneration']);
const router = useRouter();
@ -29,15 +27,14 @@ const [Drawer, drawerApi] = useVbenDrawer({
title: '图片详情',
footer: false,
});
// 图片分页相关的参数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
});
}); // 图片分页相关的参数
const pageTotal = ref<number>(0); // page size
const imageList = ref<AiImageApi.Image[]>([]); // image 列表
const imageListRef = ref<any>(); // ref
// 图片轮询相关的参数(正在生成中的)
const inProgressImageMap = ref<{}>({}); // 监听的 image 映射,一般是生成中(需要轮询),key 为 image 编号,value 为 image
const inProgressTimer = ref<any>(); // 生成中的 image 定时器,轮询生成进展
const showImageDetailId = ref<number>(0); // 图片详情的图片编号
@ -60,7 +57,6 @@ async function getImageList() {
});
try {
// 1. 加载图片列表
const { list, total } = await getImagePageMy(queryParams);
imageList.value = list;
pageTotal.value = total;
@ -78,6 +74,7 @@ async function getImageList() {
loading();
}
}
const debounceGetImageList = useDebounceFn(getImageList, 80);
/** 轮询生成中的 image 列表 */
async function refreshWatchImages() {
@ -132,7 +129,7 @@ async function handleImageButtonClick(
}
// 重新生成
if (type === 'regeneration') {
await emits('onRegeneration', imageDetail);
emits('onRegeneration', imageDetail);
}
}
@ -152,7 +149,9 @@ async function handleImageMidjourneyButtonClick(
await getImageList();
}
defineExpose({ getImageList }); /** 组件挂在的时候 */
defineExpose({ getImageList });
/** 组件挂在的时候 */
onMounted(async () => {
// 获取 image 列表
await getImageList();
@ -189,6 +188,7 @@ onUnmounted(async () => {
<Button @click="handleViewPublic">绘画作品</Button>
</template>
<!-- TODO @AI:一行应该有 3 个,目前只有两个。 -->
<div
class="flex flex-1 flex-wrap content-start overflow-y-auto p-5 pb-28 pt-5"
ref="imageListRef"

View File

@ -29,21 +29,17 @@ import {
import { midjourneyImagine } from '#/api/ai/image';
import { ImageUpload } from '#/components/upload';
// 消息弹窗
// 接收父组件传入的模型列表
const props = defineProps({
models: {
type: Array<AiModelModelApi.Model>,
default: () => [] as AiModelModelApi.Model[],
},
});
}); // 接收父组件传入的模型列表
const emits = defineEmits(['onDrawStart', 'onDrawComplete']);
// 定义属性
const drawIn = ref<boolean>(false); // 生成中
const selectHotWord = ref<string>(''); // 选中的热词
// 表单
const prompt = ref<string>(''); // 提示词
const referImageUrl = ref<any>(); // 参考图
const selectModel = ref<string>('midjourney'); // 选中的模型
@ -58,7 +54,6 @@ async function handleHotWordClick(hotWord: string) {
selectHotWord.value = '';
return;
}
// 情况二:选中
selectHotWord.value = hotWord; // 选中
prompt.value = hotWord; // 设置提示次

View File

@ -25,14 +25,12 @@ import {
import { drawImage } from '#/api/ai/image';
// 接收父组件传入的模型列表
const props = defineProps({
models: {
type: Array<AiModelModelApi.Model>,
default: () => [] as AiModelModelApi.Model[],
},
});
}); // 接收父组件传入的模型列表
const emits = defineEmits(['onDrawStart', 'onDrawComplete']);
function hasChinese(str: string) {
@ -60,7 +58,6 @@ async function handleHotWordClick(hotWord: string) {
selectHotWord.value = '';
return;
}
// 情况二:选中
selectHotWord.value = hotWord; // 选中
prompt.value = hotWord; // 替换提示词
@ -82,7 +79,7 @@ async function handleGenerateImage() {
// 二次确认
if (hasChinese(prompt.value)) {
alert('暂不支持中文!');
await alert('暂不支持中文!');
return;
}
await confirm(`确认生成内容?`);