congzc 1年前
コミット
de51a1ba89
9個のファイルの変更581行の追加158行の削除
  1. +26
    -2
      src/apis/createVideo.js
  2. +0
    -97
      src/apis/login copy.js
  3. バイナリ
      src/assets/img/Scale.png
  4. バイナリ
      src/assets/img/delete.png
  5. +159
    -0
      src/components/EditPosition copy.vue
  6. +208
    -0
      src/components/EditPosition.vue
  7. +2
    -0
      src/types/auto-imports.d.ts
  8. +4
    -1
      src/types/components.d.ts
  9. +182
    -58
      src/views/createVideo/index.vue

+ 26
- 2
src/apis/createVideo.js ファイルの表示

@@ -6,9 +6,9 @@ import request from "@/utils/request.js";
* @param sex ,pageNum,pageSize
* @returns data
*/
export function modeListApi(sex, pageNum, pageSize) {
export function modeListApi(sex, pageNum, pageSize, videoType) {
return request({
url: `/api/personPatch/list?sex=${sex}&pageNum=${pageNum}&pageSize=${pageSize}`,
url: `/api/personPatch/list?sex=${sex}&pageNum=${pageNum}&pageSize=${pageSize}&videoType=${videoType}`,
method: 'get'
})
}
@@ -126,3 +126,27 @@ export function saveImgApi(data) {
data
})
}

/**
* @description 删除上传的背景或素材
* @returns id
*/
export function delImgApi(id) {
return request({
url: `/api/materialMould/del?id=${id}`,
method: 'get',
})
}


/**
* @description:根据id获取模板详情
* @param {number} id
* @return data
*/
export function personPatchApi(id) {
return request({
url: `/api/personPatch/findById?id=${id}`,
method: 'get'
})
}

+ 0
- 97
src/apis/login copy.js ファイルの表示

@@ -1,97 +0,0 @@
import request from "@/utils/request.js";

const baseURL = import.meta.env.VITE_APP_BASE_API

/**
* @description 注册
* @params email,password
* @returns data
*/
export function register(data) {
return request({
url: `/api/user/doRegisterByEmail`,
method: 'post',
data
})
}

/**
* @description 登录
* @params email,password,code
* @returns data
*/
export function login(data) {
return request({
url: `/api/user/loginByEmail`,
method: 'post',
data
})
}

/**
/**
* @description:重新发送邮件
* @param {string} data
* @return: data
*/
export function sendRegisterEmail(email) {
return request({
url: `/api/user/sendRegisterEmail`,
method: 'post',
data: {
email
}
})
}

/**
/**
* @description:忘记密码发送邮件
* @param {string} data
* @return: data
*/
export function sendUpdPwdEmailApi(email) {
return request({
url: `/api/user/sendUpdPwdEmail`,
method: 'post',
data: {
email
}
})
}

/**
/**
* @description:邮件重置密码,
* @param pwd, ticket
* @return: data
*/
export function resetPwdEmailApi(data) {
return request({
url: `/api/user/doUpdPass`,
method: 'post',
data
})
}

/**
/**
* @description:邮件重置密码,
* @param oldpwd, newpwd
* @return: data
*/
export function resetPwdFormApi(data) {
return request({
url: `/api/user/oldUpdPass`,
method: 'post',
data
})
}


/**
* @description:获取图形验证码
* @return: 验证码地址
*/
export const getCodeImgUrl = baseURL + '/api/user/captcha.jpg'


バイナリ
src/assets/img/Scale.png ファイルの表示

変更前 変更後
幅: 129  |  高さ: 128  |  サイズ: 2.9 KiB

バイナリ
src/assets/img/delete.png ファイルの表示

変更前 変更後
幅: 200  |  高さ: 200  |  サイズ: 3.8 KiB

+ 159
- 0
src/components/EditPosition copy.vue ファイルの表示

