| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090 |
- <template>
- <el-dialog title="结果预定与审核" width="80%" custom-class="reservation-approval-dialog" :visible.sync="dialogVisible" :close-on-click-modal="false">
- <div class="reservation-approval-block">
- <div class="reservation-approval-header">
- <div class="crop-type-block" v-if="pages == 'crop' && statusPages == 4">
- <span class="label">裁切类型:</span>
- <el-select v-model="form.cropType" clearable placeholder="请选择" size="small">
- <el-option
- v-for="item in cropTypes"
- :key="item.value"
- :label="item.label"
- :value="item.value">
- </el-option>
- </el-select>
- </div>
- <div class="crop-colorCode-block" style="display: flex;align-items: center;" v-if="pages == 'crop' && statusPages == 4">
- <span class="label" style="white-space: nowrap;">颜色代码:</span>
- <el-input v-model="form.colorCode" size="small"></el-input>
- </div>
- <div class="crop-colorCode-block" style="display: flex;align-items: center;" v-if="cropPreview && statusPages == 4">
- <span class="label" style="white-space: nowrap;">SKU:</span>
- <el-input v-model="form.sku" size="small"></el-input>
- </div>
- <div class="reservation-approval__status" v-if="!cropPreview">
- <ul v-if="pages == 'review'">
- <li :class="{'active': statusPages == 2}">待审核图</li>
- <li :class="{'active': statusPages == 3}">待复核</li>
- <li :class="{'active': statusPages == 4}">审核完成</li>
- </ul>
- <ul v-if="pages == 'crop'">
- <li :class="{'active': statusPages == 4}">待裁图</li>
- <li :class="{'active': statusPages == 5}">待复核</li>
- <li :class="{'active': statusPages >= 6}">已完成</li>
- </ul>
- </div>
- <div class="reservation-approval__save" v-if="!cropPreview && (pages == 'review' || (pages == 'crop' && statusPages >= 4))">
- <el-button
- size="small"
- :disabled="(pages == 'review' && statusPages == 4) || (pages == 'crop' && statusPages >= 6) || !imagesList.length"
- :loading="saveLoading"
- @click="saveHandle"
- >
- 保存修改
- </el-button>
- </div>
- <div class="reservation-approval__confirm">
- <el-button
- type="primary"
- size="small"
- :disabled="(pages == 'review' && statusPages == 4) || (pages == 'crop' && statusPages >= 6) || !imagesList.length"
- :loading="reviewLoading"
- @click="handleConfirm"
- >
- {{ pages == 'crop' && statusPages == 4 ? '确认裁图' : '审核通过' }}
- </el-button>
- </div>
- <div class="reservation-approval__submit" v-if="statusPages == 8">
- <el-button
- type="primary"
- size="small"
- :loading="submitLoading"
- @click="uploadGalleryList"
- >
- 上传图库
- </el-button>
- </div>
- </div>
- <div class="reservation-approval-body" :class="{'full': !form.regenerateImage}">
- <el-row>
- <el-col :span="24">
- <div class="images-list-wapper" v-if="statusPages >= 5">
- <div class="images-list__one">
- <h2>主图1:1</h2>
- <draggable
- tag="div"
- class="images-list-block"
- v-model="imagesList"
- @start="onDragStart"
- @end="onDragEnd"
- :options="{ animation: 150 }">
- <div class="images-items" v-for="(acc, index) in imagesList" v-if="acc.position === 'main' && acc.width === acc.height" :key="index">
- <images-item :images-list="cropPreview ? imagesList : originalImagesList" :pages="pages" :item="acc" :index="index" :status-pages="statusPages" @delImage="delImage" @needRegenerate="needRegenerate"></images-item>
- </div>
- </draggable>
- </div>
- <div class="images-list__one">
- <h2>主图3:4</h2>
- <draggable
- tag="div"
- class="images-list-block"
- v-model="imagesList"
- @start="onDragStart"
- @end="onDragEnd"
- :options="{ animation: 150 }">
- <div class="images-items" v-for="(acc, index) in imagesList" v-if="acc.position === 'main' && acc.width !== acc.height" :key="index">
- <images-item :images-list="cropPreview ? imagesList : originalImagesList" :pages="pages" :item="acc" :index="index" :status-pages="statusPages" @delImage="delImage" @needRegenerate="needRegenerate"></images-item>
- </div>
- </draggable>
- </div>
- <div class="images-list__one">
- <h2>竖图2:3</h2>
- <draggable
- tag="div"
- class="images-list-block"
- v-model="imagesList"
- @start="onDragStart"
- @end="onDragEnd"
- :options="{ animation: 150 }">
- <div class="images-items" v-for="(acc, index) in imagesList" v-if="acc.position === 'list'" :key="index">
- <images-item :images-list="cropPreview ? imagesList : originalImagesList" :pages="pages" :item="acc" :index="index" :status-pages="statusPages" @delImage="delImage" @needRegenerate="needRegenerate"></images-item>
- </div>
- </draggable>
- </div>
- <div class="images-list__one">
- <h2>颜色图1:1</h2>
- <draggable
- tag="div"
- class="images-list-block"
- v-model="imagesList"
- @start="onDragStart"
- @end="onDragEnd"
- :options="{ animation: 150 }">
- <div class="images-items" v-for="(acc, index) in imagesList" v-if="acc.position === 'color'" :key="index">
- <images-item :images-list="cropPreview ? imagesList : originalImagesList" :pages="pages" :item="acc" :index="index" :status-pages="statusPages" @delImage="delImage" @needRegenerate="needRegenerate"></images-item>
- </div>
- </draggable>
- </div>
- </div>
- <div class="images-list-wapper" v-else>
- <draggable
- tag="div"
- class="images-list-block"
- v-model="imagesList"
- @start="onDragStart"
- @end="onDragEnd"
- :move="checkMove"
- :options="{ animation: 150 }">
- <div class="images-items" v-for="(acc, index) in imagesList" :key="index">
- <images-item :images-list="cropPreview ? imagesList : originalImagesList" :crop-preview="cropPreview" :pages="pages" :item="acc" :index="index" :status-pages="statusPages" @delImage="delImage" @needRegenerate="needRegenerate"></images-item>
- </div>
- <div class="images-items fixed-item" v-if="cropPreview">
- <div class="images-items__img">
- <el-upload
- ref="uploadRefCrop"
- class="upload-demo"
- drag
- :action="action"
- :show-file-list="false"
- :headers="{
- 'Authorization': 'Bearer ' + token
- }"
- multiple
- :on-success="handleVideoSuccess"
- :before-upload="beforeUploadVideo">
- <div v-loading="uploading">
- <div class="el-upload__info">
- <i class="el-icon-upload"></i>
- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
- <div class="el-upload__tip" slot="tip">图片要求:支持JPG、PNG和WEBP,最大为20M</div>
- </div>
- </div>
- </el-upload>
- </div>
- </div>
- </draggable>
- </div>
- </el-col>
- </el-row>
- <div class="regenerate-block" v-if="form.regenerateImage && statusPages < 6">
- <el-form ref="regenerate-form" :model="form" label-width="100px" label-position="top">
- <el-form-item>
- <img class="regenerate-image" :src="form.regenerateImage" alt="">
- </el-form-item>
- <el-form-item label="商品信息">
- <el-input v-model="form.sku" size="small" disabled></el-input>
- </el-form-item>
- <el-form-item label="内容" v-if="pages == 'review'" class="upload-form-item">
- <el-input v-model="form.prompt" :rows="5" type="textarea"></el-input>
- </el-form-item>
- <el-form-item label="裁图图片" v-if="pages == 'crop'" class="upload-form-item">
- <el-upload
- ref="uploadRef"
- class="upload-demo"
- drag
- :action="action"
- :show-file-list="false"
- :headers="{
- 'Authorization': 'Bearer ' + token
- }"
- :on-success="handleVideoSuccess"
- :before-upload="beforeUploadVideo">
- <div v-loading="uploading">
- <div v-if="form.imageUrl" class="avatar-black">
- <img :src="form.imageUrl" class="avatar">
- <div class="custom-file__btns">
- <el-button
- class="replace-btn"
- @click.stop="replaceFile()">
- <svg t="1760412251487" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6466" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M902.314667 206.741333a21.333333 21.333333 0 0 1 0 30.122667l-46.933334 47.146667-122.581333 123.178666a21.333333 21.333333 0 0 1-30.229333 0l-31.829334-31.957333a21.333333 21.333333 0 0 1 0-30.122667l42.666667-42.816c13.376-13.44 3.84-36.394667-15.146667-36.394666H375.189333c-46.933333 0-91.157333 18.389333-124.373333 51.733333a175.914667 175.914667 0 0 0-51.52 124.885333v91.712a21.333333 21.333333 0 0 1-21.333333 21.333334H132.970667a21.333333 21.333333 0 0 1-21.333334-21.333334v-91.818666c0-146.090667 118.037333-264.618667 263.530667-264.618667h323.008c18.986667 0 28.522667-22.933333 15.125333-36.373333l-42.666666-42.837334a21.333333 21.333333 0 0 1 0-30.101333l31.829333-31.978667a21.333333 21.333333 0 0 1 30.250667 0l122.581333 123.093334 47.018667 47.146666z m-97.941334 353.706667c0 47.146667-18.325333 91.52-51.541333 124.885333a174.464 174.464 0 0 1-124.373333 51.733334H325.653333c-18.986667 0-28.522667-22.954667-15.125333-36.394667l42.752-42.922667a21.333333 21.333333 0 0 0 0-30.122666l-31.829333-31.957334a21.333333 21.333333 0 0 0-30.229334 0l-122.602666 123.008-46.933334 47.146667a21.333333 21.333333 0 0 0 0 30.08l46.933334 47.146667 122.602666 123.093333a21.333333 21.333333 0 0 0 30.229334 0l31.829333-31.957333a21.333333 21.333333 0 0 0 0-30.101334l-42.453333-42.624c-13.397333-13.44-3.861333-36.394667 15.104-36.394666H628.48c145.493333 0 263.530667-118.528 263.530667-264.618667v-90.538667a21.333333 21.333333 0 0 0-21.333334-21.333333h-44.970666a21.333333 21.333333 0 0 0-21.333334 21.333333v90.538667z" p-id="6467" fill="#ffffff"></path></svg>
- 重新上传
- </el-button>
- <el-button
- class="replace-btn"
- @click.stop="imgUploadDel()">
- <svg t="1760412304801" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7509" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M853.333333 256H170.666667V853.333333a85.333333 85.333333 0 0 0 85.333333 85.333334h512A85.333333 85.333333 0 0 0 853.333333 853.333333V256zM85.333333 170.666667h170.666667V85.333333A85.333333 85.333333 0 0 1 341.333333 0h341.333334a85.333333 85.333333 0 0 1 85.333333 85.333333V170.666667h213.333333a42.666667 42.666667 0 0 1 0 85.333333H938.666667V853.333333a170.666667 170.666667 0 0 1-170.666667 170.666667h-512a170.666667 170.666667 0 0 1-170.666667-170.666667V256H42.666667a42.666667 42.666667 0 1 1 0-85.333333H85.333333zM341.333333 170.666667h341.333334V85.333333H341.333333V170.666667z m42.666667 256c23.552 0 42.666667 19.114667 42.666667 42.666666v256a42.666667 42.666667 0 0 1-85.333334 0v-256c0-23.552 19.114667-42.666667 42.666667-42.666666z m256 0c23.552 0 42.666667 19.114667 42.666667 42.666666v256a42.666667 42.666667 0 0 1-85.333334 0v-256c0-23.552 19.114667-42.666667 42.666667-42.666666z" fill="#ffffff" p-id="7510"></path></svg>
- 删除图片
- </el-button>
- </div>
- </div>
- <div class="el-upload__info" v-else>
- <i class="el-icon-upload"></i>
- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
- <div class="el-upload__tip" slot="tip">图片要求:支持JPG、PNG和WEBP,最大为20M</div>
- </div>
- </div>
- </el-upload>
- </el-form-item>
- <span class="tips">重生成之后,需要保存!</span>
- </el-form>
- <span class="regenerate-footer">
- <el-button size="small" @click="colseRegenerateImage">取消</el-button>
- <el-button type="primary" size="small" :loading="regenerateLoading" @click="handleRegenerate">重生成</el-button>
- </span>
- </div>
- </div>
- </div>
- </el-dialog>
- </template>
- <script>
- import { api } from "@/api/api";
- import { getToken } from '@/utils/auth'
- import draggable from "vuedraggable";
- import ImagesItem from "./ImagesItem";
- import request from '@/utils/request'
- import { genCidHex16, fetchStreamText } from '@/utils/index'
- export default {
- name: "CropSizeModal",
- props: {
- sizeList: {
- type: Array,
- default: () => {
- return []
- }
- }
- },
- components: {
- draggable,
- ImagesItem
- },
- data() {
- return {
- action: api.fileUrl,
- uploading: false,
- cropPreview: false,
- pages: '',
- statusPages: '',
- paramsId: '',
- taskId: '',
- form: {
- imageId: '',
- regenerateImage: null,
- sku: null,
- prompt: '',
- imageUrl: '',
- cropType: null,
- colorCode: ''
- },
- rules: {
- cropType: [
- { required: true, message: '请选择裁图类型', trigger: 'change' }
- ]
- },
- cropTypes: [
- {label: '上衣/短外套', value: 1},
- {label: '下装(裤子、半身裙)', value: 2},
- {label: '连衣裙/套装/中长外套', value: 3},
- {label: '膝盖以上的连身装(连衣裙、外套)', value: 4}
- ],
- imagesList: [],
- originalOrders: [],
- originalImagesList: [],
- dialogVisible: false,
- saveLoading: false,
- submitLoading: false,
- reviewLoading: false,
- regenerateLoading: false,
- isCropDone: false
- };
- },
- computed: {
- token() {
- return getToken();
- }
- },
- watch: {
- dialogVisible(val) {
- if (!val) {
- this.regenerateLoading = false;
- if (this.reviewLoading) {
- // 说明裁图还没有执行完毕
- this.isCropDone = true;
- } else {
- this.isCropDone = false;
- }
- this.resetForm();
- }
- }
- },
- methods: {
- show(row, type) {
- this.dialogVisible = true;
- this.$nextTick(() => {
- // if (localStorage.getItem('cropInfo')) {
- // try {
- // const cropInfo = JSON.parse(localStorage.getItem('cropInfo'));
- // this.form.sku = cropInfo.sku || null;
- // this.form.cropType = cropInfo.cropType || null;
- // this.form.colorCode = cropInfo.colorCode || '';
- // } catch (e) {}
- // }
- this.cropPreview = false;
- this.saveLoading = false;
- this.pages = type;
- this.paramsId = row.id;
- if (row.type == 1) {
- this.originalImagesList = [...row.referenceImagesList, ...row.originalImagesList];
- } else {
- this.originalImagesList = row.aiGeneratedImageVOList.filter(acc => acc.imageType == 1).map(acc => {
- return acc.imageUrl
- });
- }
- // this.originalImagesList = [...row.referenceImagesList, ...row.originalImagesList];
- this.taskId = row.aiGeneratedImageVOList && row.aiGeneratedImageVOList[0].taskId;
- this.statusPages = row.status * 1;
- this.form.sku = row.sku;
- const images = this.statusPages < 5 ? row.aiGeneratedImageVOList.filter(acc => acc.imageType == 1) : row.aiGeneratedImageVOList.filter(acc => acc.imageType == 2);
- this.imagesList = images.map(acc => {
- return {
- id: acc.id,
- imageUrl: acc.imageUrl,
- imageOrder: acc.imageOrder,
- position: acc.position,
- width: acc.width,
- height: acc.height
- }
- })
- console.log(this.imagesList, 444)
- })
- },
- init() {
- this.dialogVisible = true;
- this.$nextTick(() => {
- this.saveLoading = false;
- this.reviewLoading = false;
- this.taskId = '';
- this.cropPreview = true;
- this.pages = 'crop';
- this.statusPages = 4;
- this.originalImagesList = []
- })
- },
- uploadGalleryList() {
- this.submitLoading = true;
- const params = {
- taskId: this.taskId
- }
- request({
- url: '/imageTask/uploadGallery',
- method: 'post',
- data: params
- }).then(res => {
- if (res.code == 200) {
- this.$message.success(res.msg || '操作成功!');
- }
- }).finally(() => {
- this.submitLoading = false
- })
- },
- saveHandle() {
- this.saveLoading = true;
- request({
- url: '/image/update',
- method: 'post',
- data: this.imagesList.map(acc => {
- return {
- id: acc.id,
- imageUrl: acc.imageUrl,
- imageOrder: acc.imageOrder,
- }
- })
- }).then(res => {
- if (res.code == 200) {
- this.$emit('update-success');
- this.$message.success(res.msg || '保存成功!');
- }
- }).finally(() => {
- this.saveLoading = false;
- })
- },
- async handleCrop() {
- // 参数校验
- if (!this.validateCropParams()) return;
- try {
- this.reviewLoading = true;
- // 如果是裁图预览模式,先直传图片
- if (this.cropPreview && !this.taskId) {
- const res = await this.directSubmitImages();
- if (res.code === 200) {
- this.isCropDone = false;
- this.dialogVisible = false
- this.$emit('update-success');
- this.$message.success('裁图已提交');
- }
- } else {
- // 执行裁图
- const res = await this.cropImagesHandle();
- if (res.code === 200 && this.taskId && !this.isCropDone) {
- this.isCropDone = false;
- this.afterCropSuccess(res);
- }
- if (res.code === 500) {
- this.isCropDone = false;
- this.$emit('update-success');
- }
- }
- } catch (err) {
- console.error(err);
- } finally {
- this.reviewLoading = false;
- }
- },
- // ======================
- // 参数校验
- // ======================
- validateCropParams() {
- if (this.cropPreview && !this.form.sku) {
- this.$message.error('请填写SKU!');
- return false;
- }
- if (!this.form.cropType || !this.form.colorCode) {
- this.$message.error('请选择裁切类型或填写颜色代码!');
- return false;
- }
- return true;
- },
- // ======================
- // 直传图片(directSubmit)
- // ======================
- directSubmitImages() {
- return request({
- url: '/imageTask/directSubmit',
- method: 'post',
- data: {
- sessionId: `${Date.now() + 10}_${genCidHex16()}`,
- applicationId: 6,
- sizes: this.sizeList.map(acc => ({
- position: acc.positionCode,
- height: acc.height,
- width: acc.width,
- sort: acc.sort
- })),
- tasks: [
- {
- sku: this.form.sku,
- type: this.form.cropType,
- colorCode: this.form.colorCode,
- images: this.imagesList.map((acc, index) => ({
- imageUrl: acc.imageUrl,
- imageOrder: index
- }))
- }
- ]
- }
- });
- },
- // ======================
- // 裁图接口(crop)
- // ======================
- cropImagesHandle() {
- return request({
- url: '/imageTask/crop',
- method: 'post',
- data: {
- sessionId: `${Date.now() + 10}_${genCidHex16()}`,
- applicationId: 6,
- sku: this.form.sku,
- type: this.form.cropType,
- taskId: this.taskId,
- colorCode: this.form.colorCode,
- sizes: this.sizeList.map(acc => ({
- position: acc.positionCode,
- height: acc.height,
- width: acc.width,
- sort: acc.sort
- }))
- }
- });
- },
- // ======================
- // 裁图成功后的统一处理
- // ======================
- afterCropSuccess(res) {
- this.statusPages += 1;
- this.$emit('update-success');
- this.$emit('update-status', this.paramsId, this.statusPages);
-
- this.imagesList = res.data.map(acc => ({
- id: acc.id,
- imageUrl: acc.imageUrl,
- imageOrder: acc.imageOrder,
- position: acc.position,
- width: acc.width,
- height: acc.height
- }));
- this.$message.success(res.msg || '操作成功!');
- },
- handleConfirm() {
- if (this.pages == 'crop' && this.statusPages == 4) {
- this.handleCrop();
- } else {
- this.reviewLoading = true;
- request({
- url: `/imageTask/audit/${this.paramsId}`,
- method: 'post',
- data: {
- id: this.paramsId,
- aiGeneratedImageUpdateParams: this.imagesList.map(acc => {
- return {
- id: acc.id,
- imageUrl: acc.imageUrl,
- imageOrder: acc.imageOrder,
- }
- })
- }
- }).then(res => {
- if (res.code == 200) {
- this.statusPages += 1;
- if (this.statusPages >= 6) {
- this.form.regenerateImage = null;
- }
- this.$emit('update-status', this.paramsId, this.statusPages);
- this.$message.success(res.msg || '操作成功!');
- }
- }).finally(() => {
- this.reviewLoading = false;
- })
- }
-
- },
- // 拖动开始:记录原始 imageOrder 顺序
- onDragStart() {
- this.originalOrders = this.imagesList.map(item => item.imageOrder)
- },
- checkMove(evt) {
- // 禁止 fixed-item 被拖动
- if (evt.dragged.classList.contains('fixed-item')) {
- return false
- }
- return true
- },
- // 拖动结束:按当前位置重新赋值 imageOrder
- onDragEnd() {
- this.imagesList = this.imagesList.map((item, index) => {
- return {
- ...item,
- imageOrder: this.originalOrders[index]
- }
- })
- },
- delImage(row, itemIndex) {
- //删除
- this.$confirm("确定要删除吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- }).then(() => {
- if (this.cropPreview) {
- this.imagesList.splice(itemIndex, 1);
- this.$notify({
- title: "成功",
- message: "删除成功",
- type: "success",
- duration: 3000
- });
- } else {
- request({
- url: '/image/delete',
- method: 'post',
- data: [row.id]
- }).then(res => {
- if (res.code == 200) {
- this.imagesList.forEach((acc, itemIndex) => {
- if (acc.id == row.id) {
- this.imagesList.splice(itemIndex, 1);
- }
- })
- this.$emit('update-images', this.paramsId, row.id);
- if (row.id == this.form.imageId) {
- this.form.regenerateImage = null;
- }
- this.$notify({
- title: "成功",
- message: "删除成功",
- type: "success",
- duration: 3000
- });
- }
- }).finally(() => {
-
- })
- }
-
- });
- },
- colseRegenerateImage() {
- this.form.regenerateImage = null;
- this.form.prompt = '';
- this.form.imageUrl = '';
- },
- async handleRegenerate() {
- if (this.pages == 'review' && !this.form.prompt) {
- this.$message.error('请填写内容!');
- return;
- }
- if (this.pages == 'crop' && !this.form.imageUrl) {
- this.$message.error('请上传裁图图片!');
- return;
- }
- if (this.pages == 'review') {
- this.regenerateLoading = true;
- try {
- const payload = {
- sessionId: `${Date.now() + 10}_${genCidHex16()}`,
- applicationId: 2,
- images: this.pages == 'review' ? [this.form.regenerateImage] : [this.form.imageUrl]
- }
- if (this.pages == 'review') {
- payload.prompt = this.form.prompt;
- }
- const result = await fetchStreamText(`/app/ai/send/imageMessage`, payload, {
- onChunk: (chunk) => {
- console.log('实时分片:', chunk)
- // this.replyText += chunk // Vue 可实时更新聊天内容
- }
- })
- try {
- this.regenerateLoading = false;
- if (result && typeof result == 'string') {
- console.log('完整文本:', result)
- const data = JSON.parse(result)
- if (result.code == 200) {
- this.imagesList.forEach(acc => {
- if (acc.id == this.form.imageId) {
- acc.imageUrl = data.image
- }
- })
- } else {
- if (result.code == 401) {
- this.$router.push(`/login`);
- } else {
- this.$message.error(result.msg || result.errorContent || '请求出错,请联系管理员!');
- }
- }
- } else {
- console.log('JSON 对象12', result)
- if (result.code == 200) {
- this.imagesList.forEach(acc => {
- if (acc.id == this.form.imageId) {
- acc.imageUrl = result.image
- }
- })
- } else {
- if (result.code == 401) {
- this.$router.push(`/login`);
- } else {
- this.$message.error(result.msg || result.errorContent || '请求出错,请联系管理员!');
- }
-
- }
- }
- } catch (e) {
- console.error('报错:', e)
- }
- } catch (e) {
- console.error('请求错误:', e)
- } finally {
- this.regenerateLoading = false;
- }
- } else {
- this.imagesList.forEach(acc => {
- if (acc.id == this.form.imageId) {
- acc.imageUrl = this.form.imageUrl;
- }
- })
- }
- },
- needRegenerate(item) {
- this.form.imageUrl = '';
- this.form.imageId = this.imagesList.filter(acc => acc.id == item.id)[0].id;
- this.form.regenerateImage = this.imagesList.filter(acc => acc.id == item.id)[0].imageUrl;
- },
- replaceFile() {
- if (this.$refs.uploadRef) {
- // 清空上传队列
- this.$refs.uploadRef.uploadFiles = []
- // 手动触发上传框选择文件
- const input = this.$refs.uploadRef.$el.querySelector('input[type=file]')
- input.click()
- }
- // 在 handleSuccess 中会替换对应文件
- },
- beforeUploadVideo(file) {
- this.uploading = true;
- const isLt10M = file.size / 1024 / 1024 < 200;
- const imagesTypes = ['image/png','image/jpeg','image/webp']
- if (!imagesTypes.includes(file.type)) {
- this.uploading = false;
- this.$message.error('图片只能是jpg、png和webp格式!');
- return false;
- }
- if (!isLt10M) {
- this.$message.error('上传文件大小不能超过20MB哦!');
- return false;
- }
- return true
- },
- handleVideoSuccess(res) {
- this.uploading = false
- if (res.code == 200) {
- if (this.cropPreview) {
- this.imagesList.push({
- imageUrl: res.data.url
- })
- } else {
- this.form.imageUrl = res.data.url;
- }
-
- } else {
- this.$message.error('上传失败,请重新上传!');
- }
- },
- imgUploadDel() {
- //删除
- this.$confirm("确定要删除吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- }).then(() => {
- this.form.imageUrl = '';
- this.$notify({
- title: "成功",
- message: "删除成功",
- type: "success",
- duration: 3000
- });
- });
- },
- resetForm() {
- this.cropPreview = false;
- this.pages = '';
- this.statusPages = '';
- this.paramsId = '';
- this.taskId = '';
- this.imagesList = [];
- this.originalOrders = [];
- const data = { sku: this.form.sku, cropType: this.form.cropType, colorCode: this.form.colorCode };
- localStorage.setItem('cropInfo', JSON.stringify(data));
- this.form = {
- imageId: '',
- regenerateImage: null,
- sku: null,
- prompt: '',
- imageUrl: '',
- cropType: null,
- colorCode: ''
- }
- }
- }
- };
- </script>
- <style lang="scss">
- .reservation-approval-dialog {
- margin-top: 5vh !important;
- max-height: 90vh;
- display: flex;
- flex-direction: column;
- height: 100%;
- .el-dialog__body {
- padding-top: 0;
- flex: 1;
- overflow: hidden;
- min-height: 0;
- padding-bottom: 20px;
- }
- }
- .reservation-approval-block {
- height: 100%;
- display: flex;
- flex-direction: column;
- .reservation-approval-header {
- display: flex;
- justify-content: flex-end;
- gap: 20px;
- margin-bottom: 20px;
- }
- .reservation-approval__status ul{
- display: flex;
- margin: 0;
- padding: 0;
- height: 32px;
- border-radius: 200px;
- background: #f2f2f2;
- align-items: center;
- gap: 15px;
- li {
- list-style: none;
- margin: 0;
- height: 100%;
- display: flex;
- align-items: center;
- padding: 0 10px;
- border-radius: 200px;
- font-size: 12px;
- line-height: 32px;
- white-space: nowrap;
- &.active {
- background: #ae8877;
- color: #fff;
- }
- }
- }
- .reservation-approval-body {
- position: relative;
- display: flex;
- height: 100%;
- flex: 1;
- min-height: 0;
- overflow: hidden;
- overflow-y: auto;
- .el-row {
- width: 75%;
- }
- .tips {
- font-size: 12px;
- color: red;
- }
- &.full .el-row {
- width: 100%;
- }
- .images-list__one {
- margin-bottom: 20px;
- &:last-child {
- margin-bottom: 0;
- }
- h2 {
- font-size: 16px;
- color: #333;
- margin: 0;
- padding: 0;
- margin-bottom: 10px;
- }
- }
- .images-list-block {
- display: flex;
- flex-wrap: wrap;
- margin-left: -15px;
- .images-items {
- width: 20%;
- padding-left: 15px;
- margin-bottom: 15px;
- }
- .images-items__img {
- position: relative;
- width: 100%;
- aspect-ratio: 3 / 4;
- display: flex;
- justify-content: center;
- align-items: center;
- border-radius: 4px;
- border: 1px solid #ccc;
- overflow: hidden;
- cursor: pointer;
- &:hover {
- .btns-group {
- display: block;
- }
- }
- .size {
- position: absolute;
- top: 5px;
- left: 5px;
- padding: 0px 7px;
- background: linear-gradient(to right,#b8857b,#e5c0ac);
- color: #fff;
- font-size: 12px;
- height: 20px;
- line-height: 20px;
- display: block;
- z-index: 10;
- }
- .upload-demo {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- }
- .el-upload-dragger {
- width: 100%;
- height: 100%;
- border: none;
- padding: 0 20px;
- .el-icon-upload {
- margin: 0;
- margin-bottom: 30px;
- }
- }
- }
- .btns-group {
- position: absolute;
- bottom: 10px;
- z-index: 10;
- font-size: 12px;
- display: none;
- .el-button {
- border: none;
- background: rgba(0,0,0,0.5);
- color: #fff;
- padding: 7px 15px;
- }
- }
- img {
- display: block;
- max-height: 100%;
- }
- }
- }
- }
- .regenerate-block {
- position: sticky;
- top: 0;
- right: 0;
- width: 25%;
- padding: 0 20px 10px;
- max-height: 100%;
- overflow-y: auto;
- .el-form-item {
- margin-bottom: 10px;
- }
- .regenerate-image {
- max-width: 200px;
- width: 100%;
- margin: 0 auto;
- display: block;
- }
- .el-form-item__label {
- line-height: 20px;
- padding: 0;
- }
- .upload-form-item .el-form-item__label{
- padding-bottom: 4px;
- }
- .el-select {
- width: 100%;
- }
- .el-upload {
- width: 100%;
- height: 100%;
- }
- .el-upload-dragger {
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- .el-icon-upload {
- margin: 0;
- }
- .el-upload__text,.el-upload__tip {
- line-height: 20px;
- }
- }
- .avatar-black {
- position: relative;
- width: 100%;
- height: 100%;
- margin: 0 auto;
- img {
- display: block;
- object-fit: cover;
- width: 100%;
- height: 100%;
- max-width: 50%;
- margin: 0 auto;
- }
- .custom-file__btns {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 10;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.5);
- border-radius: 6px;
- display: none;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 10px;
- transition: all .5s;
- .replace-btn {
- font-size: 12px;
- padding: 4px 10px;
- background: rgba(0, 0, 0, 0.8);
- border-color: rgba(0, 0, 0, 0.8);
- color: #fff;
- margin: 0;
- /deep/ span {
- display: flex;
- align-items: center;
- gap: 4px;
- }
- svg {
- width: 14px;
- height: 14px;
- }
- &:hover {
- background: #ae8878;
- border-color: #ae8878;
- }
- }
- }
- &:hover .custom-file__btns{
- display: flex;
- }
- }
- .regenerate-footer {
- display: flex;
- justify-content: flex-end;
- margin-top: 20px;
- }
- }
- @media screen and (max-width: 1366px) {
- .reservation-approval-block .reservation-approval-body .images-list-block .images-items {
- width: 25%;
- }
- }
- @media screen and (max-width: 1540px) {
- .reservation-approval-block .reservation-approval-header {
- gap: 10px;
- }
- .reservation-approval-dialog {
- width: 98% !important;
- }
- }
- </style>
|