Commit da11b384 by haojie

1

parent cdad148a
<svg width="11" height="8" viewBox="0 0 11 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.58333 0L5.46921 4.293L1.35508 0L0 1.414L5.46921 7.121L10.9384 1.414L9.58333 0Z" fill="#00DDDD"/>
</svg>
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.1567 24.8875C16.3149 25.9593 13.9912 25.8461 11.4194 24.5064C9.13124 23.4693 7.5726 21.5405 7.50715 21.4593L7.25215 21.1395L10.3108 19.3914C10.3676 19.3669 10.422 19.337 10.4731 19.302C10.3925 19.2431 10.305 19.1944 10.2126 19.1568C6.48442 17.0343 2.00283 14.4966 1.54124 14.2777C1.50606 14.2585 1.46731 14.2466 1.42737 14.243C1.40351 14.2695 1.36464 14.4216 1.36328 14.5382V24.5636C1.36328 24.6584 1.37964 24.6905 1.37964 24.6918C1.36942 24.657 1.41919 24.6414 1.44305 24.6305L4.51396 22.8809L4.69328 23.1605C4.70419 23.1761 5.80192 24.8541 8.93214 26.8184C10.786 27.9836 13.1049 28.6239 15.4612 28.6239C17.3799 28.6239 19.2371 28.1834 20.8306 27.3495C24.1149 25.6314 26.4167 22.6436 27.0787 21.7177L24.6071 20.0425C23.1685 22.3375 21.151 24.1348 19.1567 24.8875ZM28.619 5.305C28.6251 5.33909 28.5678 5.36023 28.5596 5.36432L25.4853 7.11591L25.3053 6.83568C25.2951 6.81932 24.2001 5.14477 21.0658 3.17705C19.2119 2.01523 16.8951 1.375 14.5415 1.375C12.6228 1.375 10.7656 1.81545 9.17215 2.64932C5.88715 4.3675 3.58601 7.35523 2.92396 8.28114L5.39078 9.94886C6.83078 7.65386 8.8476 5.85659 10.8426 5.10523C13.6837 4.03341 16.0081 4.14591 18.5792 5.485C20.8674 6.52205 22.4274 8.45091 22.4915 8.53273L22.7465 8.85182L19.6878 10.5993C19.6304 10.6249 19.5756 10.656 19.5242 10.692C19.5678 10.7268 19.6469 10.778 19.7867 10.8393C22.7942 12.5507 27.9631 15.4825 28.4574 15.717C28.4928 15.7365 28.5317 15.7485 28.5719 15.7525L28.5726 16.0948L28.5753 15.7525C28.5992 15.7239 28.6367 15.5609 28.6367 15.4593V5.4325C28.636 5.33773 28.6196 5.305 28.619 5.305Z" fill="#888FA1"/>
</svg>
<template>
<div ref="DragBox" :class="[DefaultClassName, 'drag']">
<img class="show-img" @dragstart.prevent :src="img" />
</div>
<CustomContextMenu :el="DragBox" @change="MenuChange"></CustomContextMenu>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import CustomContextMenu from '@/components/custom/ContextMenu.vue';
const props = defineProps<{
id: string;
img: string;
}>();
const emit = defineEmits(['delete']);
// 拖拽元素
const DragBox = ref();
// 默认类名
const DefaultClassName = ref('custom-drag-img' + props.id);
const MenuChange = (item: any) => {
if (item.value == 'delete') {
emit('delete', item, props.id);
}
};
class Drag {
constructor(
target,
options = { limit: true, drag: true, zoom: true, minWidth: 0, minHeight: 0 }
) {
this.target = target;
this.options = options;
this.init();
}
// 初始化
init() {
this.target.style.position = 'relative';
this.getBoundary();
if (this.options.drag) {
this.drag();
}
if (this.options.zoom) {
this.addHorn();
this.addBorder();
this.leftZoom();
this.rightZoom();
this.topZoom();
this.bottomZoom();
this.leftTopZoom();
this.leftBottomZoom();
this.rightTopZoom();
this.rightBottomZoom();
}
}
// 获取父元素的宽高
getBoundary() {
this.maxWidth = this.target.parentNode.parentNode.clientWidth;
this.maxHeight = this.target.parentNode.parentNode.clientHeight;
}
// 获取自身起始信息
getInfo(e) {
this.width = this.target.clientWidth;
this.height = this.target.clientHeight;
let translateStr = this.target.style.transform;
if (translateStr) {
const reg = /\d+/g;
let translateArr = translateStr.match(reg);
this.tx = Number(translateArr[0]);
this.ty = Number(translateArr[1]);
} else {
this.tx = 0;
this.ty = 0;
}
this.startX = e.clientX;
this.startY = e.clientY;
}
// 拖动实现
drag() {
this.target.addEventListener('mousedown', (e) => {
this.getInfo(e);
document.onmousemove = (e) => {
if (this.options.limit) {
this.distanceX = Math.max(
0,
Math.min(
this.tx + e.clientX - this.startX,
this.maxWidth - this.width
)
);
this.distanceY = Math.max(
0,
Math.min(
this.ty + e.clientY - this.startY,
this.maxHeight - this.height
)
);
} else {
this.distanceX = this.tx + e.clientX - this.startX;
this.distanceY = this.ty + e.clientY - this.startY;
}
this.target.style.transform = `translate(${this.distanceX}px, ${this.distanceY}px)`;
};
document.onmouseup = () => {
document.onmousemove = null;
};
});
}
// 添加四个角
addHorn() {
this.leftTop = document.createElement('div');
this.rightTop = document.createElement('div');
this.leftBottom = document.createElement('div');
this.rightBottom = document.createElement('div');
this.leftTop.className = 'horn leftTop';
this.rightTop.className = 'horn rightTop';
this.leftBottom.className = 'horn leftBottom';
this.rightBottom.className = 'horn rightBottom';
this.target.append(this.leftTop);
this.target.append(this.rightTop);
this.target.append(this.leftBottom);
this.target.append(this.rightBottom);
}
// 添加四条边
addBorder() {
this.left = document.createElement('div');
this.right = document.createElement('div');
this._top = document.createElement('div');
this.bottom = document.createElement('div');
this.left.className = 'vertical left';
this.right.className = 'vertical right';
this._top.className = 'horizontal top';
this.bottom.className = 'horizontal bottom';
this.target.append(this.left);
this.target.append(this.right);
this.target.append(this._top);
this.target.append(this.bottom);
}
// 缩放实现
zoom(el: any, direction: any) {
el.addEventListener('mousedown', (e) => {
e.stopPropagation();
this.getInfo(e);
document.onmousemove = (e) => {
switch (direction) {
case 'left':
this.leftInfo(e);
break;
case 'right':
this.rightInfo(e);
break;
case 'top':
this.topInfo(e);
break;
case 'bottom':
this.bottomInfo(e);
break;
case 'leftTop':
this.leftTopInfo(e);
break;
case 'leftBottom':
this.leftBottomInfo(e);
break;
case 'rightTop':
this.rightTopInfo(e);
break;
case 'rightBottom':
this.rightBottomInfo(e);
break;
}
// 这里不能直接使用对this.newWidth隐式类型转换来判断,因为this.newWidth===0时,会使用this.width
let width = this.newWidth !== undefined ? this.newWidth : this.width;
let height =
this.newHeight !== undefined ? this.newHeight : this.height;
let translateX =
this.distanceX !== undefined ? this.distanceX : this.tx;
let translateY =
this.distanceY !== undefined ? this.distanceY : this.ty;
this.target.style.width = `${width}px`;
this.target.style.height = `${height}px`;
this.target.style.transform = `translate(${translateX}px, ${translateY}px)`;
};
document.onmouseup = () => {
document.onmousemove = null;
};
});
}
// 获取缩放时宽高、translate等参数的值
leftInfo(e: any) {
this.newWidth = this.width - (e.clientX - this.startX);
this.distanceX = this.tx + (e.clientX - this.startX);
if (this.options.limit) {
this.newWidth = Math.max(
this.options.minWidth,
Math.min(this.newWidth, this.width + this.tx)
);
this.distanceX = Math.max(
0,
Math.min(this.distanceX, this.width + this.tx - this.options.minWidth)
);
}
}
rightInfo(e: any) {
this.newWidth = this.width + (e.clientX - this.startX);
if (this.options.limit) {
this.newWidth = Math.max(
this.options.minWidth,
Math.min(this.newWidth, this.maxWidth - this.tx)
);
}
}
topInfo(e: any) {
this.newHeight = this.height - (e.clientY - this.startY);
this.distanceY = this.ty + (e.clientY - this.startY);
if (this.options.limit) {
this.newHeight = Math.max(
this.options.minHeight,
Math.min(this.newHeight, this.height + this.ty)
);
this.distanceY = Math.max(
0,
Math.min(this.distanceY, this.height + this.ty - this.options.minHeight)
);
}
}
bottomInfo(e: any) {
this.newHeight = this.height + (e.clientY - this.startY);
if (this.options.limit) {
this.newHeight = Math.max(
this.options.minHeight,
Math.min(this.newHeight, this.maxHeight - this.ty)
);
}
}
leftTopInfo(e) {
this.leftInfo(e);
this.topInfo(e);
}
leftBottomInfo(e) {
this.leftInfo(e);
this.bottomInfo(e);
}
rightTopInfo(e) {
this.rightInfo(e);
this.topInfo(e);
}
rightBottomInfo(e) {
this.rightInfo(e);
this.bottomInfo(e);
}
leftZoom() {
this.zoom(this.left, 'left');
}
rightZoom() {
this.zoom(this.right, 'right');
}
topZoom() {
this.zoom(this._top, 'top');
}
bottomZoom() {
this.zoom(this.bottom, 'bottom');
}
leftTopZoom() {
this.zoom(this.leftTop, 'leftTop');
}
leftBottomZoom() {
this.zoom(this.leftBottom, 'leftBottom');
}
rightTopZoom() {
this.zoom(this.rightTop, 'rightTop');
}
rightBottomZoom() {
this.zoom(this.rightBottom, 'rightBottom');
}
}
onMounted(() => {
let dragEl = document.querySelector(`.${DefaultClassName.value}`);
if (dragEl) {
new Drag(dragEl);
}
});
</script>
<style lang="less">
.drag {
height: 100px;
width: 100px;
background-repeat: no-repeat;
background-size: 100% 100%;
-moz-background-size: 100% 100%;
border: 1px dashed transparent;
cursor: all-scroll;
.show-img {
width: 100%;
height: 100%;
user-select: none;
}
&:hover {
border-color: #ddd;
}
.horn {
width: 14px;
height: 14px;
position: absolute;
}
.vertical {
width: 10px;
height: calc(100% - 14px);
margin: 7px 0px;
position: absolute;
cursor: col-resize;
}
.horizontal {
width: calc(100% - 14px);
height: 10px;
margin: 0px 7px;
position: absolute;
cursor: row-resize;
}
.top {
top: -5px;
left: 0;
}
.left {
top: 0;
left: -5px;
}
.bottom {
left: 0;
bottom: -5px;
}
.right {
top: 0;
right: -5px;
}
.leftTop {
cursor: nw-resize;
left: -7px;
top: -7px;
}
.rightTop {
cursor: ne-resize;
right: -7px;
top: -7px;
}
.leftBottom {
cursor: sw-resize;
bottom: -7px;
left: -7px;
}
.rightBottom {
cursor: se-resize;
right: -7px;
bottom: -7px;
}
}
</style>
<template>
<div class="change-img">
<a id="link"></a>
<div class="course-container" id="myImage">
<template v-if="backimg">
<div class="course">
<img :src="backimg" />
</div>
</template>
<template v-else>
<div class="empty-background"></div>
</template>
<template v-if="list.length">
<div class="drag-img-parent">
<template v-for="item in list" :key="item.id">
<ImageDarg
:id="item.id"
:img="item.img"
@delete="DeleteImg"
></ImageDarg>
</template>
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import html2canvas from 'html2canvas';
import { ref, watch } from 'vue';
import ImageDarg from '@/components/custom/ImageDrag.vue';
import { show_message } from '@/utils/tdesign_tool';
import { base642File } from '@/utils/file';
import { UploadImageToAly } from '@/utils/http/http';
import { ModelStatus } from '@/utils/api/Task';
const props = withDefaults(
defineProps<{
list: any[];
edit_image?: string;
module_status: number;
config?: any;
}>(),
{
edit_image: '',
config: {},
}
);
const emit = defineEmits([
'update:module_status',
'moduleChange',
'delete',
'submit',
]);
// 添加可以拖拽功能,放大缩小功能
const backimg = ref(props.edit_image);
watch(
() => props.edit_image,
(v) => {
if (v) {
backimg.value = v;
}
}
);
// menu事件
const DeleteImg = (item: any, id: string) => {
emit('delete', item, id);
};
// 将元素转换为base64格式
const ConversionBase64 = async () => {
const canvas = await html2canvas(document.querySelector('#myImage'));
const base64 = canvas
.toDataURL('image/png')
.replace('image/png', 'image/octet-stream');
return base64;
};
// 保存到本地
const save = () => {
html2canvas(document.querySelector('#myImage')).then((canvas) => {
// var image = canvas
// .toDataURL('image/png')
// .replace('image/png', 'image/octet-stream');
//save as download without name and extension
//window.location.href = image;
var link = document.getElementById('link');
link.setAttribute('download', 'my.png');
link.setAttribute(
'href',
canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
);
link.click();
});
};
// 转换图片
const ConversionImage = async () => {
try {
const { config } = props;
// 转换图片格式
const ImageBase64 = await ConversionBase64();
if (ImageBase64) {
// 转二进制
const file = await base642File(ImageBase64);
if (file) {
// 准备上传图片
const res = await UploadImageToAly(config, file);
if (res.status == 'fail') {
show_message('图片上传失败,请再次点击生成按钮');
return;
}
const url = res.response.url;
// 通知父组件提交任务
emit('submit', url);
}
}
} catch (e) {
console.log(e);
}
};
/**
* 转换为二进制,上传阿里云,提交任务
*/
watch(
() => props.module_status,
(v) => {
if (v == ModelStatus.upload) {
// 上传并提交任务
ConversionImage();
}
}
);
</script>
<style scoped lang="less">
@import '@/style/variables.less';
.change-img {
display: flex;
flex-direction: column;
padding: 20px;
.course-container {
height: 0;
width: 100%;
padding-top: 100%;
position: relative;
flex: 1;
.course {
z-index: 1;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
// object-fit: contain;
// cover 效果更好
object-fit: cover;
}
}
}
}
.empty-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px dashed #00f9f9;
}
.code {
z-index: 2;
position: absolute;
width: 150px;
height: 150px;
img {
width: 100%;
height: 100%;
cursor: move;
}
}
.drag-img-parent {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 3;
}
</style>
<template>
<div class="custom-img-wait">
<CustomLoading></CustomLoading>
<div>请耐心等待图片生成</div>
<div>{{ label }}</div>
</div>
</template>
<script lang="ts" setup>
import CustomLoading from '@/components/custom/loading2.vue';
const props = withDefaults(
defineProps<{
label?: string;
}>(),
{
label: '请耐心等待图片生成',
}
);
</script>
<style lang="less">
......
<template>
<div class="custom-img-wait">
<EmptySvg></EmptySvg>
<div>未有图片,快去左侧输入你的创意吧</div>
<div>{{ label }}</div>
</div>
</template>
<script lang="ts" setup>
import EmptySvg from '@/assets/svg/gpt/empty.svg';
const props = withDefaults(
defineProps<{
label?: string;
}>(),
{
label: '未有图片,快去左侧输入你的创意吧',
}
);
</script>
<style lang="less">
......
<template>
<div class="local-file-upload">
<div
class="not-upload-status"
@click="BeforeUpload"
v-if="UploadStatus == 'wait'"
>
<div class="label-1">选择图片</div>
<div class="label-2">或拖图片到此处上传</div>
<div class=""><UploadSvg></UploadSvg></div>
<CustomResetButton class="chose-local-image" bold
>选择图片</CustomResetButton
>
</div>
<div class="upload-success-box" v-else>
<span class="reset-svg" @click="BeforeUpload">
<ResetSvg></ResetSvg>
</span>
<img :src="CurrentImage" alt="" />
</div>
<input
ref="referenceUpload"
class="custom-upload-file"
type="file"
@change="displayimg"
name="myfile"
accept="image/png, image/jpeg"
required
/>
</div>
</template>
<script lang="ts" setup>
import CustomResetButton from '@/components/custom/resetbutton.vue';
import UploadSvg from '@/assets/svg/upload/uploadTip2.svg';
import { ref } from 'vue';
import { v4 } from 'uuid';
import ResetSvg from '@/assets/svg/upload/reset.svg';
const emit = defineEmits(['SubmitImg']);
const referenceUpload = ref<HTMLElement>();
// 上传状态
const UploadStatus = ref('wait');
// 当前图片
const CurrentImage = ref('');
const BeforeUpload = () => {
referenceUpload.value.click();
};
const displayimg = (e) => {
// 单个上传
// var file = e.target.files[0];
// //判断当前是否支持使用FileReader
// if (window.FileReader) {
// //创建读取文件的对象
// var fr = new FileReader();
// //以读取文件字符串的方式读取文件 但是不能直接读取file
// //因为文件的内容是存在file对象下面的files数组中的
// //该方法结束后图片会以data:URL格式的字符串(base64编码)存储在fr对象的result中
// fr.readAsDataURL(file);
// fr.onloadend = function () {
// // 添加到列表
// emit('SubmitImg', {
// img: fr.result.replace(/\s/g, encodeURIComponent(' ')),
// id: props.list_len + 1 + '',
// });
// };
// }
// 循环获取
let files = e.target.files;
for (let i = 0, j = files.length; i < j; i++) {
console.log(files[i]);
//判断当前是否支持使用FileReader
if (window.FileReader) {
//创建读取文件的对象
const fr = new FileReader();
//以读取文件字符串的方式读取文件 但是不能直接读取file
//因为文件的内容是存在file对象下面的files数组中的
//该方法结束后图片会以data:URL格式的字符串(base64编码)存储在fr对象的result中
fr.readAsDataURL(files[i]);
fr.onloadend = function () {
if (fr.result) {
// 添加到列表
const img = fr.result.replace(/\s/g, encodeURIComponent(' '));
emit('SubmitImg', {
img: img,
id: 1 + '' + v4(),
});
CurrentImage.value = img;
UploadStatus.value = 'success';
}
};
}
}
referenceUpload.value.value = null;
};
</script>
<style lang="less">
@import '@/style/variables.less';
.local-file-upload {
position: relative;
color: white;
font-size: @font-size-16;
height: 100%;
background: #181818;
border: 0.5px dashed #b1b5c4;
border-radius: 8px;
cursor: pointer;
.not-upload-status {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.chose-local-image {
background: #00dddd !important;
font-size: 16px;
color: #000000;
}
.label-1 {
font-weight: 600;
font-size: @font-size-20;
color: #b3bfde;
}
.label-2 {
font-weight: 500;
font-size: @font-size-16;
color: #888fa1;
}
& > :not(:first-child) {
margin-top: 12px;
}
}
.upload-success-box {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
img {
width: 80%;
height: 80%;
}
.reset-svg {
cursor: pointer;
position: absolute;
top: 12px;
right: 12px;
}
}
.custom-upload-file {
position: absolute;
top: 0;
left: 0;
margin: 0;
padding: 0;
cursor: pointer;
display: none;
}
}
</style>
......@@ -73,12 +73,21 @@ watch(
<style lang="less">
@import '@/style/variables.less';
.custom-textarea-box {
position: relative;
width: 100%;
background: #181818;
border: @main-border;
color: white;
resize: none;
border-radius: 8px;
transition: border 0.2s;
&:focus-within {
border-color: #00f9f9;
transition: all 0.2s;
}
.custom-t-textarea {
.t-textarea__inner {
background: #181818;
border: @main-border;
border: none;
color: white;
padding: 6px 12px;
resize: none;
......@@ -94,20 +103,16 @@ watch(
.t-is-focused {
box-shadow: none;
}
&:focus-within {
.t-textarea__inner {
border-color: #00f9f9;
transition: all 0.2s;
}
}
}
.position-text {
position: absolute;
bottom: 12px;
right: 12px;
font-size: @font-size-12;
text-align: right;
padding-right: 12px;
padding-bottom: 6px;
.reset-btn {
cursor: pointer;
user-select: none;
color: #00f9f9;
}
}
}
......
......@@ -4,7 +4,9 @@ import { TASKTYPE } from '@/utils/api/Task';
// 跳转产品详情页
export const JumpDetailPage = (item: any) => {
// 本地写死
item.type = TASKTYPE.MODEL_GENERATION;
// item.type = TASKTYPE.MODEL_GENERATION;
// 模板选择
item.type = TASKTYPE.MODELTEMPLATE;
let path = '';
if (item.type == TASKTYPE.CHAT) {
// 文案1
......@@ -15,6 +17,9 @@ export const JumpDetailPage = (item: any) => {
} else if (item.type == TASKTYPE.MODEL_GENERATION) {
// 模特生成+换衣 4
path = '/ModelGeneration';
} else if (item.type == TASKTYPE.MODELTEMPLATE) {
// 选择模特模板
path = '/ModelTemplate';
}
if (path) {
const url = router.resolve({
......
......@@ -9,8 +9,10 @@ export default defineComponent({
list: Object as any,
status: String,
page_module: Number,
edit_image: String,
},
setup(props, ctx) {
emits: ['update:page_module', 'update:status', 'update:edit_image'],
setup(props, { emit }) {
// 按钮组
const btn_list = [
{
......@@ -38,16 +40,32 @@ export default defineComponent({
// 提交切割任务
const SubmitSplitTask = async () => {
try {
// 进入loading模式
emit('update:status', 'loading');
// let res:any = await dd();
// 10秒后关闭loading
await new Promise((resolve, reject) => {
setTimeout(() => {
emit('update:status', 'success');
// 接口回调中提交要修改的图片链接
emit(
'update:edit_image',
// ' https://img1.baidu.com/it/u=1210516829,3619266924&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750'
new URL('../../../../assets/img/mote2.png', import.meta.url).href
);
resolve('三秒后出现');
}, 3000);
});
} catch (e) {
console.log(e);
}
};
// 图片切割并打开图片合并模块
const Composition = async () => {
// 提交
// 提交图片切割任务
await SubmitSplitTask();
//
// 提交成功后进入第二个模块
emit('update:page_module', 2);
};
// 为空时展示的html
const EmptyHTML = () => {
......@@ -92,14 +110,20 @@ export default defineComponent({
// 判断当前展示的模块--第一个模块
const CurrentModule = () => {
// return LoadSuccessHTML();
const { status } = props;
if (status == '') {
// 未开始
return EmptyHTML();
} else if (status == 'loading') {
return LoadingHTML();
} else {
return LoadSuccessHTML();
const { status, page_module } = props;
if (page_module == 1) {
if (status == '') {
// 未开始
return EmptyHTML();
} else if (status == 'loading') {
return LoadingHTML();
} else {
return LoadSuccessHTML();
}
} else if (page_module == 2) {
if (status == 'loading') {
return LoadingHTML();
}
}
};
return () => <div class="img-res-status">{CurrentModule()}</div>;
......
<template>
<div class="model-generate-success">
<template v-for="item in list" :key="item">
<img :src="item" alt="" />
</template>
</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
list: string[];
}>();
</script>
<style lang="less">
.model-generate-success {
width: 100%;
height: 100%;
padding: 20px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
</style>
<template>
<div class="custom-model-generation-box">
<div class="generation-box-parent">
<div class="generation-box-parent" v-show="AdminData.page_module == 1">
<div class="generation-box" v-show="!loading" ref="GenerationBox">
<div class="interaction-form">
<div
......@@ -65,13 +65,21 @@
</div>
<div class="generate-result">
<GenerateResult
status="success"
:page_module="AdminData.page_module"
v-model:status="AdminData.status"
v-model:page_module="AdminData.page_module"
v-model:edit_image="AdminData.edit_image"
:list="test_list"
></GenerateResult>
</div>
</div>
</div>
<div class="custom-image-edit-box" v-show="AdminData.page_module != 1">
<CompositeImage
v-model:status="AdminData.status"
v-model:page_module="AdminData.page_module"
v-model:edit_image="AdminData.edit_image"
></CompositeImage>
</div>
<CustomLoading v-show="loading"></CustomLoading>
</div>
</template>
......@@ -102,6 +110,7 @@ import { FormExample3 } from '@/utils/api/Task';
import { Validationrules, ChangePageHeight } from '@/utils/tool';
import { useRoute } from 'vue-router';
import { show_message } from '@/utils/tdesign_tool';
import CompositeImage from './components/CompositeImage.vue';
const loading = ref(false);
const route = useRoute();
// 当前
......@@ -130,15 +139,16 @@ const AdminData = reactive({
* loading-生成中
* success-结束
*/
status: '',
status: 'success',
/**
* 当前显示的模块
* 1--模特生成
* 2--图片切割
* 3--图片合成
* 4--合成图片提交
* 2--图片合成
* 3--合成图片提交
*/
page_module: 1,
// 要修改的图片链接
edit_image: '',
reset_num: 1,
});
const scenario_id = ref();
......@@ -234,8 +244,6 @@ const ImageCallback = async (uuid: string) => {
if (res.code == 0) {
if (res.data.image && res.data.image.length) {
AdminData.status = 'success';
// 进入第二个模块
AdminData.page_module = 2;
if (res.data.image.length > AdminData.callback_list.length) {
AdminData.callback_list = res.data.image;
}
......@@ -451,5 +459,9 @@ onBeforeUnmount(() => {
}
}
}
.custom-image-edit-box {
width: 100%;
height: 100%;
}
}
</style>
@import '@/style/variables.less';
.img-res-status {
display: flex;
justify-content: center;
align-items: center;
.empty-box,
.loading-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.custom-loading-two {
position: relative !important;
top: 0;
left: 0;
transform: none;
}
& > :nth-child(2) {
margin-top: 12px;
font-size: @font-size-16;
color: #888fa1;
}
}
.load-success-box {
padding: 0 20px;
height: 100%;
display: flex;
flex-direction: column;
width: 100%;
.result-img-box {
padding: 100px 0 20px 0;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
row-gap: 20px;
width: 100%;
.result-img {
margin: 0 12px;
width: 350px;
height: 350px;
border-radius: 8px;
.img {
width: 100%;
height: 100%;
}
}
}
.download-img-box {
flex: 1;
display: flex;
align-items: flex-end;
padding: 0 12px 20px 12px;
.custom-reset-button {
width: calc(100% - 2px) !important;
&::before {
width: calc(200% - 2px);
}
}
}
}
}
import { defineComponent } from 'vue';
import './index.less';
import CustomResetButton from '@/components/custom/resetbutton.vue';
import OnWait from '@/components/custom/ImgLoadingStatus/OnWait.vue';
import OnLoading from '@/components/custom/ImgLoadingStatus/OnLoading.vue';
export default defineComponent({
props: {
list: Object as any,
status: String,
},
setup(props, ctx) {
// 为空时展示的html
const EmptyHTML = () => {
return <OnWait></OnWait>;
};
// 加载时的html
const LoadingHTML = () => {
return <OnLoading></OnLoading>;
};
// 加载完成展示的html
const LoadSuccessHTML = () => {
return (
<div class="load-success-box">
<div class="result-img-box">
{props.list
? props.list.map((item: any) => (
<div class="result-img">
<img class="img" src={item} alt="" />
</div>
))
: ''}
</div>
<div class="download-img-box">
<CustomResetButton>下载</CustomResetButton>
</div>
</div>
);
};
// 判断当前展示的模块
const CurrentModule = () => {
// return LoadSuccessHTML();
const { status } = props;
if (status == '') {
// 未开始
return EmptyHTML();
} else if (status == 'loading') {
return LoadingHTML();
} else {
return LoadSuccessHTML();
}
};
return () => <div class="img-res-status">{CurrentModule()}</div>;
},
});
......@@ -57,6 +57,15 @@ export default [
header: true,
},
},
// 模特模板选择+换衣 ModelTemplate
{
path: '/ModelTemplate',
name: 'ModelTemplate',
component: () => import('@/pages/ModelTemplate/index.vue'),
meta: {
header: true,
},
},
{
path: '/login',
name: 'login',
......
......@@ -14,11 +14,11 @@
&::-webkit-scrollbar {
}
&::-webkit-scrollbar-thumb {
background: #ddd;
background: #565656;
}
&:hover {
&::-webkit-scrollbar-thumb {
background: #ddd !important;
background: #565656 !important;
}
}
}
......@@ -13,6 +13,17 @@ export const TASKTYPE = {
VIDEO: 3,
// 模特生成+换衣
MODEL_GENERATION: 4,
// 选择模特模板+换衣
MODELTEMPLATE: 5,
};
// 模特换衣模块状态
export const ModelStatus = {
wait: 1,
upload: 2,
loading: 3,
success: 4,
error: 5,
};
// 文案生成对话记录 本地的key
......@@ -233,17 +244,12 @@ export const FormExample2 = [
label: '上传图片',
value: null,
span: 24,
// rules: [
// {
// type: 'required',
// message: '必填',
// },
// ],
rules: [],
},
],
},
];
//
// 亚马逊模特生成+换衣 form表单示例
export const FormExample3 = [
{
......@@ -310,3 +316,91 @@ export const FormExample3 = [
],
},
];
// 模特模板选择+换衣
// select_model 选择模特
// local_upload 本地上传
export const FormExample4 = [
{
name: '模特样式',
lists: [
{
// 选择模特
type: 'select_model',
name: 'model_1',
label: '模特样式',
value: null,
span: 24,
placeholder:
'输入模特性别、区域、服装类别 “例如:女模特、亚洲、连衣裙”',
maxlength: 1000,
rules: [
{
type: 'required',
message: '模特样式必选',
},
],
},
],
},
// 图片尺寸
{
name: '图片尺寸',
lists: [
{
// 单选按钮组
type: 'radio_group_size',
name: 'size_1',
value: '1600x1600',
span: 24,
label: '图片尺寸',
placeholder: '详细描述产品细节,生成的文案更加完美。',
options: [
{
size: '1600x1600',
label: '亚马逊产品图尺寸',
value: '1600x1600',
},
{
size: '600x180',
label: '亚马逊a+主图',
value: '600x180',
},
{
type: 'custom',
label: '自定义',
value: '',
value1: '',
value2: '',
},
],
rules: [
{
type: 'required',
message: '图片尺寸必选',
},
],
},
],
},
// 本地图片上传
{
name: '图片上传',
lists: [
{
// 选择模特
type: 'local_upload',
name: 'local_upload',
label: '图片上传',
value: null,
span: 24,
rules: [
{
type: 'required',
message: '图片必传',
},
],
},
],
},
];
import { RequestMethodResponse } from 'tdesign-vue-next';
import { v4 } from 'uuid';
import request from '@/utils/otherRequest';
/**
* 可复用的http请求
*/
/**
* 图片上传到阿里云
*/
export const UploadImageToAly = (config: any, file: File) => {
return new Promise<RequestMethodResponse>((resolve) => {
const uuid = v4();
let url = '';
url = 'https://' + config.host;
setTimeout(() => {
const formData = new FormData();
formData.append('key', config.dir + uuid + '.png');
formData.append('policy', config.policy);
formData.append('OSSAccessKeyId', config.accessid);
formData.append('success_action_status', '200');
formData.append('callback', config.callback);
formData.append('signature', config.signature);
// formData.append('name', uuid + '.png');
formData.append('file', file);
request
.post(url, formData, {
headers: {
'Content-Type': 'multipart/form-data;charset=utf-8',
// Accept: '*/*',
},
})
.then((res: any) => {
// resolve 参数为关键代码
const url = config.domain + config.dir + uuid + '.png';
if (res == 200) {
// 外网url
resolve({
status: 'success',
response: { url: url },
});
} else {
resolve({
status: 'fail',
response: { url: url },
});
}
})
.catch((e) => {
console.log(e);
});
}, 1000);
});
};
......@@ -125,8 +125,6 @@ export const ChangePageHeight = (el: HTMLElement) => {
// 获取元素高度
const el_height = el.clientHeight;
const client = el.getBoundingClientRect();
console.log(el_height);
console.log(client.bottom);
if (client.bottom > el_height) {
// 铺满屏幕
el.style.height = '100%';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment