|
|
@@ -0,0 +1,1090 @@
|
|
|
+<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>
|
|
|
+
|
|
|
+
|