@@ -0,0 +1,159 @@
<template>
<div class="myPage">
<!-- 主要显示 -->
<div
:class="props.videoType == 1 ? 'content1' : 'content2'"
id="content"
:style="bgStyle"
ref="fatherBox"
>
<!-- 数字人的图片 -->
<div
class="virtual"
:class="showBorderActive == materialList.virtual.id ? 'border' : ''"
@mousedown="handleDrag(materialList.virtual.id, $event)"
:style="virtualStyle"
>
<img id="virtualImg" :src="materialList.virtual.material" alt="" />
<div class="stretchBox box1"></div>
<div class="stretchBox box2"></div>
<div class="stretchBox box3"></div>
<div class="stretchBox box4"></div>
</div>
</div>
</div>
</template>
<script setup>
//#region 父组件传参
const props = defineProps({
// isLoading: {
// required: true, //是否必传
// },
materialList: {
required: true,
},
videoType: {
required: true,
},
proportion: {
required: true,
},
});
//#endregion --------------------------
//#region 大盒子样式
const bgStyle = computed(() => {
return {
// width: '1080px',
// height: '1920px',
// transform: 'scale(0.2)',
backgroundImage: `url(${props.materialList.BGI.material})`,
backgroundSize: "cover",
backgroundPosition: "center",
};
});
//#endregion --------------------------
//#region 数字人逻辑
// 计算属性来计算盒子位置和大小
const virtualStyle = computed(() => {
return {
top: props.materialList.virtual.y + "px",
left: props.materialList.virtual.x + "px",
transform:
"scale(" + props.materialList.virtual.w / props.proportion + ") ",
transformOrigin: "top left",
};
});
// 拖动盒子
const showBorderActive = ref(null); //判断显示边框
const fatherBox = ref(null);
const handleDrag = (id, event) => {
showBorderActive.value = id;
event.preventDefault();
const imageElement = fatherBox.value;
const startX = event.clientX; //保存初始值,避免闪烁
const startY = event.clientY;
const startLeft = props.materialList.virtual.x;
const startTop = props.materialList.virtual.y;
// 鼠标移动
const onMouseMove = (event) => {
const deltaX = event.clientX - startX;
const deltaY = event.clientY - startY;
props.materialList.virtual.x = startLeft + deltaX;
props.materialList.virtual.y = startTop + deltaY;
};
// 鼠标抬起
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
};
//#endregion --------------------------
//#region
//#endregion --------------------------
</script>
<style lang="scss" scoped>
.myPage {
// height: 768px;
// width: 432px;
}
.content1 {
position: relative;
height: 768px;
width: 432px;
overflow: hidden;
}
.content2 {
position: relative;
height: 432px;
width: 768px;
overflow: hidden;
}
.virtual {
position: absolute;
user-select: none;
border: rgba(0, 0, 0, 0) 5px solid;
}
.border {
border: 5px solid #00ff00;
.stretchBox {
opacity: 1;
position: absolute;
width: 20px;
height: 20px;
background-color: #7264f5;
}
.box1 {
top: -10px;
left: -10px;
cursor: nwse-resize;
}
.box2 {
top: -10px;
left: 100%;
transform: translateX(-10px);
cursor: nesw-resize;
}
.box3 {
top: 100%;
left: -10px;
transform: translateY(-10px);
cursor: nesw-resize;
}
.box4 {
top: 100%;
left: 100%;
transform: translate(-10px, -10px);
cursor: nwse-resize;
}
}
</style>

+ 208
- 0
src/components/EditPosition.vue ファイルの表示

