文件

818 行
34 KiB
HTML
可执行文件

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<!--[1.6.48]-->
<style>
.content {
font-size: 14px;
width: 100%;
padding: 10px;
box-sizing: border-box;
border-radius: 4px;
margin-bottom: 20px;
height: calc(100vh - 310px);
overflow-y: auto;
}
.list {
height: 92px;
border: 1px solid #ddd;
margin-right: 5px;
margin-bottom: 5px;
display: inline-block;
vertical-align: top;
position: relative;
cursor: default;
}
.list-img {
height: 100%;
}
.list-hover {
position: absolute;
z-index: 3;
bottom: 0;
left: 0;
overflow: hidden;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
transition: 0.3s;
display: none;
}
.list:hover > .list-hover {
display: block;
}
.list:hover > .del {
display: block;
}
.list-name {
height: 16px;
font-size: 12px;
line-height: 20px;
font-family: 宋体, Arial;
color: rgb(255, 255, 255);
text-shadow: rgb(0, 0, 0) 1px 1px;
margin: 0 8px;
overflow: hidden;
text-overflow: ellipsis;
}
.big-box {
background-color: #eee;
display: flex;
align-items: center;
justify-content: center;
}
.center {
height: 56px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.check, .checkAll {
position: absolute;
top: -1px;
left: -1px;
border: 1px solid #ddd;
width: 16px;
height: 16px;
z-index: 3;
background-color: white;
cursor: pointer;
box-sizing: border-box;
border-radius: 2px;
transition: 0.3s;
}
.check:hover, .checkAll:hover {
border-color: #409eff;
}
.checkAll {
left: 10px;
top: 2px;
}
.isChecked, .someChecked {
border-color: #409eff;
background-color: #409eff;
}
.isChecked:before {
content: '';
width: 4px;
height: 9px;
border-bottom: 2px solid white;
border-right: 2px solid white;
transform: rotateZ(45deg);
position: absolute;
top: 1px;
left: 4px;
border-radius: 2px;
}
.someChecked:before {
content: '';
width: 9px;
height: 1px;
position: absolute;
background-color: white;
top: 6px;
left: 3px;
border-radius: 2px;
}
.check-box {
position: relative;
padding-left: 32px;
font-size: 14px;
color: #333;
cursor: pointer;
}
.flex {
margin: 10px auto;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.el-upload-list--picture .el-upload-list__item-thumbnail {
width: auto;
max-width: 200px;
height: auto;
max-height: 70px;
}
.el-upload-list .el-upload-list--text {
text-align: left;
}
.tip {
font-size: 12px;
color: #606266;
margin-top: 7px;
text-align: center;
padding: 15px;
}
.top-select {
margin-bottom: 10px;
}
.left-name {
font-size: 12px;
color: #333;
}
.big-image {
max-width: 100%;
max-height: calc(100vh - 200px);
}
.cursor {
cursor: pointer;
}
.cursor:hover {
color: #409eff;
}
.progress {
position: fixed;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 20000;
}
</style>
<div id="ImageGalleryApp" v-cloak style="padding: 0">
<el-tabs v-model="activeTab" @tab-click="changeTab" type="border-card"
v-loading="loading"
element-loading-spinner="el-icon-loading">
<el-tab-pane v-for="(tab,tIndex) in tabs" :key="tIndex" :name="tab.name" :label="tab.label">
<div class="top-select">
<span class="left-name">图片来源</span>
<el-select @change="changeSelectTypeP($event,tIndex)" filterable size="small"
v-model="selectTypeP[tIndex]" placeholder="请选择图片来源">
<el-option
v-for="item in selectTypeListP[tIndex]"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-select v-if="selectTypeListC[tIndex]" @change="changeSelectTypeC($event,tIndex)" filterable
size="small"
v-model="selectTypeC[tIndex]" placeholder="请选择图片来源">
<el-option
v-for="item1 in selectTypeListC[tIndex]"
:key="item1.id"
:label="item1.name"
:value="item1.id">
</el-option>
</el-select>
<el-button type="primary" plain @click="doSearch(tIndex)" size="small">查询</el-button>
</div>
<div class="flex">
<template v-if="!isCheckDelete[tIndex]">
<if condition="$authArr['uploadImage']">
<el-button type="primary" plain
@click="doFile" size="small" icon="el-icon-upload el-icon--right">上传图片
</el-button>
<el-button v-if="allFileList[tIndex].length>0"
@click="transferStorageType='';delFileState='';showTransfer=true" size="small">一键迁移图片
</el-button>
</if>
<if condition="$authArr['delImage']">
<el-button @click="toCheck(tIndex)" size="small">批量删除
</el-button>
</if>
</template>
<template v-else>
<if condition="$authArr['delImage']">
<div class="check-box" @click="checkAll(tIndex)">
<div class="checkAll"
:class="isCheckedAll[tIndex]?'isChecked':(checkedLength[tIndex]?'someChecked':'')"></div>
<span>{{isCheckedAll[tIndex]?'取消多选':(checkedLength[tIndex]>0?'部分选中':'多选')}}<span
style="padding-left:5px;font-size: 12px;color: #666">{{checkedLength[tIndex]}}/100</span></span>
</div>
<div>
<el-button @click="toCheck(tIndex)" size="small">取消</el-button>
<el-button type="primary" @click="toDeleteMore(tIndex)" size="small" icon="el-icon-delete">
确认删除
</el-button>
</div>
</if>
</template>
</div>
<div class="content">
<div class="list" v-for="(item,index) in allFileList[tIndex]" :key="index" @click="seeBig(item)">
<img v-cloak class="list-img" :src="item.path">
<div class="list-hover">
<div class="list-name center">查看大图</div>
<div class="list-name" v-text="item.name"></div>
<div class="list-name" v-text="item.size"></div>
</div>
<div class="check" v-if="isCheckDelete[tIndex]" :class="item.checked?'isChecked':''"
@click.stop="checkItem(index,tIndex)"></div>
</div>
<div v-if="!canLoad[tIndex]&&allFileList[tIndex].length" class="tip">已显示全部</div>
<div v-else-if="canLoad[tIndex]&&allFileList[tIndex].length" class="tip cursor" @click="getData">加载更多
</div>
<div v-else-if="!allFileList[tIndex]">暂无数据</div>
</div>
</el-tab-pane>
</el-tabs>
<el-dialog :title="bigImgName" :modal-append-to-body="false" :visible.sync="showBigImage" :width="'80%'" :top="bigImgNameTop">
<div class="big-box" ref="bigImgName">
<img class="big-image" :src="bigImg">
</div>
</el-dialog>
<el-dialog :title="uploadTypeName" :modal-append-to-body="false" :visible.sync="showUpload" :width="'600px'" :before-close="closeUpload">
<div style="text-align: center">
<el-upload
class="upload-demo"
drag
action="{:U('uploadFile')}"
show-file-list
:data="uploadData"
accept="image/jpeg,image/jpg,image/png"
:on-progress="uploadFileIng"
:on-success="uploadFileSuccess"
:on-error="uploadFileError"
:limit="100"
:file-list="fileList"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将图片拖到此处上传,或<em>点击选择上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,每次最多选择100张图片</div>
</el-upload>
</div>
</el-dialog>
<el-dialog title="一键迁移图片" :modal-append-to-body="false" :visible.sync="showTransfer" :width="'80%'" :close-on-click-modal="false"
:show-close="false">
<div v-loading="transferLoading"
element-loading-text="文件迁移中,请不要关闭此网页,并耐心等待"
element-loading-spinner="el-icon-loading">
<el-form label-width="150px">
<el-form-item label="迁移至">
<el-radio :disabled="activeTab=='1'" v-model="transferStorageType" :label="1">
本地{{defaultStorageType==1?'(当前默认存储方式)':''}}
</el-radio>
<el-radio :disabled="activeTab=='2'" v-model="transferStorageType" :label="2">
七牛云{{defaultStorageType==2?'(当前默认存储方式)':''}}
</el-radio>
<el-radio :disabled="activeTab=='3'" v-model="transferStorageType" :label="3">
腾讯云{{defaultStorageType==3?'(当前默认存储方式)':''}}
</el-radio>
<el-radio :disabled="activeTab=='4'" v-model="transferStorageType" :label="4">
阿里云OSS{{defaultStorageType==4?'(当前默认存储方式)':''}}
</el-radio>
</el-form-item>
<el-form-item label="原地址图片">
<div>
<el-radio v-model="delFileState" :label="1">删除</el-radio>
<el-radio v-model="delFileState" :label="2">不删除</el-radio>
</div>
<span style="color: #999">为避免占用服务器资源,原存储位置为“本地”的建议删除,否则迁移完成之后路径将无从判断,删除将更费时</span>
</el-form-item>
<el-form-item label="原地址图片">
<div>
<el-input type="textarea" v-model="urlList" placeholder="请输入域名"></el-input>
</div>
<span style="color: #999">如您更换过当前被迁移数据存储方式的外部存储的域名(本地存储不用设置),请在此处填写曾经用过的域名及当前使用的域名,用英文逗号“,”隔开,注意:请不要写换行符,域名后请加“/”</span>
</el-form-item>
<el-form-item label="迁移须知">
<div>1. 本次迁移完成之前请勿关闭此页面,若数据量过多将会需要大量时间</div>
<div>2. 百度编辑器上传的图片,只有商户商品档案与门店商品档案能进行迁移,其余的无法进行迁移,请您谅解</div>
<div>3. 请您在网络良好、操作设备电量充足的情况下进行此操作,否则迁移中断发生迁移错误开发团队概不负责整理数据</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer" style="text-align: right">
<el-button size="small" @click="showTransfer = false">取 消</el-button>
<el-button size="small" type="primary" @click="transferToOut()">确 定</el-button>
</div>
</div>
<el-progress class="progress" v-if="progress" type="circle" :percentage="progressWidth"
color="#409EFF"></el-progress>
</el-dialog>
</div>
<script>
var ImageGalleryApp = new Vue({
el: '#ImageGalleryApp',
data: function () {
return {
tabs: [
{name: '1', label: '本地图片'},
{name: '2', label: '七牛云图片'},
{name: '3', label: '腾讯云图片'},
{name: '4', label: '阿里云图片'}
],
selectTypeListP: [{$from_class1}, {$from_class1}, {$from_class1}, {$from_class1}],
selectTypeListC: [[], [], [], []],
searchKey: '',
selectTypeP: [-1, -1, -1, -1],
selectTypeC: ['', '', '', ''],
activeTab: '1',
bigImgName: '图片名称',
showBigImage: false,
bigImg: '',
uploadTypeName: '本地上传',
showUpload: false,
fileList: [],
uploadData: {
storage_type: 1
},
isUploading: false,
page: [1, 1, 1, 1],
canLoad: [true, true, true, true],
limit: 25,
isCheckedAll: [false, false, false, false],
checkedLength: [0, 0, 0, 0],
bigImgNameTop: '0px',
allFileList: [[], [], [], []],
isCheckDelete: [false, false, false, false],
fileLength: 0,
showTransfer: false,
defaultStorageType: {$storage_type},
transferStorageType: '',
delFileState: '',
transferLoading: false,
urlList: '',
uploadCount: 0,
allUploadCount: 0,
progress: false,
progressWidth: 0,
}
},
methods: {
transferToOut: function () {
if (!this.transferStorageType) {
this.$message({
message: '请选择迁移后的存储位置',
type: 'warning'
});
return;
}
if (!this.delFileState) {
this.$message({
message: '请选择迁移后的原文件是否删除',
type: 'warning'
});
return;
}
this.transferLoading = true;
this.progressWidth = 0;
this.allUploadCount = this.allUploadCount ? this.allUploadCount : 1;
this.progress = true;
this.transfer();
},
roundNum: function (num) {
var numStr = num.toString();
var numLast = numStr.split(".");
if (numLast[1] && (numLast[1].length > 3) && numLast[1].slice(2, 6) == "4999") {
num = parseFloat(numLast[0]) + (parseFloat(numLast[1].slice(0, 2)) + 1) / 100;
}
num = Math.round(num * 100) / 100;
return num;
},
transfer: function () {
$.ajax({
url: "{:U('transferToOut')}",
type: 'post',
data: {
transfer_from: this.activeTab,
transfer_to: this.transferStorageType,
del_file_state: this.delFileState,
url_list: this.urlList,
},
success: (res) => {
if (res.status == 2) {
//还需继续迁移
this.uploadCount = parseInt(this.uploadCount) + parseInt(res.count);
this.progressWidth = this.roundNum((this.uploadCount / this.allUploadCount) * 100);
this.transfer();
} else if (res.status == 1) {
//已经迁移完毕
this.transferLoading = false;
this.page[parseInt(this.activeTab) - 1] = 1;
this.canLoad[parseInt(this.activeTab) - 1] = true;
this.progressWidth = 100;
this.$confirm(res.msg, '成功', {
closeOnClickModal: false,
confirmButtonText: '关闭',
type: 'success',
showCancelButton: false,
}).then(() => {
this.progress = false;
this.showTransfer = false;
this.getData();
}).catch(() => {
});
} else {
//迁移出错
this.progress = false;
this.transferLoading = false;
this.$confirm(res.msg, '错误', {
closeOnClickModal: false,
confirmButtonText: '关闭',
showCancelButton: false,
}).then(() => {
}).catch(() => {
});
}
}, error: (res) => {
this.transferLoading = false;
this.$confirm(JSON.stringify(res), '错误', {
closeOnClickModal: false,
confirmButtonText: '关闭',
showCancelButton: false,
}).then(() => {
}).catch(() => {
});
}
})
},
doSearch: function (tIndex) {
this.page[tIndex] = 1;
this.canLoad[tIndex] = true;
this.$nextTick(() => {
this.getData();
});
},
changeSelectTypeP: function (val, tIndex) {
if (val > 0) {
$.post("{:U('getSelectTypeC')}", {id: val}, (res) => {
if (res.status == 1) {
var selectTypeListC = JSON.parse(JSON.stringify(this.selectTypeListC));
selectTypeListC[tIndex] = res.data;
this.selectTypeListC = [];
this.selectTypeListC = selectTypeListC;
var selectTypeC = JSON.parse(JSON.stringify(this.selectTypeC));
selectTypeC[tIndex] = '';
this.selectTypeC = [];
this.selectTypeC = selectTypeC;
} else {
this.$message({
type: 'error',
message: res.msg,
duration: 1000
});
}
});
} else {
var selectTypeListC = JSON.parse(JSON.stringify(this.selectTypeListC));
selectTypeListC[tIndex] = [];
this.selectTypeListC = [];
this.selectTypeListC = selectTypeListC;
this.selectTypeC = ['', '', '', ''];
}
},
changeSelectTypeC: function (val, tIndex) {
console.log(val, tIndex);
},
doFile: function () {
switch (this.activeTab) {
case '1':
this.uploadData.storage_type = 1;
this.uploadTypeName = '上传到本地';
break;
case '2':
this.uploadData.storage_type = 2;
this.uploadTypeName = '上传到七牛云';
break;
case '3':
this.uploadData.storage_type = 3;
this.uploadTypeName = '上传到腾讯云';
break;
case '4':
this.uploadData.storage_type = 4;
this.uploadTypeName = '上传到阿里云';
break;
}
this.showUpload = true;
},
checkAll: function (tIndex) {
var isCheckedAll = JSON.parse(JSON.stringify(this.isCheckedAll));
var allFileList = JSON.parse(JSON.stringify(this.allFileList));
var checkedLength = JSON.parse(JSON.stringify(this.checkedLength));
isCheckedAll[tIndex] = !isCheckedAll[tIndex];
if (isCheckedAll[tIndex]) {
checkedLength[tIndex] = allFileList[tIndex].length;
} else {
checkedLength[tIndex] = 0;
}
var len = allFileList[tIndex].length <= 100 ? allFileList[tIndex].length : 100;
for (var i = 0; i < len; i++) {
allFileList[tIndex][i].checked = isCheckedAll[tIndex];
}
this.allFileList = [];
this.allFileList = allFileList;
this.$nextTick(() => {
this.isCheckedAll = [];
this.isCheckedAll = isCheckedAll;
this.checkedLength = [];
this.checkedLength = checkedLength;
})
},
toCheck: function (tIndex) {
var isCheckDelete = JSON.parse(JSON.stringify(this.isCheckDelete));
isCheckDelete[tIndex] = !isCheckDelete[tIndex];
this.isCheckDelete = [];
this.isCheckDelete = isCheckDelete;
},
checkItem: function (index, tIndex) {
var checkedLength = JSON.parse(JSON.stringify(this.checkedLength));
var allFileList = JSON.parse(JSON.stringify(this.allFileList));
var isCheckedAll = JSON.parse(JSON.stringify(this.isCheckedAll));
if (!allFileList[tIndex][index].checked) {
if (checkedLength[tIndex] < 100) {
allFileList[tIndex][index].checked = true;
checkedLength[tIndex] = checkedLength[tIndex] + 1;
} else {
this.$message({
type: 'warning',
message: '单次删除图片数量不能超过100个',
duration: 1000
})
}
} else {
allFileList[tIndex][index].checked = false;
checkedLength[tIndex] = checkedLength[tIndex] - 1;
}
if (checkedLength[tIndex] == allFileList[tIndex].length) {
isCheckedAll[tIndex] = true;
} else {
isCheckedAll[tIndex] = false;
}
this.allFileList = [];
this.allFileList = allFileList;
this.$nextTick(() => {
this.checkedLength = [];
this.checkedLength = checkedLength;
this.isCheckedAll = [];
this.isCheckedAll = isCheckedAll;
});
},
seeBig: function (item) {
this.bigImgName = item.name + '(大小:' + item.size + ')';
this.bigImg = item.path;
this.showBigImage = true;
var height = document.body.clientHeight | document.documentElement.clientHeight;
this.$nextTick(() => {
console.log(height, this.$refs.bigImgName.offsetHeight)
var _height = (this.$refs.bigImgName.offsetHeight + 150) / 2;
if (height > _height) {
this.bigImgNameTop = 'calc(' + (height / 2) + 'px - ' + _height + 'px)';
} else {
this.bigImgNameTop = '0px';
}
})
},
changeTab: function (val) {
// console.log(val);
if (!this.allFileList[parseInt(this.activeTab) - 1].length) {
this.getData();
}
},
uploadFileIng: function (event, file, fileList) {
this.isUploading = true;
},
uploadFileSuccess: function (response, file, fileList) {
this.isUploading = false;
if (response.status == 1) {
this.$message({
type: 'success',
message: '上传成功'
});
this.fileLength++;
if (this.fileLength == fileList.length) {
this.fileLength = 0;
var page = JSON.parse(JSON.stringify(this.page));
page[parseInt(this.activeTab) - 1] = 1;
var canLoad = JSON.parse(JSON.stringify(this.canLoad));
canLoad[parseInt(this.activeTab) - 1] = true;
this.page = [];
this.page = page;
this.canLoad = [];
this.canLoad = page;
this.$nextTick(() => {
this.getData();
})
}
} else {
this.$message({
message: response.msg,
type: 'error',
duration: 1500
});
}
},
uploadFileError: function (event, file, fileList) {
console.log(event, file, fileList)
this.isUploading = false;
this.$message({
message: '上传失败,请重试',
type: 'error',
duration: 1500
});
},
closeUpload: function () {
if (!this.isUploading) {
this.fileList = [];
this.fileLength = 0;
this.showUpload = false;
}
},
toDeleteMore: function (tIndex) {
var allFileList = JSON.parse(JSON.stringify(this.allFileList));
var isCheckedAll = this.isCheckedAll[tIndex];
var del = [];
for (var i = 0; i < allFileList[tIndex].length; i++) {
if (allFileList[tIndex][i].checked || isCheckedAll) {
del.push(allFileList[tIndex][i].id);
}
}
if (del.length) {
var text = tIndex == 0 ? '本地' : (tIndex == 1 ? '七牛云' : (tIndex == 2 ? '腾讯云' : '阿里云'));
this.$confirm('图片删除后将无法恢复,若该图片在使用中将导致显示错误,请谨慎操作!', '确认从' + text + '服务器删除选中图片?', {
confirmButtonText: '确认删除',
cancelButtonText: '取消',
type: 'warning '
}).then(() => {
this.$loading({
lock: true,
text: '加载中,请等待',
spinner: 'el-icon-loading',
background: 'rgba(255, 255, 255, 0.7)'
});
var id = del.join(',');
$.post("{:U('deleteMoreFile')}", {
id: id
}, (res) => {
if (res.status == 1) {
this.$message({
type: 'success',
message: res.msg,
duration: 1000
});
var checkedLength = JSON.parse(JSON.stringify(this.checkedLength));
checkedLength[tIndex] = 0;
this.checkedLength = [];
this.checkedLength = checkedLength;
var canLoad = JSON.parse(JSON.stringify(this.canLoad));
canLoad[tIndex] = true;
this.canLoad = [];
this.canLoad = canLoad;
var page = JSON.parse(JSON.stringify(this.page));
page[tIndex] = 1;
this.page = [];
this.page = page;
this.$nextTick(() => {
this.$loading().close();
this.getData();
})
} else {
this.$loading().close();
this.$message({
type: 'error',
message: res.msg
});
}
})
}).catch(() => {
this.$loading().close();
});
} else {
this.$message({
message: '未选择图片',
type: 'warning',
duration: 1000
});
}
},
getData: function () {
var tIndex = parseInt(this.activeTab) - 1;
if (!this.canLoad[tIndex]) {
return;
}
var page = this.page[tIndex];
// return;
this.loading = true;
$.post("{:U('getAllImages')}", {
type: this.activeTab,
page: page,
limit: this.limit,
selectTypeP: this.selectTypeP[tIndex],
selectTypeC: this.selectTypeC[tIndex]
}, (res) => {
if (res.status == 1) {
var allFileList = JSON.parse(JSON.stringify(this.allFileList));
if (page == 1) {
allFileList[tIndex] = res.list;
} else {
var list = allFileList[tIndex];
var arr = list.concat(res.list);
allFileList[tIndex] = arr;
}
this.page[tIndex] = page + 1;
this.allFileList = [];
this.allFileList = allFileList;
if (res.count) {
this.allUploadCount = parseInt(res.count);
}
this.$nextTick(() => {
this.loading = false;
var canLoad = JSON.parse(JSON.stringify(this.canLoad));
if (res.list.length == this.limit) {
canLoad[tIndex] = true;
} else {
canLoad[tIndex] = false;
}
this.canLoad = [];
this.canLoad = canLoad;
})
} else {
this.loading = false;
this.$confirm(res.msg, '提示', {
confirmButtonText: '确定',
type: 'error'
}).then(() => {
top.window.location.href = "{:U('Login/index')}"
}).cache(() => {
});
}
})
},
handleScroll: function (e) {
var scrollTop = e.target.scrollTop; //变量windowHeight是可视区的高度
var windowHeight = e.target.clientHeight; //变量scrollHeight是滚动条的总高度
var scrollHeight = e.target.scrollHeight; //滚动条到底部的条件
if (scrollTop + windowHeight == scrollHeight) {
// console.log("距顶部" + scrollTop + "可视区高度" + windowHeight + "滚动条总高度" + scrollHeight);
this.getData();
}
}
},
mounted: function () {
document.getElementsByClassName('content')[0].addEventListener('scroll', this.handleScroll, true);
document.getElementsByClassName('content')[1].addEventListener('scroll', this.handleScroll, true);
document.getElementsByClassName('content')[2].addEventListener('scroll', this.handleScroll, true);
document.getElementsByClassName('content')[3].addEventListener('scroll', this.handleScroll, true);
},
created: function () {
this.getData();
}
})
</script>
</html>