refactor(web-antd): 修正 Tinyflow 组件中的导入路径

- 将 './ui/typing' 修改为 './ui/typeing'(可能是原代码中的拼写错误)
- 将 './ui/typing' 修改为 './ui/index',以符合常见的模块入口文件结构
This commit is contained in:
gjd
2025-06-16 13:16:07 +08:00
parent 0f701dd49b
commit 31a98ba9f8
27 changed files with 700 additions and 1592 deletions

View File

@@ -65,8 +65,12 @@ onMounted(async () => {
});
</script>
<template>
<Card body-class="" class="image-card">
<div class="image-operation">
<Card
body-class=""
class="relative flex h-auto w-[320px] flex-col rounded-[10px]"
>
<!-- 图片操作区 -->
<div class="flex flex-row justify-between">
<div>
<Button v-if="detail?.status === AiImageStatusEnum.IN_PROGRESS">
生成中
@@ -78,31 +82,30 @@ onMounted(async () => {
异常
</Button>
</div>
<!-- 操作区 -->
<div>
<div class="flex">
<Button
class="btn"
class="m-0 p-[10px]"
type="text"
@click="handleButtonClick('download', detail)"
>
<span class="icon-[ant-design--download-outlined]"></span>
</Button>
<Button
class="btn"
class="m-0 p-[10px]"
type="text"
@click="handleButtonClick('regeneration', detail)"
>
<span class="icon-[ant-design--redo-outlined]"></span>
</Button>
<Button
class="btn"
class="m-0 p-[10px]"
type="text"
@click="handleButtonClick('delete', detail)"
>
<span class="icon-[ant-design--delete-outlined]"></span>
</Button>
<Button
class="btn"
class="m-0 p-[10px]"
type="text"
@click="handleButtonClick('more', detail)"
>
@@ -110,14 +113,17 @@ onMounted(async () => {
</Button>
</div>
</div>
<div class="image-wrapper" ref="cardImageRef">
<Image class="image" :src="detail?.picUrl" />
<!-- 图片展示区域 -->
<div class="mt-[20px] h-[280px] flex-1 overflow-hidden" ref="cardImageRef">
<Image class="w-full rounded-[10px]" :src="detail?.picUrl" />
<div v-if="detail?.status === AiImageStatusEnum.FAIL">
{{ detail?.errorMessage }}
</div>
</div>
<!-- Midjourney 专属操作 -->
<div class="image-mj-btns">
<!-- Midjourney 专属操作按钮 -->
<div class="mt-[5px] flex w-full flex-wrap justify-start">
<Button
size="small"
v-for="(button, index) in detail?.buttons"
@@ -130,46 +136,3 @@ onMounted(async () => {
</div>
</Card>
</template>
<style scoped lang="scss">
.image-card {
position: relative;
display: flex;
flex-direction: column;
width: 320px;
height: auto;
border-radius: 10px;
.image-operation {
display: flex;
flex-direction: row;
justify-content: space-between;
.btn {
//border: 1px solid red;
padding: 10px;
margin: 0;
}
}
.image-wrapper {
flex: 1;
height: 280px;
margin-top: 20px;
overflow: hidden;
.image {
width: 100%;
border-radius: 10px;
}
}
.image-mj-btns {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
width: 100%;
margin-top: 5px;
}
}
</style>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import type { AiImageApi } from '#/api/ai/image';
import type { ImageModelVO } from '#/utils/constants';
import { ref, toRefs, watch } from 'vue';
@@ -43,15 +42,16 @@ watch(
</script>
<template>
<div class="item">
<div class="body">
<Image class="image" :src="detail?.picUrl" />
<div class="mb-5 w-full overflow-hidden break-words">
<div class="body mt-2 text-gray-600">
<Image class="rounded-[10px]" :src="detail?.picUrl" />
</div>
</div>
<!-- 时间 -->
<div class="item">
<div class="tip">时间</div>
<div class="body">
<div class="mb-5 w-full overflow-hidden break-words">
<div class="tip text-lg font-bold">时间</div>
<div class="body mt-2 text-gray-600">
<div>
提交时间{{ formatTime(detail.createTime, 'yyyy-MM-dd HH:mm:ss') }}
</div>
@@ -60,177 +60,150 @@ watch(
</div>
</div>
</div>
<!-- 模型 -->
<div class="item">
<div class="tip">模型</div>
<div class="body">
<div class="mb-5 w-full overflow-hidden break-words">
<div class="tip text-lg font-bold">模型</div>
<div class="body mt-2 text-gray-600">
{{ detail.model }}({{ detail.height }}x{{ detail.width }})
</div>
</div>
<!-- 提示词 -->
<div class="item">
<div class="tip">提示词</div>
<div class="body">
<div class="mb-5 w-full overflow-hidden break-words">
<div class="tip text-lg font-bold">提示词</div>
<div class="body mt-2 text-gray-600">
{{ detail.prompt }}
</div>
</div>
<!-- 地址 -->
<div class="item">
<div class="tip">图片地址</div>
<div class="body">
<!-- 图片地址 -->
<div class="mb-5 w-full overflow-hidden break-words">
<div class="tip text-lg font-bold">图片地址</div>
<div class="body mt-2 text-gray-600">
{{ detail.picUrl }}
</div>
</div>
<!-- StableDiffusion 专属区域 -->
<!-- StableDiffusion 专属 -->
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.STABLE_DIFFUSION &&
detail?.options?.sampler
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">采样方法</div>
<div class="body">
<div class="tip text-lg font-bold">采样方法</div>
<div class="body mt-2 text-gray-600">
{{
StableDiffusionSamplers.find(
(item: ImageModelVO) => item.key === detail?.options?.sampler,
(item) => item.key === detail?.options?.sampler,
)?.name
}}
</div>
</div>
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.STABLE_DIFFUSION &&
detail?.options?.clipGuidancePreset
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">CLIP</div>
<div class="body">
<div class="tip text-lg font-bold">CLIP</div>
<div class="body mt-2 text-gray-600">
{{
StableDiffusionClipGuidancePresets.find(
(item: ImageModelVO) =>
item.key === detail?.options?.clipGuidancePreset,
(item) => item.key === detail?.options?.clipGuidancePreset,
)?.name
}}
</div>
</div>
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.STABLE_DIFFUSION &&
detail?.options?.stylePreset
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">风格</div>
<div class="body">
<div class="tip text-lg font-bold">风格</div>
<div class="body mt-2 text-gray-600">
{{
StableDiffusionStylePresets.find(
(item: ImageModelVO) => item.key === detail?.options?.stylePreset,
(item) => item.key === detail?.options?.stylePreset,
)?.name
}}
</div>
</div>
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.STABLE_DIFFUSION &&
detail?.options?.steps
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">迭代步数</div>
<div class="body">
{{ detail?.options?.steps }}
</div>
<div class="tip text-lg font-bold">迭代步数</div>
<div class="body mt-2 text-gray-600">{{ detail?.options?.steps }}</div>
</div>
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.STABLE_DIFFUSION &&
detail?.options?.scale
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">引导系数</div>
<div class="body">
{{ detail?.options?.scale }}
</div>
<div class="tip text-lg font-bold">引导系数</div>
<div class="body mt-2 text-gray-600">{{ detail?.options?.scale }}</div>
</div>
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.STABLE_DIFFUSION &&
detail?.options?.seed
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">随机因子</div>
<div class="body">
{{ detail?.options?.seed }}
</div>
<div class="tip text-lg font-bold">随机因子</div>
<div class="body mt-2 text-gray-600">{{ detail?.options?.seed }}</div>
</div>
<!-- Dall3 专属区域 -->
<!-- Dall3 专属 -->
<div
class="item"
v-if="detail.platform === AiPlatformEnum.OPENAI && detail?.options?.style"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">风格选择</div>
<div class="body">
<div class="tip text-lg font-bold">风格选择</div>
<div class="body mt-2 text-gray-600">
{{
Dall3StyleList.find(
(item: ImageModelVO) => item.key === detail?.options?.style,
)?.name
Dall3StyleList.find((item) => item.key === detail?.options?.style)?.name
}}
</div>
</div>
<!-- Midjourney 专属区域 -->
<!-- Midjourney 专属 -->
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.MIDJOURNEY && detail?.options?.version
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">模型版本</div>
<div class="body">
{{ detail?.options?.version }}
</div>
<div class="tip text-lg font-bold">模型版本</div>
<div class="body mt-2 text-gray-600">{{ detail?.options?.version }}</div>
</div>
<div
class="item"
v-if="
detail.platform === AiPlatformEnum.MIDJOURNEY &&
detail?.options?.referImageUrl
"
class="mb-5 w-full overflow-hidden break-words"
>
<div class="tip">参考图</div>
<div class="body">
<div class="tip text-lg font-bold">参考图</div>
<div class="body mt-2 text-gray-600">
<Image :src="detail.options.referImageUrl" />
</div>
</div>
</template>
<style scoped lang="scss">
.item {
width: 100%;
margin-bottom: 20px;
overflow: hidden;
word-wrap: break-word;
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.tip {
font-size: 16px;
font-weight: bold;
}
.body {
margin-top: 10px;
color: #616161;
.taskImage {
border-radius: 10px;
}
}
}
</style>

View File

@@ -166,38 +166,46 @@ onUnmounted(async () => {
}
});
</script>
<template>
<Drawer class="w-[600px]">
<ImageDetail :id="showImageDetailId" />
</Drawer>
<Card
class="dr-task"
class="dr-task flex h-full w-full flex-col"
:body-style="{
margin: 0,
padding: 0,
height: '100%',
position: 'relative',
display: 'flex',
flexDirection: 'column',
}"
>
<template #title>
绘画任务
<!-- TODO @fan看看怎么优化下这个样子哈 -->
<Button @click="handleViewPublic">绘画作品</Button>
</template>
<div class="task-image-list" ref="imageListRef">
<div
class="task-image-list flex flex-1 flex-wrap content-start overflow-y-auto p-5 pb-[140px] pt-5"
ref="imageListRef"
>
<ImageCard
v-for="image in imageList"
:key="image.id"
:detail="image"
@on-btn-click="handleImageButtonClick"
@on-mj-btn-click="handleImageMidjourneyButtonClick"
class="mb-5 mr-5"
/>
</div>
<div class="task-image-pagination">
<div
class="task-image-pagination sticky bottom-0 z-50 flex h-[60px] items-center justify-center bg-white shadow-[0_-2px_8px_rgba(0,0,0,0.1)]"
>
<Pagination
:total="pageTotal"
:show-total="(total: number) => `${total}`"
:show-total="(total) => `${total}`"
show-quick-jumper
show-size-changer
v-model:current="queryParams.pageNo"
@@ -208,43 +216,3 @@ onUnmounted(async () => {
</div>
</Card>
</template>
<style lang="scss">
.dr-task {
width: 100%;
height: 100%;
}
.task-image-list {
position: relative;
box-sizing: border-box; /* 确保内边距不会增加高度 */
display: flex;
flex-flow: row wrap;
align-content: flex-start;
height: 100%;
padding: 20px 20px 140px;
overflow: auto;
> div {
margin-right: 20px;
margin-bottom: 20px;
}
> div:last-of-type {
//margin-bottom: 100px;
}
}
.task-image-pagination {
position: absolute;
bottom: 60px;
z-index: 999;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 100%;
height: 50px;
line-height: 90px;
background-color: #fff;
}
</style>

View File

@@ -117,19 +117,20 @@ defineExpose({ settingValues });
v-model:value="prompt"
:maxlength="1024"
:rows="5"
class="w-100% mt-[15px]"
class="mt-[15px] w-full"
placeholder="例如:童话里的小屋应该是什么样子?"
show-count
/>
</div>
<div class="hot-words">
<div class="hot-words mt-[30px] flex flex-col">
<div>
<b>随机热词</b>
</div>
<Space wrap class="word-list">
<Space wrap class="word-list mt-[15px] flex flex-wrap justify-start">
<Button
shape="round"
class="btn"
class="btn m-0"
:type="selectHotWord === hotWord ? 'primary' : 'default'"
v-for="hotWord in ImageHotWords"
:key="hotWord"
@@ -139,16 +140,17 @@ defineExpose({ settingValues });
</Button>
</Space>
</div>
<div class="group-item">
<div class="group-item mt-[30px]">
<div>
<b>平台</b>
</div>
<Space wrap class="group-item-body">
<Space wrap class="group-item-body mt-[15px] w-full">
<Select
v-model:value="otherPlatform"
placeholder="Select"
size="large"
class="!w-[330px]"
class="!important w-[330px]"
@change="handlerPlatformChange"
>
<Select.Option
@@ -161,16 +163,17 @@ defineExpose({ settingValues });
</Select>
</Space>
</div>
<div class="group-item">
<div class="group-item mt-[30px]">
<div>
<b>模型</b>
</div>
<Space wrap class="group-item-body">
<Space wrap class="group-item-body mt-[15px] w-full">
<Select
v-model:value="modelId"
placeholder="Select"
size="large"
class="!w-[330px]"
class="!important w-[330px]"
>
<Select.Option
v-for="item in platformModels"
@@ -182,11 +185,12 @@ defineExpose({ settingValues });
</Select>
</Space>
</div>
<div class="group-item">
<div class="group-item mt-[30px]">
<div>
<b>图片尺寸</b>
</div>
<Space wrap class="group-item-body">
<Space wrap class="group-item-body mt-[15px] flex flex-wrap gap-x-[20px]">
<InputNumber
v-model:value="width"
class="mt-[10px] w-[170px]"
@@ -199,7 +203,8 @@ defineExpose({ settingValues });
/>
</Space>
</div>
<div class="btns">
<div class="btns mt-[50px] flex justify-center">
<Button
type="primary"
size="large"
@@ -212,37 +217,3 @@ defineExpose({ settingValues });
</Button>
</div>
</template>
<style scoped lang="scss">
.hot-words {
display: flex;
flex-direction: column;
margin-top: 30px;
.word-list {
display: flex;
flex-flow: row wrap;
justify-content: start;
margin-top: 15px;
.btn {
margin: 0;
}
}
}
// 模型
.group-item {
margin-top: 30px;
.group-item-body {
width: 100%;
margin-top: 15px;
}
}
.btns {
display: flex;
justify-content: center;
margin-top: 50px;
}
</style>

View File

@@ -151,19 +151,18 @@ defineExpose({ settingValues });
v-model:value="prompt"
:maxlength="1024"
:rows="5"
class="w-100% mt-[15px]"
class="mt-[15px] w-full"
placeholder="例如:童话里的小屋应该是什么样子?"
show-count
/>
</div>
<div class="hot-words">
<div>
<b>随机热词</b>
</div>
<Space wrap class="word-list">
<div class="hot-words mt-[30px] flex flex-col">
<div><b>随机热词</b></div>
<Space wrap class="word-list mt-[15px] flex flex-wrap justify-start">
<Button
shape="round"
class="btn"
class="btn m-0"
:type="selectHotWord === hotWord ? 'primary' : 'default'"
v-for="hotWord in ImageHotWords"
:key="hotWord"
@@ -173,15 +172,17 @@ defineExpose({ settingValues });
</Button>
</Space>
</div>
<div class="model">
<div>
<b>模型选择</b>
</div>
<Space wrap class="model-list">
<div class="model mt-[30px]">
<div><b>模型选择</b></div>
<Space wrap class="model-list mt-[15px] flex flex-wrap gap-[10px]">
<div
:class="
selectModel === model.key ? 'modal-item selectModel' : 'modal-item'
"
class="modal-item flex w-[110px] cursor-pointer flex-col items-center overflow-hidden rounded-[5px] border-[3px]"
:class="[
selectModel === model.key
? 'border-[#1293ff!important]'
: 'border-transparent',
]"
v-for="model in Dall3Models"
:key="model.key"
>
@@ -191,21 +192,21 @@ defineExpose({ settingValues });
fit="contain"
@click="handleModelClick(model)"
/>
<div class="model-font">{{ model.name }}</div>
<div class="model-font text-[14px] font-bold text-[#3e3e3e]">
{{ model.name }}
</div>
</div>
</Space>
</div>
<div class="image-style">
<div>
<b>风格选择</b>
</div>
<Space wrap class="image-style-list">
<div class="image-style mt-[30px]">
<div><b>风格选择</b></div>
<Space wrap class="image-style-list mt-[15px] flex flex-wrap gap-[10px]">
<div
:class="
style === imageStyle.key
? 'image-style-item selectImageStyle'
: 'image-style-item'
"
class="image-style-item flex w-[110px] cursor-pointer flex-col items-center overflow-hidden rounded-[5px] border-[3px]"
:class="[
style === imageStyle.key ? 'border-[#1293ff]' : 'border-transparent',
]"
v-for="imageStyle in Dall3StyleList"
:key="imageStyle.key"
>
@@ -215,35 +216,41 @@ defineExpose({ settingValues });
fit="contain"
@click="handleStyleClick(imageStyle)"
/>
<div class="style-font">{{ imageStyle.name }}</div>
<div class="style-font text-[14px] font-bold text-[#3e3e3e]">
{{ imageStyle.name }}
</div>
</div>
</Space>
</div>
<div class="image-size">
<div>
<b>画面比例</b>
</div>
<Space wrap class="size-list">
<div class="image-size mt-[30px] w-full">
<div><b>画面比例</b></div>
<Space
wrap
class="size-list mt-[20px] flex w-full flex-row justify-between"
>
<div
class="size-item"
class="size-item flex cursor-pointer flex-col items-center"
v-for="imageSize in Dall3SizeList"
:key="imageSize.key"
@click="handleSizeClick(imageSize)"
>
<div
:class="
selectSize === imageSize.key
? 'size-wrapper selectImageSize'
: 'size-wrapper'
"
class="size-wrapper flex h-[50px] w-[50px] flex-col items-center justify-center rounded-[7px] border bg-white p-[4px]"
:class="[
selectSize === imageSize.key ? 'border-[#1293ff]' : 'border-white',
]"
>
<div :style="imageSize.style"></div>
</div>
<div class="size-font">{{ imageSize.name }}</div>
<div class="size-font text-[14px] font-bold text-[#3e3e3e]">
{{ imageSize.name }}
</div>
</div>
</Space>
</div>
<div class="btns">
<div class="btns mt-[50px] flex justify-center">
<Button
type="primary"
size="large"
@@ -256,134 +263,3 @@ defineExpose({ settingValues });
</Button>
</div>
</template>
<style scoped lang="scss">
// 热词
.hot-words {
display: flex;
flex-direction: column;
margin-top: 30px;
.word-list {
display: flex;
flex-flow: row wrap;
justify-content: start;
margin-top: 15px;
.btn {
margin: 0;
}
}
}
// 模型
.model {
margin-top: 30px;
.model-list {
margin-top: 15px;
.modal-item {
display: flex;
flex-direction: column;
align-items: center;
width: 110px;
//outline: 1px solid blue;
overflow: hidden;
cursor: pointer;
border: 3px solid transparent;
.model-font {
font-size: 14px;
font-weight: bold;
color: #3e3e3e;
}
}
.selectModel {
border: 3px solid #1293ff;
border-radius: 5px;
}
}
}
// 样式 style
.image-style {
margin-top: 30px;
.image-style-list {
margin-top: 15px;
.image-style-item {
display: flex;
flex-direction: column;
align-items: center;
width: 110px;
//outline: 1px solid blue;
overflow: hidden;
cursor: pointer;
border: 3px solid transparent;
.style-font {
font-size: 14px;
font-weight: bold;
color: #3e3e3e;
}
}
.selectImageStyle {
border: 3px solid #1293ff;
border-radius: 5px;
}
}
}
// 尺寸
.image-size {
width: 100%;
margin-top: 30px;
.size-list {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
margin-top: 20px;
.size-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
.size-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
padding: 4px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 7px;
}
.size-font {
font-size: 14px;
font-weight: bold;
color: #3e3e3e;
}
}
}
.selectImageSize {
border: 1px solid #1293ff !important;
}
}
.btns {
display: flex;
justify-content: center;
margin-top: 50px;
}
</style>

View File

@@ -150,19 +150,18 @@ defineExpose({ settingValues });
v-model:value="prompt"
:maxlength="1024"
:rows="5"
class="w-100% mt-[15px]"
class="mt-[15px] w-full"
placeholder="例如:童话里的小屋应该是什么样子?"
show-count
/>
</div>
<div class="hot-words">
<div>
<b>随机热词</b>
</div>
<Space wrap class="word-list">
<div class="mt-8 flex flex-col">
<div><b>随机热词</b></div>
<Space wrap class="mt-4 flex flex-wrap gap-2">
<Button
shape="round"
class="btn"
class="m-0"
:type="selectHotWord === hotWord ? 'primary' : 'default'"
v-for="hotWord in ImageHotWords"
:key="hotWord"
@@ -172,41 +171,41 @@ defineExpose({ settingValues });
</Button>
</Space>
</div>
<div class="image-size">
<div>
<b>尺寸</b>
</div>
<Space wrap class="size-list">
<div class="mt-8 w-full">
<div><b>尺寸</b></div>
<Space wrap class="mt-5 flex w-full flex-row justify-between">
<div
class="size-item"
class="flex cursor-pointer flex-col items-center"
v-for="imageSize in MidjourneySizeList"
:key="imageSize.key"
@click="handleSizeClick(imageSize)"
>
<div
:class="
selectSize === imageSize.key
? 'size-wrapper selectImageSize'
: 'size-wrapper'
"
class="flex h-[50px] w-[50px] items-center justify-center rounded-[7px] border bg-white p-1"
:class="[
selectSize === imageSize.key ? 'border-[#1293ff]' : 'border-white',
]"
>
<div :style="imageSize.style"></div>
</div>
<div class="size-font">{{ imageSize.key }}</div>
<div class="text-sm font-bold text-[#3e3e3e]">{{ imageSize.key }}</div>
</div>
</Space>
</div>
<div class="model">
<div>
<b>模型</b>
</div>
<Space wrap class="model-list">
<div class="mt-8">
<div><b>模型</b></div>
<Space wrap class="mt-4 flex flex-wrap gap-4">
<div
:class="
selectModel === model.key ? 'modal-item selectModel' : 'modal-item'
"
v-for="model in MidjourneyModels"
:key="model.key"
class="flex w-[150px] cursor-pointer flex-col items-center overflow-hidden border-[3px]"
:class="[
selectModel === model.key
? 'rounded border-[#1293ff]'
: 'border-transparent',
]"
>
<Image
:preview="false"
@@ -214,18 +213,17 @@ defineExpose({ settingValues });
fit="contain"
@click="handleModelClick(model)"
/>
<div class="model-font">{{ model.name }}</div>
<div class="text-sm font-bold text-[#3e3e3e]">{{ model.name }}</div>
</div>
</Space>
</div>
<div class="version">
<div>
<b>版本</b>
</div>
<Space wrap class="version-list">
<div class="mt-5">
<div><b>版本</b></div>
<Space wrap class="mt-5 w-full">
<Select
v-model:value="selectVersion"
class="version-select !w-[330px]"
class="!w-[330px]"
clearable
placeholder="请选择版本"
>
@@ -239,15 +237,15 @@ defineExpose({ settingValues });
</Select>
</Space>
</div>
<div class="model">
<div>
<b>参考图</b>
</div>
<Space wrap class="model-list">
<div class="mt-8">
<div><b>参考图</b></div>
<Space wrap class="mt-4">
<ImageUpload v-model:value="referImageUrl" :show-description="false" />
</Space>
</div>
<div class="btns">
<div class="mt-[50px] flex justify-center">
<Button
type="primary"
size="large"
@@ -259,113 +257,3 @@ defineExpose({ settingValues });
</Button>
</div>
</template>
<style scoped lang="scss">
// 热词
.hot-words {
display: flex;
flex-direction: column;
margin-top: 30px;
.word-list {
display: flex;
flex-flow: row wrap;
justify-content: start;
margin-top: 15px;
.btn {
margin: 0;
}
}
}
// version
.version {
margin-top: 20px;
.version-list {
width: 100%;
margin-top: 20px;
}
}
// 模型
.model {
margin-top: 30px;
.model-list {
margin-top: 15px;
.modal-item {
display: flex;
flex-direction: column;
align-items: center;
width: 150px;
//outline: 1px solid blue;
overflow: hidden;
cursor: pointer;
border: 3px solid transparent;
.model-font {
font-size: 14px;
font-weight: bold;
color: #3e3e3e;
}
}
.selectModel {
border: 3px solid #1293ff;
border-radius: 5px;
}
}
}
// 尺寸
.image-size {
width: 100%;
margin-top: 30px;
.size-list {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
margin-top: 20px;
.size-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
.size-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
padding: 4px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 7px;
}
.size-font {
font-size: 14px;
font-weight: bold;
color: #3e3e3e;
}
}
}
.selectImageSize {
border: 1px solid #1293ff !important;
}
}
.btns {
display: flex;
justify-content: center;
margin-top: 50px;
}
</style>