@@ -0,0 +1,208 @@
<template>
<div class="myPage">
<!-- 主要显示 -->
<div
:class="props.videoType == 1 ? 'content1' : 'content2'"
id="content"
:style="bgStyle"
ref="fatherBox"
>
<!-- 数字人的图片 -->
<div
class="virtual"
:class="showBorderActive == materialList.virtual.id ? 'border' : ''"
@mousedown="handleDrag(materialList.virtual.id, $event)"
:style="virtualStyle"
>
<img id="virtualImg" :src="materialList.virtual.material" alt="" />
<div class="stretchBox box1"></div>
<div class="stretchBox box2"></div>
<div class="stretchBox box3"></div>
<div @mousedown.stop="changeScale" class="stretchBox box4"></div>
</div>
</div>
</div>
</template>
<script setup>
//#region 父组件传参
const props = defineProps({
// isLoading: {
// required: true, //是否必传
// },
materialList: {
required: true,
},
videoType: {
required: true,
},
proportion: {
required: true,
},
});
//#endregion --------------------------
//#region 大盒子样式
const bgStyle = computed(() => {
return {
// width: '1080px',
// height: '1920px',
// transform: 'scale(0.2)',
backgroundImage: `url(${props.materialList.BGI.material})`,
backgroundSize: "cover",
backgroundPosition: "center",
};
});
//#endregion --------------------------
//#region 数字人逻辑
// 计算属性来计算盒子位置和大小
const virtualStyle = computed(() => {
return {
top: props.materialList.virtual.y + "px",
left: props.materialList.virtual.x + "px",
transform:
"scale(" + props.materialList.virtual.w / props.proportion + ") ",
transformOrigin: "top left",
};
});
// 拖动盒子
const showBorderActive = ref(null); //判断显示边框
const fatherBox = ref(null);
const handleDrag = (id, event) => {
showBorderActive.value = id;
event.preventDefault();
const imageElement = fatherBox.value;
const startX = event.clientX; //保存初始值,避免闪烁
const startY = event.clientY;
const startLeft = props.materialList.virtual.x;
const startTop = props.materialList.virtual.y;
// 鼠标移动
const onMouseMove = (event) => {
const deltaX = event.clientX - startX;
const deltaY = event.clientY - startY;
props.materialList.virtual.x = startLeft + deltaX;
props.materialList.virtual.y = startTop + deltaY;
};
// 鼠标抬起
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
};
// 缩放盒子
let touchStart = reactive({
pageX: null,
pageY: null,
});
const scaleNum = ref(0.003);
function changeScale(event) {
event.preventDefault();
const x = event.clientX;
const y = event.clientY;
touchStart = {
pageX: x,
pageY: y,
};
// 鼠标移动
const onMouseMove = (event) => {
const MoveX = event.clientX;
const MoveY = event.clientY;
const flag = Math.sign(x - touchStart.pageX) == -1 ? true : false;
if (flag) {
// 限制最大缩放系数
if (props.materialList.virtual.w > 1.3) return;
props.materialList.virtual.w += scaleNum.value;
// 更新坐标位置
touchStart = {
pageX: MoveX,
pageY: MoveY,
};
} else {
// 限制最小缩放系数
if (props.materialList.virtual.w < 0.4) return;
props.materialList.virtual.w -= scaleNum.value;
// 更新坐标位置
touchStart = {
pageX: MoveX,
pageY: MoveY,
};
}
};
// 鼠标抬起
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
}
//#endregion --------------------------
//#region
//#endregion --------------------------
</script>
<style lang="scss" scoped>
.myPage {
// height: 768px;
// width: 432px;
}
.content1 {
position: relative;
height: 768px;
width: 432px;
overflow: hidden;
}
.content2 {
position: relative;
height: 432px;
width: 768px;
overflow: hidden;
}
.virtual {
position: absolute;
user-select: none;
border: rgba(0, 0, 0, 0) 5px solid;
}
.border {
border: 5px solid #00ff00;
.stretchBox {
opacity: 1;
position: absolute;
width: 20px;
height: 20px;
background-color: #7264f5;
}
.box1 {
top: -10px;
left: -10px;
cursor: nwse-resize;
}
.box2 {
top: -10px;
left: 100%;
transform: translateX(-10px);
cursor: nesw-resize;
}
.box3 {
top: 100%;
left: -10px;
transform: translateY(-10px);
cursor: nesw-resize;
}
.box4 {
top: 100%;
left: 100%;
transform: translate(-10px, -10px);
cursor: nwse-resize;
}
}
</style>

+ 2
- 0
src/types/auto-imports.d.ts ファイルの表示

