Files
dyf-vue-ui/src/views/debugCenter/debugPanel/index.vue
2025-09-11 11:10:53 +08:00

1011 lines
28 KiB
Vue

<template>
<div class="content" v-loading="Status.fullLoading">
<div class="percent100">
<div class="topTool">
<div class="button-row">
<el-button type="primary" :disabled="checkrows.length === 0" plain @click.stop="ShowMultiEdit(MideaType.Boot)">修改开机画面</el-button>
<el-button type="primary" :disabled="checkrows.length === 0" plain @click.stop="ShowMultiEdit(MideaType.Param)">修改产品参数</el-button>
<el-button type="primary" :disabled="checkrows.length === 0" plain @click.stop="ShowMultiEdit(MideaType.Oprate)">修改操作说明</el-button>
<el-button type="primary" :disabled="checkrows.length === 0" plain @click.stop="ShowMultiEdit(MideaType.Video)">修改操作视频</el-button>
</div>
<div>
<el-form :inline="true" :model="queryParams" class="demo-form-inline" @submit.native.prevent>
<el-form-item label="" style="margin-right: 15px">
<el-input :suffix-icon="'Search'" v-model="queryParams.deviceName" placeholder="设备名称" clearable @keyup.enter.stop="handleQuery" />
</el-form-item>
<el-form-item style="margin-right: 0px">
<el-button type="primary" @click.stop="showSearch">高级筛选</el-button>
</el-form-item>
</el-form>
</div>
</div>
<div class="demo-collapse" v-show="Status.showSearch.length > 0">
<el-collapse accordion v-model="Status.showSearch">
<el-collapse-item name="1">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" class="queryFormRef">
<el-form-item label="设备类型" prop="deviceType">
<el-select v-model="queryParams.deviceType" placeholder="设备类型">
<el-option v-for="item in deviceTypeOptions" :key="item.value" :label="item.typeName" :value="item.deviceTypeId" />
</el-select>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable />
</el-form-item>
<el-form-item label="设备状态" prop="deviceStatus">
<el-select v-model="queryParams.deviceStatus" placeholder="设备状态" clearable>
<el-option label="正常" value="1"></el-option>
<el-option label="失效" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="设备MAC" prop="deviceMac">
<el-input v-model="queryParams.deviceMac" placeholder="请输入设备MAC" clearable />
</el-form-item>
<el-form-item label="设备IMEI" prop="deviceImei">
<el-input v-model="queryParams.deviceImei" placeholder="请输入设备IMEI" clearable @keyup.enter="handleQuery" />
</el-form-item>
<!-- <el-form-item label="使用人员" prop="personnelBy">
<el-input v-model="queryParams.personnelBy" placeholder="请输入使用人员姓名" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item label="通信方式" prop="communicationMode">
<el-select v-model="queryParams.communicationMode" placeholder="请选择通信方式" clearable>
<el-option label="4G" value="0"></el-option>
<el-option label="蓝牙" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-collapse-item>
</el-collapse>
</div>
<el-table
ref="grid"
v-loading="Status.loading"
border
:data="List"
:height="Status.showSearch.length > 0 ? 'calc(100vh - 355px)' : 'calc(100vh - 255px)'"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备图片" align="center" prop="devicePic">
<template #default="scope">
<el-popover placement="right" trigger="click">
<template #reference>
<img
:src="scope.row.devicePic"
style="width: 40px; height: 40px; cursor: pointer; object-fit: contain"
class="hover:opacity-80 transition-opacity"
/>
</template>
<img :src="scope.row.devicePic" style="max-width: 600px; max-height: 600px; object-fit: contain" />
</el-popover>
</template>
</el-table-column>
<el-table-column label="设备类型" align="center" prop="typeName" />
<el-table-column label="设备MAC" align="center" prop="deviceMac">
<template #default="scope">
<div>{{ scope.row.deviceMac || '/' }}</div>
</template>
</el-table-column>
<el-table-column label="设备IMEI" align="center" prop="deviceImei" />
<el-table-column label="使用人员" align="center" prop="personnelBy" />
<el-table-column label="设备状态" align="center" prop="onlineStatus">
<template #default="scope">
<div class="normal green" v-if="scope.row.onlineStatus == 1">在线</div>
<div class="normal red" v-if="scope.row.onlineStatus == 0">离线</div>
</template>
</el-table-column>
<el-table-column label="电量" align="center" prop="battery">
<template #default="scope">
<div
:class="{
'battery-red': Number(scope.row.battery) < 20,
'battery-yellow': Number(scope.row.battery) >= 20 && Number(scope.row.battery) < 80,
'battery-green': Number(scope.row.battery) >= 80 && Number(scope.row.battery) <= 100
}"
>
{{ scope.row.battery }}%
</div>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="ShowSingleEdit(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="pagin.total > 0"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
:total="pagin.total"
@pagination="getList"
/>
</div>
<!-- 批量给多个设备编辑弹出层 -->
<el-dialog
class=""
v-model="Status.showEditMidea"
:title="Status.currMideaType ? '编辑' + Status.currMideaType : '编辑'"
width="520"
:draggable="true"
>
<div class="MultiEditContent" v-show="Status.currMideaType != MideaType.Video" id="dropArea">
<div>
<el-icon size="36px" color="#027CFB"><Upload /></el-icon>
</div>
<div class="txt1">将文件拖到此处上传</div>
<div class="txt2">或者,您可以单击<span class="txt3" @click.stop="showCheckFile()">此处</span>选择图片</div>
<div class="txt3" @click.stop="showCheckFile()">选择图片</div>
<div class="txt2 imgPreview" v-show="checkFile.file">
<img class="img" :src="checkFile.src" />
<div class="txt">
<div>文件名:{{ checkFile.name }}</div>
<div>类型:{{ checkFile.type }}</div>
<div>大小:{{ checkFile.size }}</div>
</div>
</div>
<input type="file" id="fileInput" accept="image/*" multiple class="displayNone" />
</div>
<div class="SingEditContent Multi" v-show="Status.currMideaType == MideaType.Video">
<div class="Video item">
<div class="title">操作视频</div>
<div class="img fleft" style="width: calc(100% - 80px)">
<el-input v-model="cEdit.Video" placeholder="输入网址" />
</div>
<div class="clear"></div>
</div>
</div>
<div class="center" style="margin-top: 20px">
<el-button type="primary" @click="SaveMultiData"> 确定 </el-button>
<el-button type="primary" plain @click="CloseMultiEdit"> 取消 </el-button>
</div>
</el-dialog>
<!-- 单个个设备编辑层 -->
<el-dialog v-model="Status.ShowEditPop" title="编辑" :draggable="true" width="500px">
<div class="SingEditContent">
<div class="Boot item">
<div class="title">开机画面</div>
<div class="img">
<div class="Preview">
<img class="img" :src="cEdit.fileBoot.src" @click.stop="showCheckFile('fileBoot')" />
</div>
</div>
<div class="option center" @click.stop="showCheckFile('fileBoot')">修改</div>
<div class="clear">
<input type="file" id="fileBoot" class="displayNone" />
</div>
</div>
<div class="Param item">
<div class="title">产品参数</div>
<div class="img">
<div class="Preview">
<img v-for="(item, index) in cEdit.fileParam" class="img" :src="item.src" />
</div>
</div>
<div class="option center" @click.stop="showCheckFile('fileParam')">修改</div>
<div class="clear">
<input type="file" id="fileParam" class="displayNone" />
</div>
</div>
<div class="Oprat item">
<div class="title">操作说明</div>
<div class="img">
<div class="Preview">
<img onerror="this.style.display='none'" v-for="(item, index) in cEdit.fileOprat" class="img" :src="item.src" />
</div>
</div>
<div class="option center" @click.stop="showCheckFile('fileOprat')">修改</div>
<div class="clear">
<input type="file" id="fileOprat" class="displayNone" />
</div>
</div>
<div class="Video item">
<div class="title">操作视频</div>
<div class="img fleft" style="width: calc(100% - 80px)">
<el-input v-model="cEdit.Video" placeholder="输入网址" />
</div>
<div class="clear"></div>
</div>
</div>
<div class="center" style="margin-top: 20px">
<el-button type="primary" @click="SaveItemData"> 确定 </el-button>
<el-button type="primary" plain @click="CloseSingleEdit"> 取消 </el-button>
</div>
</el-dialog>
<!-- 提示框 -->
<el-dialog :width="300" :draggable="true" v-model="Status.confirm.Visible" :title="Status.confirm.title" center>
<span>
{{ Status.confirm.text }}
</span>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="Status.confirm.OkCallback"> 确定 </el-button>
<el-button v-show="Status.confirm.showCancel" @click="Status.confirm.cancelCallback">取消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import api from '@/api/debugCenter/debugCenter';
import common from '@/utils/common';
import apiTypeAll from '@/api/equipmentManagement/device/index';
var fileInput = document.getElementById('fileInput');
var fileInputs = {
fileBoot: null,
fileParam: null,
fileOprat: null
};
var dropArea = document.getElementById('dropArea');
enum MideaType {
Boot = '开机画面', //
Param = '产品参数',
Oprate = '操作说明',
Video = '操作视频'
}
var grid = ref(null);
//全局状态控制
var Status = reactive({
fullLoading: false, //是否显示全屏loading
loading: false, //是否显示表格区域loading
confirm: {
//弹出框的配置
Visible: false,
title: '',
text: '',
cancelCallback: null,
OkCallback: null,
showCancel: true
},
showSearch: [], //是否显示高级筛选
ShowEditPop: false, //是否显示编辑弹窗
ShowAdvanceSearch: false, //是否显示高级筛选
showEditMidea: null, //是否显示批量编辑
currMideaType: null //当前正在编辑哪种类型
});
var cEdit = reactive({
deviceId: '',
deviceImei: '',
fileBoot: { name: '', type: '', size: '', src: '', file: null },
fileParam: [],
fileOprat: [],
Video: ''
});
//页码控件数据
var pagin = reactive({
total: 0
});
//列表数据
var List = ref<any[]>(null);
var deviceTypeOptions = ref([]); //设备类型
var queryParams = reactive({
groupId: '',
pageNum: 1,
deviceId: '',
deviceName: '',
deviceStatus: '',
deviceMac: '',
deviceImei: '',
personnelBy: '',
communicationMode: '',
pageSize: 10,
deviceType: '',
content: ''
});
//选择的文件
var checkFile = reactive({ name: '', type: '', size: '', src: '', file: null });
//---------------------------------------
//显示隐藏高级查询
function showSearch() {
if (Status.showSearch.length > 0) {
Status.showSearch = [];
} else {
Status.showSearch = ['1'];
}
}
//响应查询
var queryTime = null;
function handleQuery() {
clearTimeout(queryTime);
queryTime = setTimeout(getList, 500);
}
function getList() {
Status.loading = true;
api
.getDevice(queryParams)
.then((res) => {
List.value = res.rows;
pagin.total = res.total;
})
.finally(() => {
Status.loading = false;
});
}
//重置查询条件
function resetQuery() {
let cfg = {
groupId: '',
deviceId: '',
deviceName: '',
onlineStatus: '',
deviceMac: '',
deviceImei: '',
personnelBy: '',
communicationMode: '',
deviceType: '',
content: ''
};
let keys = Object.keys(cfg);
keys.forEach((k) => {
queryParams[k] = cfg[k];
});
}
// 设备类型
const getDeviceType = () => {
apiTypeAll
.deviceTypeAll()
.then((res) => {
if (res.code == 200) {
deviceTypeOptions.value = res.data;
}
})
.catch((err) => {});
};
//获取已选中的行
var getSelectionRows = (gridInstance) => {
if (gridInstance.value) {
// 检查ref是否已正确引用组件实例
var selectedRows = gridInstance.value.getSelectionRows(); // 获取选中行数据数组
return selectedRows;
}
return [];
};
var checkrows = computed(() => {
return getSelectionRows(grid);
});
//显示上传框
function ShowMultiEdit(type: MideaType) {
let arr = getSelectionRows(grid);
if (arr.length == 0) {
return;
}
if (arr.length > 100) {
alert('最多只能选择100个设备');
return;
}
let types = common.getUniqueValues(arr, 'typeName');
if (types.length > 1) {
alert('只能选择同一设备类型的设备');
return;
}
Status.showEditMidea = true;
Status.currMideaType = type;
setTimeout(dragImgAddEvt, 500);
}
function ShowSingleEdit(item) {
Status.ShowEditPop = true;
//期待接口返回以下4个字段
cEdit.deviceId = item.id;
cEdit.deviceImei = item.deviceImei;
cEdit.Video = item.Video;
// cEdit.fileBoot.src=item.fileBoot;
// cEdit.fileOprat.src = item.fileOprat;
// cEdit.fileParam.src =item.fileParam;
api.getDeviceInfoById(item.id).then((res) => {
if (res.code == 200) {
let video = res.data.appOperationVideoVoList.find((v) => {
return v.videoUrl;
});
if (video) {
cEdit.Video = video.videoUrl;
}
let arr = res.data.appBusinessFileVoList;
cEdit.fileOprat = arr
.filter((v) => {
return v.fileType == 1;
})
.map((v) => {
return { name: v.fileName, type: '', size: '', src: v.fileUrl, file: null };
});
cEdit.fileParam = arr
.filter((v) => {
return v.fileType == 2;
})
.map((v) => {
return { name: v.fileName, type: '', size: '', src: v.fileUrl, file: null };
});
}
});
setTimeout(addFileEvt, 500);
}
function CloseSingleEdit() {
Status.ShowEditPop = false;
cEdit.Video = '';
cEdit.fileBoot = { name: '', type: '', size: '', src: '', file: null };
cEdit.fileOprat = [];
cEdit.fileParam = [];
}
//关闭上传框
function CloseMultiEdit() {
Status.showEditMidea = false;
Status.currMideaType = null;
cEdit.Video = '';
checkFile.name = '';
checkFile.size = '';
checkFile.type = '';
checkFile.file = null;
checkFile.src = null;
}
//批量给多个设备上传图片
function SaveMultiData() {
if (!checkFile.file && Status.currMideaType != MideaType.Video) {
alert('请选择要上传的图片');
return;
}
Status.fullLoading = true;
setTimeout(() => {
let promise = null;
let formData = new FormData();
let json = { videoUrl: '', deviceIds: [] };
let fileType = Status.currMideaType == MideaType.Oprate ? '1' : Status.currMideaType == MideaType.Param ? '2' : '0';
let arr = getSelectionRows(grid);
if (Status.currMideaType != MideaType.Video) {
formData.append('files', checkFile.file);
formData.append('fileType', fileType);
} else {
json = { videoUrl: cEdit.Video, deviceIds: [] };
}
arr = arr.map((v) => {
return v.id;
});
arr.forEach((element) => {
if (Status.currMideaType != MideaType.Video) {
formData.append('deviceIds', element);
} else {
json.deviceIds.push(element);
}
});
if (Status.currMideaType == MideaType.Boot) {
promise=updaeLogo(arr,checkFile.file);
} else if (Status.currMideaType == MideaType.Video) {
promise = api.addVideo(json); //操作视频
} else {
promise = api.uploadFile(formData);
}
promise
.then((res) => {
if (res.code == 200) {
CloseMultiEdit();
}
alert(res.msg);
})
.catch((ex) => {})
.finally(() => {
Status.fullLoading = false;
});
}, 0);
}
//上传开机画面
function updaeLogo(ids, file) {
if (!file || !ids) {
return Promise.resolve({ code: 200, msg: '成功' });
}
if (!Array.isArray(ids)) {
ids = [ids];
}
var formData = new FormData();
ids.forEach((element) => {
formData.append('deviceIds', element);
});
formData.append('file', file);
return api.uploadBoot(formData);
}
//保存单个设备的数据
function SaveItemData() {
if (!cEdit.fileBoot.file && !cEdit.fileParam.length && !cEdit.fileOprat.length && !cEdit.Video) {
alert('开机画面、产品参数、操作说明、操作视频四个项至少填写一项。');
return;
}
Status.fullLoading = true;
var formData = new FormData();
formData.append('deviceId', cEdit.deviceId);
formData.append('deviceImei', cEdit.deviceImei);
// formData.append("logoFile",cEdit.fileBoot.file);//开机画面
cEdit.fileParam.forEach((v) => {
if (v.file) {
formData.append('parameterFiles', v.file); //产品参数
}
});
cEdit.fileOprat.forEach((v) => {
if (v.file) {
formData.append('explanationFiles', v.file); //操作说明
}
});
formData.append('videoUrl', cEdit.Video); //操作视频
let promise1 = api.updateItem(formData);
let promise2 = updaeLogo(cEdit.deviceId, cEdit.fileBoot.file);
Promise.allSettled([promise1, promise2])
.then((res) => {
if (res[0].status == 'fulfilled' && res[1].status == 'fulfilled') {
if (res[0].code == 200 && res[1].code == 200) {
CloseSingleEdit();
alert("操作成功");
return;
}
}
alert('全部失败或部分失败');
})
.finally(() => {
Status.fullLoading = false;
});
}
//点击选择图片
function showCheckFile(type) {
if (!type) {
fileInput.click();
} else {
let dom = fileInputs[type];
if (!dom) {
dom = document.getElementById(type);
}
dom.click();
}
}
//拖拽选择
function dragImgAddEvt() {
if (dropArea) {
return;
}
fileInput = document.getElementById('fileInput');
dropArea = document.getElementById('dropArea');
// 阻止拖放的默认行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
dropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// 高亮拖放区域
['dragenter', 'dragover'].forEach((eventName) => {
dropArea.addEventListener(eventName, highlight, false);
});
// 取消高亮
['dragleave', 'drop'].forEach((eventName) => {
dropArea.addEventListener(eventName, unhighlight, false);
});
function highlight() {
dropArea.classList.add('active');
}
function unhighlight() {
dropArea.classList.remove('active');
}
// 处理文件拖放
dropArea.addEventListener('drop', handleDrop, false);
function checkMultiImgOver(res) {
let keys = Object.keys(res);
keys.forEach((k) => {
checkFile[k] = res[k];
});
}
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files).then(checkMultiImgOver);
}
fileInput.addEventListener('change', () => {
handleFiles(fileInput.files).then(checkMultiImgOver);
});
}
function addFileEvt() {
var checkImgOver = function (res, type) {
if (type == 'fileBoot') {
let keys = Object.keys(res);
keys.forEach((k) => {
cEdit[type][k] = res[k];
});
} else {
cEdit[type].push(res);
}
};
if (!fileInputs.fileBoot || !fileInputs.fileOprat || !fileInputs.fileParam) {
fileInputs.fileBoot = document.getElementById('fileBoot');
fileInputs.fileOprat = document.getElementById('fileOprat');
fileInputs.fileParam = document.getElementById('fileParam');
}
let keys = Object.keys(fileInputs);
keys.forEach((k) => {
fileInputs[k].addEventListener('change', () => {
handleFiles(fileInputs[k].files).then((res) => {
checkImgOver(res, k);
});
});
});
}
// 处理选择的文件
function handleFiles(files) {
return new Promise((resolve, reject) => {
try {
if (files.length === 0) {
reject();
return;
}
let file = files[0];
if (file.size > 10485760) {
alert('请选择10M以内的文件');
reject();
return;
}
if (file.type.indexOf('image/') == -1) {
alert('只能选择图片文件');
reject();
return;
}
let json = { file: '', name: '', type: '', size: '', src: null };
json.file = file;
json.name = file.name;
json.type = file.type.replace('image/', '');
json.size = common.formatBytes(file.size);
const reader = new FileReader();
// 读取完成后设置图片源
reader.onload = function (e) {
json.src = e.target.result; // 结果是DataURL
resolve(json);
};
reader.onerror = function (ex) {
resolve(json);
};
// 读取图片文件
reader.readAsDataURL(file);
} catch (ex) {
reject();
}
});
}
window.confirm = function (text, OK, cancel, title) {
let Cfg = {
Visible: true,
title: title ? title : '提示',
text: text ? text : '此操作不可逆,您确定这样做吗?',
OkCallback: () => {
Status.confirm.Visible = false;
if (OK) {
OK();
}
},
showCancel: true,
cancelCallback: () => {
Status.confirm.Visible = false;
if (cancel) {
cancel();
}
}
};
Status.confirm = Cfg;
};
window.alert = function (text, OK, title) {
let Cfg = {
Visible: true,
title: title ? title : '提示',
text: text ? text : '不符合规则',
OkCallback: () => {
Status.confirm.Visible = false;
if (OK) {
OK();
}
},
showCancel: false,
cancelCallback: null
};
Status.confirm = Cfg;
};
var hideConfirm = function () {
let Cfg = {
Visible: false,
title: '提示',
text: '',
cancelCallback: null,
OkCallback: null,
showCancel: false
};
Status.confirm = Cfg;
};
onMounted(() => {
getDeviceType();
getList();
});
</script>
<style lang="scss" scoped>
.fleft {
float: left;
}
.fright {
float: right;
}
.clear {
clear: both;
}
.center {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: center;
}
.displayNone {
display: none !important;
}
.content {
width: 100%;
min-height: calc(100vh - 84px);
height: calc(100vh - 84px);
background: rgba(247, 248, 252, 1);
font-size: 16px;
box-sizing: border-box;
padding: 8px 20px;
font-family: 'Microsoft YaHei';
}
.topTool {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
align-items: flex-start;
width: 100%;
border-bottom: 1px solid #e1e2e5f2;
margin-bottom: 15px;
}
.percent100 {
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0px 0px 6px 0px rgba(0, 34, 96, 0.1);
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
padding: 15px;
}
:deep .el-collapse-item__header {
display: none !important;
}
:deep .el-collapse,
:deep .el-collapse-item__wrap {
border: none !important;
}
.MultiEditContent {
height: 230px;
width: 100%;
box-sizing: border-box;
box-sizing: border-box;
border: 1px dashed rgba(56, 64, 79, 0.4);
border-radius: 4px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: center;
align-items: center;
justify-content: center;
}
#MultiEditContent.active {
border-color: #3498db;
background-color: #f0f7ff;
}
.txt1 {
color: rgba(56, 64, 79, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 700;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
.txt2 {
color: rgba(56, 64, 79, 0.6);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
.txt3 {
color: rgba(2, 124, 251, 1);
cursor: pointer;
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
.SingEditContent .item {
width: 100%;
height: 90px;
border-bottom: 1px dashed #e7e7e7;
padding: 12px 0px;
}
.Multi .item {
display: flex;
flex-direction: row;
align-content: center;
align-items: center;
justify-content: flex-start;
padding-top: 0px !important;
}
.SingEditContent .item.Video {
height: 32px;
border: none;
}
.SingEditContent .item .title {
width: 80px;
float: left;
color: rgba(56, 64, 79, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
.SingEditContent .item .img {
width: calc(100% - 110px);
float: left;
height: 100%;
}
.SingEditContent .item .option {
width: 30px;
float: left;
height: 100%;
color: rgba(2, 124, 251, 1);
cursor: pointer;
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
#dropArea.active {
border-color: #3498db;
background-color: #f0f7ff;
}
.imgPreview {
width: 100%;
height: 60px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin-top: 20px;
padding-left: 100px;
box-sizing: border-box;
}
.imgPreview .img {
width: 60px;
height: 60px;
object-fit: contain;
}
.imgPreview .txt {
padding-left: 10px;
width: calc(100% - 60px);
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.SingEditContent .Preview {
width: 100%;
height: 100%;
}
.SingEditContent .Preview .img {
height: 100%;
width: 160px;
object-fit: contain;
border-radius: 4px;
border: 1px solid #d3d5d7;
}
</style>