View File

@@ -9,7 +9,6 @@ import { alert, confirm } from '@vben/common-ui';
import {
Button,
Input,
InputNumber,
message,
Select,
@@ -139,19 +138,19 @@ defineExpose({ settingValues });
v-model:value="prompt"
:maxlength="1024"
:rows="5"
class="w-100% mt-[15px]"
class="mt-[15px] w-full"
placeholder="例如:童话里的小屋应该是什么样子?"
show-count
/>
</div>
<div class="hot-words">
<div>
<b>随机热词</b>
</div>
<Space wrap class="word-list">
<!-- 热词区域 -->
<div class="mt-[30px] flex flex-col">
<div><b>随机热词</b></div>
<Space wrap class="mt-[15px] flex flex-wrap justify-start">
<Button
shape="round"
class="btn"
class="m-0"
:type="selectHotWord === hotWord ? 'primary' : 'default'"
v-for="hotWord in ImageHotEnglishWords"
:key="hotWord"
@@ -161,11 +160,11 @@ defineExpose({ settingValues });
</Button>
</Space>
</div>
<div class="group-item">
<div>
<b>采样方法</b>
</div>
<Space wrap class="group-item-body">
<!-- 参数项采样方法 -->
<div class="mt-[30px]">
<div><b>采样方法</b></div>
<Space wrap class="mt-[15px] w-full">
<Select
v-model:value="sampler"
placeholder="Select"
@@ -182,11 +181,11 @@ defineExpose({ settingValues });
</Select>
</Space>
</div>
<div class="group-item">
<div>
<b>CLIP</b>
</div>
<Space wrap class="group-item-body">
<!-- CLIP -->
<div class="mt-[30px]">
<div><b>CLIP</b></div>
<Space wrap class="mt-[15px] w-full">
<Select
v-model:value="clipGuidancePreset"
placeholder="Select"
@@ -203,11 +202,11 @@ defineExpose({ settingValues });
</Select>
</Space>
</div>
<div class="group-item">
<div>
<b>风格</b>
</div>
<Space wrap class="group-item-body">
<!-- 风格 -->
<div class="mt-[30px]">
<div><b>风格</b></div>
<Space wrap class="mt-[15px] w-full">
<Select
v-model:value="stylePreset"
placeholder="Select"
@@ -225,35 +224,43 @@ defineExpose({ settingValues });
</Select>
</Space>
</div>
<div class="group-item">
<div>
<b>图片尺寸</b>
</div>
<Space wrap class="group-item-body">
<Input v-model="width" class="w-[170px]" placeholder="图片宽度" />
<Input v-model="height" class="w-[170px]" placeholder="图片高度" />
<!-- 图片尺寸 -->
<div class="mt-[30px]">
<div><b>图片尺寸</b></div>
<Space wrap class="mt-[15px] w-full">
<InputNumber
v-model:value="width"
class="w-[170px]"
placeholder="图片宽度"
/>
<InputNumber
v-model:value="height"
class="w-[170px]"
placeholder="图片高度"
/>
</Space>
</div>
<div class="group-item">
<div>
<b>迭代步数</b>
</div>
<Space wrap class="group-item-body">
<!-- 迭代步数 -->
<div class="mt-[30px]">
<div><b>迭代步数</b></div>
<Space wrap class="mt-[15px] w-full">
<InputNumber
v-model="steps"
v-model:value="steps"
size="large"
class="!w-[330px]"
placeholder="Please input"
/>
</Space>
</div>
<div class="group-item">
<div>
<b>引导系数</b>
</div>
<Space wrap class="group-item-body">
<!-- 引导系数 -->
<div class="mt-[30px]">
<div><b>引导系数</b></div>
<Space wrap class="mt-[15px] w-full">
<InputNumber
v-model="scale"
v-model:value="scale"
type="number"
size="large"
class="!w-[330px]"
@@ -261,11 +268,11 @@ defineExpose({ settingValues });
/>
</Space>
</div>
<div class="group-item">
<div>
<b>随机因子</b>
</div>
<Space wrap class="group-item-body">
<!-- 随机因子 -->
<div class="mt-[30px]">
<div><b>随机因子</b></div>
<Space wrap class="mt-[15px] w-full">
<InputNumber
v-model:value="seed"
size="large"
@@ -274,7 +281,9 @@ defineExpose({ settingValues });
/>
</Space>
</div>
<div class="btns">
<!-- 生成按钮 -->
<div class="mt-[50px] flex justify-center">
<Button
type="primary"
size="large"
@@ -287,38 +296,3 @@ defineExpose({ settingValues });
</Button>
</div>
</template>
<style scoped lang="scss">
// 热词
.hot-words {
display: flex;
flex-direction: column;
margin-top: 30px;
.word-list {
display: flex;
flex-flow: row wrap;
justify-content: start;
margin-top: 15px;
.btn {
margin: 0;
}
}
}
// 模型
.group-item {
margin-top: 30px;
.group-item-body {
width: 100%;
margin-top: 15px;
}
}
.btns {
display: flex;
justify-content: center;
margin-top: 50px;
}
</style>

View File

@@ -90,15 +90,16 @@ onMounted(async () => {
<template>
<Page auto-content-height>
<div class="ai-image">
<div class="left">
<div class="ai-image absolute inset-0 flex h-full w-full flex-row">
<div class="left flex w-[390px] flex-col p-5">
<div class="segmented flex justify-center">
<Segmented
v-model:value="selectPlatform"
:options="platformOptions"
class="bg-[#ececec]"
/>
</div>
<div class="modal-switch-container">
<div class="modal-switch-container mt-[30px] h-full overflow-y-auto">
<Common
v-if="selectPlatform === 'common'"
ref="commonRef"
@@ -125,47 +126,9 @@ onMounted(async () => {
/>
</div>
</div>
<div class="main">
<div class="main flex-1 bg-white">
<ImageList ref="imageListRef" @on-regeneration="handleRegeneration" />
</div>
</div>
</Page>
</template>
<style scoped lang="scss">
.ai-image {
position: absolute;
inset: 0;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
.left {
display: flex;
flex-direction: column;
width: 390px;
padding: 20px;
.segmented .ant-segmented {
background-color: #ececec;
}
.modal-switch-container {
height: 100%;
margin-top: 30px;
overflow-y: auto;
}
}
.main {
flex: 1;
background-color: #fff;
}
.right {
width: 350px;
background-color: #f7f8fa;
}
}
</style>

View File

@@ -45,72 +45,44 @@ onMounted(async () => {
</script>
<template>
<Page auto-content-height>
<div class="square-container">
<!-- TODO @fanstyle 建议换成 unocss -->
<div class="bg-[#fff] p-[20px]">
<!-- TODO @fanSearch 可以换成 Icon 组件么 -->
<Input.Search
v-model="queryParams.prompt"
style="width: 100%; margin-bottom: 20px"
class="mb-[20px] w-full"
size="large"
placeholder="请输入要搜索的内容"
@keyup.enter="handleQuery"
/>
<div class="gallery">
<div
class="grid gap-[10px] bg-[#fff] shadow-[0_0_10px_rgba(0,0,0,0.1)]"
style="grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))"
>
<!-- TODO @fan这个图片的风格要不和 ImageCard.vue 界面一致只有卡片没有操作因为看着更有相框的感觉~~~ -->
<div v-for="item in list" :key="item.id" class="gallery-item">
<img :src="item.picUrl" class="img" />
<div
v-for="item in list"
:key="item.id"
class="relative cursor-pointer overflow-hidden bg-[#f0f0f0] transition-transform duration-300 hover:scale-[1.05]"
>
<img
:src="item.picUrl"
class="block h-auto w-full transition-transform duration-300 hover:scale-[1.1]"
/>
</div>
</div>
<!-- TODO @fan缺少翻页 -->
<!-- 分页 -->
<Pagination
:total="total"
:show-total="(total: number) => `${total}`"
:show-total="(total) => `${total}`"
show-quick-jumper
show-size-changer
v-model:current="queryParams.pageNo"
v-model:page-size="queryParams.pageSize"
@change="debounceGetList"
@show-size-change="debounceGetList"
class="mt-[20px]"
/>
</div>
</Page>
</template>
<style scoped lang="scss">
.square-container {
padding: 20px;
background-color: #fff;
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 10px;
//max-width: 1000px;
background-color: #fff;
box-shadow: 0 0 10px rgb(0 0 0 / 10%);
}
.gallery-item {
position: relative;
overflow: hidden;
cursor: pointer;
background: #f0f0f0;
transition: transform 0.3s;
}
.gallery-item img {
display: block;
width: 100%;
height: auto;
transition: transform 0.3s;
}
.gallery-item:hover img {
transform: scale(1.1);
}
.gallery-item:hover {
transform: scale(1.05);
}
}
</style>