@@ -2,6 +2,7 @@
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const ElForm: typeof import('element-plus/es')['ElForm']
const ElMessage: typeof import('element-plus/es')['ElMessage']
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
@@ -270,6 +271,7 @@ import { UnwrapRef } from 'vue'
declare module 'vue' {
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']>
readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']>
readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']>
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>


+ 4
- 1
src/types/components.d.ts ファイルの表示

@@ -8,9 +8,12 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default']
copy: typeof import('./../components/myLoading copy.vue')['default']
copy: typeof import('./../components/EditPosition copy.vue')['default']
CutImg: typeof import('./../components/cutImg.vue')['default']
CutImg1: typeof import('./../components/cutImg1.vue')['default']
DoCreateVideo: typeof import('./../components/doCreateVideo.vue')['default']
EditPosition: typeof import('./../components/EditPosition.vue')['default']
'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
ElCol: typeof import('element-plus/es')['ElCol']
ElDialog: typeof import('element-plus/es')['ElDialog']


+ 182
- 58
src/views/createVideo/index.vue ファイルの表示

@@ -26,8 +26,8 @@
<div class="tab" v-show="showChooseModel">
<div
class="tabItem"
:class="modelTabItemActive == 0 ? 'tabItemActive' : ''"
@click="changeTabSex(0)"
:class="modelTabItemActive == -1 ? 'tabItemActive' : ''"
@click="changeTabSex(-1)"
>
{{ $t("createVideo.all") }}
</div>
@@ -50,8 +50,8 @@
<div class="tab" v-show="showChooseModel">
<div
class="tabItem"
:class="modelTabItemActive2 == 0 ? 'tabItemActive' : ''"
@click="changeTabVideoType(0)"
:class="modelTabItemActive2 == -1 ? 'tabItemActive' : ''"
@click="changeTabVideoType(-1)"
>
{{ $t("createVideo.all") }}
</div>
@@ -90,7 +90,16 @@
</div>
<!-- 展示区 -->
<div class="showModelImgBox">
<img :src="modelImg" alt="" />
<!-- <img :src="modelImg" alt="" /> -->
<!-- 编辑图片位置组件 -->
<EditPosition
id="editPosition"
class="EditPosition"
:materialList="materialList"
:videoType="videoType"
:proportion="proportion"
>
</EditPosition>
<!-- 保存视频和生成视频 -->
<div class="btnBox" v-show="!showChooseModel">
<div class="customBtn" style="margin-right: 15px">
@@ -264,6 +273,8 @@
class="bjSystemBoxItem"
v-for="item in systemBGIList"
:key="item.id"
:class="bjImgActive == item.id ? 'ImgBorderActive' : ''"
@click="selectBjImg(item)"
>
<img class="boxCentreImg" :src="item.material" alt="" />
</div>
@@ -293,7 +304,16 @@
class="bjSystemBoxItem"
v-for="item in personBGIList"
:key="item.id"
:class="bjImgActive == item.id ? 'ImgBorderActive' : ''"
@click="selectBjImg(item)"
>
<div
v-show="bjImgActive == item.id"
class="delIcon"
@click="delImg(item.id)"
>
<img src="../../assets/img/delete.png" alt="" />
</div>
<img class="boxCentreImg" :src="item.material" alt="" />
</div>
</div>
@@ -327,6 +347,8 @@
class="bjSystemBoxItem"
v-for="item in systemSCIList"
:key="item.id"
:class="scImgActive == item.id ? 'ImgBorderActive' : ''"
@click="selectScImg(item)"
>
<img class="boxCentreImg" :src="item.material" alt="" />
</div>
@@ -355,7 +377,16 @@
class="bjSystemBoxItem"
v-for="item in personSCIList"
:key="item.id"
:class="scImgActive == item.id ? 'ImgBorderActive' : ''"
@click="selectScImg(item)"
>
<div
v-show="scImgActive == item.id"
class="delIcon"
@click="delImg(item.id)"
>
<img src="../../assets/img/delete.png" alt="" />
</div>
<img class="boxCentreImg" :src="item.material" alt="" />
</div>
</div>
@@ -370,6 +401,7 @@
</div>
</template>

<!-- videoType==1为竖,==2为横 -->
<script setup>
//#region 导入
import { getCurrentInstance } from "vue";
@@ -382,6 +414,8 @@ import {
personBGIListApi,
systemSCIListApi,
personSCIListApi,
delImgApi,
personPatchApi,
} from "@/apis/createVideo";
import { useI18n } from "vue-i18n";
import Recorder from "js-audio-recorder"; //mp3插件
@@ -407,29 +441,21 @@ const videoType = ref(null); //判断横屏2还是竖屏1,初始为没有,控制
const showChooseModel = ref(true); // 控制弹窗显示隐藏
const modeList = ref([]); //模版列表
const modelImg = ref(null); //模版回显图
const modelTabItemActive = ref(0); //模版tab栏 性别
const modelTabItemActive2 = ref(0); //模版tab栏 比例
const modelTabItemActive = ref(-1); //模版tab栏 性别
const modelTabItemActive2 = ref(-1); //模版tab栏 比例
const modelPageNum = ref(1);
const modelPageSize = ref(20);
const overLoadModel = ref(true); //禁用模版加载更多
const modelId = ref(null); // 选中模版的id
// 获取模版列表
async function getModeList(sex, pageNum, pageSize) {
let sexx = null;
if (sex == 0) {
sexx = "";
} else {
sexx = sex;
}
const res = await modeListApi(sexx, pageNum, pageSize);
if (tabVideoType.value == 0) {
async function getModeList(sex, pageNum, pageSize, videoType) {
try {
const res = await modeListApi(sex, pageNum, pageSize, videoType);
modeList.value = res.data.list;
} else {
modeList.value = res.data.list.filter(
(item) => item.videoType == tabVideoType.value
);
overLoadModel.value = false;
} catch (error) {
// ElMessage.success(msg);
}
overLoadModel.value = false;
}
// 点击模版
function clickModelItem(item) {
@@ -439,16 +465,21 @@ function clickModelItem(item) {
modelId.value = item.id;
}
// tab栏切换 性别
// tab栏切换 横竖比例 videoType==1为竖,==2为横
const tabSex = ref(0);
const tabVideoType = ref(0);
// tab栏切换 横竖比例 videoType==1为竖,==2为横,==-1为全部
const tabSex = ref(-1);
const tabVideoType = ref(-1);
function changeTabSex(index) {
modeList.value = [];
modelPageNum.value = 1;
modelTabItemActive.value = index;
overLoadModel.value = false;
tabSex.value = false;
tabSex.value = index;
getModeList(index, modelPageNum.value, modelPageSize.value);
getModeList(
index,
modelPageNum.value,
modelPageSize.value,
tabVideoType.value
);
}
function changeTabVideoType(index) {
modeList.value = [];
@@ -456,7 +487,12 @@ function changeTabVideoType(index) {
modelTabItemActive2.value = index;
overLoadModel.value = false;
tabVideoType.value = index;
getModeList(tabSex.value, modelPageNum.value, modelPageSize.value);
getModeList(
tabSex.value,
modelPageNum.value,
modelPageSize.value,
tabVideoType.value
);
}
// watch(tabSex, (newVal, oldVal) => {
// if (newVal == 0) {
@@ -479,24 +515,16 @@ function changeTabVideoType(index) {
// 触底刷新
async function loadMoreModel(params) {
modelPageNum.value += 1;
if (modelTabItemActive.value == 0) {
const res = await modeListApi("", modelPageNum.value, modelPageSize.value);
modeList.value.push(...res.data.list);
if (res.data.list.length == 0) {
overLoadModel.value = true;
modelPageNum.value = modelPageNum.value - 1;
}
} else {
const res = await modeListApi(
modelTabItemActive.value,
modelPageNum.value,
modelPageSize.value
);
modeList.value.push(...res.data.list);
if (res.data.list.length == 0) {
overLoadModel.value = true;
modelPageNum.value = modelPageNum.value - 1;
}
const res = await modeListApi(
tabSex.value,
modelPageNum.value,
modelPageSize.value,
tabVideoType.value
);
modeList.value.push(...res.data.list);
if (res.data.list.length == 0) {
overLoadModel.value = true;
modelPageNum.value = modelPageNum.value - 1;
}
}
//#endregion ----------------------------
@@ -711,7 +739,11 @@ async function reGetpersonBGIList() {
overLoadpersonBG.value = true;
await getpersonBGIList();
}

// 点击列表中的背景图
const bjImgActive = ref(null);
function selectBjImg(img) {
bjImgActive.value = img.id;
}
//#endregion ----------------------------

//#region 素材
@@ -776,6 +808,87 @@ async function reGetpersonSCIList() {
overLoadpersonSC.value = true;
await getpersonSCIList();
}
// 点击列表中的素材图
const scImgActive = ref(null);
function selectScImg(img) {
scImgActive.value = img.id;
}
// 删除上传的背景或素材
function delImg(id) {
const msg =
lanChange.value == "zh-cn"
? "确定删除图片吗?"
: "Are you sure to delete the picture?";
const notice = lanChange.value == "zh-cn" ? "提示" : "Notice";
const confirm = lanChange.value == "zh-cn" ? "确定" : "Confirm";
const cancel = lanChange.value == "zh-cn" ? "取消" : "Cancel";
ElMessageBox.confirm(msg, notice, {
confirmButtonText: confirm,
cancelButtonText: cancel,
}).then(async () => {
try {
const res = await delImgApi(id);
reGetpersonSCIList();
reGetpersonBGIList();
ElMessage.success(
lanChange.value == "zh-cn" ? "删除成功!" : "Deleted successfully!"
);
} catch (error) {}
});
}
//#endregion ----------------------------

//#region 编辑区域
const proportion = ref(1); //比例
const elementWidth = ref(null);
onMounted(() => {
elementWidth.value = document.getElementById("editPosition").clientWidth;
});
watch(
() => videoType.value,
(newValue, oldValue) => {
// 根据横竖屏来确定比例 1竖2横
if (videoType.value == 1) {
proportion.value = 1080 / elementWidth.value;
} else if (videoType.value == 2) {
proportion.value = 1920 / elementWidth.value;
}
console.log(proportion.value);
},
{ deep: true }
);
const materialList = reactive({
BGI: {},
scList: [],
virtual: {},
});
// 根据模版id获取信息
async function getPersonPatch() {
try {
const res = await personPatchApi(modelId.value);
materialList.BGI.material = res.data.backgroundMaterial;
materialList.BGI.id = res.data.backgroundId + "";
materialList.virtual.material = res.data.material;
materialList.virtual.id = res.data.id;
// if (!materialList.virtual.w) {
materialList.virtual = {
...materialList.virtual,
x: 50,
y: 50,
z: 0,
w: 1,
h: 1,
};
// }
} catch (error) {}
}
watch(
() => modelId.value,
async (newValue, oldValue) => {
await getPersonPatch();
},
{ deep: true }
);
//#endregion ----------------------------

//#region
@@ -799,7 +912,7 @@ onMounted(async () => {
voiceTotal(); //获取声音列表
// getSystemSCIList();
// getpersonBGIList();
await getModeList("", 1, 20); //获取模版列表
await getModeList(tabSex.value, 1, 20, tabVideoType.value); //获取模版列表
getpersonSCIList();
getSystemSCIList();
});
@@ -832,7 +945,7 @@ onMounted(async () => {
left: 0px;
width: 50%;
height: 100%;
padding: 30px;
padding: 30px 30px 10px 30px;
transition: all 0.3s;
// background-color: #f1f2f6;
background-color: #454545;
@@ -917,7 +1030,7 @@ onMounted(async () => {
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;
height: calc(100% - 180px);
max-height: calc(100% - 180px);
padding: 20px;
border-radius: 20px;
// background-color: #fff;
@@ -967,6 +1080,14 @@ onMounted(async () => {
max-width: 800px;
max-height: 800px;
}
.EditPosition {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 800px;
max-height: 800px;
}
.btnBox {
position: absolute;
display: flex;
@@ -1080,27 +1201,30 @@ onMounted(async () => {
background-color: #e5e5e5;
border-radius: 10px;
cursor: pointer;
img {
border: rgba(0, 0, 0, 0) 2px solid;
> img {
padding: 10px;
max-width: 100%;
max-height: 100%;
}
.bjSystemBoxItemAction {
position: relative;
margin-right: 3%;
margin-bottom: 10px;
width: 30%;
height: 200px;
background-color: #e5e5e5;
.delIcon {
position: absolute;
right: 5px;
top: 5px;
width: 20px;
height: 20px;
border-radius: 10px;
z-index: 999;
cursor: pointer;
img {
padding: 10px;
max-width: 100%;
max-height: 100%;
}
}
}
.ImgBorderActive {
border: #7264f5 2px solid;
}
}
}
}


読み込み中…
キャンセル
保存