591 lines
21 KiB
HTML
591 lines
21 KiB
HTML
{extend name="common:base" /}
|
|
|
|
{block name="title"}{:lang('Picture management')} - {$config.site_name}{/block}
|
|
|
|
{block name="css"}
|
|
<link rel="stylesheet" href="/static/contextjs/css/context.standalone.css">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/viewerjs@1.5.0/dist/viewer.min.css">
|
|
{/block}
|
|
|
|
{block name="main"}
|
|
<div class="mdui-container-fluid">
|
|
<main>
|
|
<div class="images-container">
|
|
<div class="screen-box mdui-m-b-1">
|
|
<div class="mdui-chip">
|
|
<span class="mdui-chip-icon"><i class="mdui-icon material-icons"></i></span>
|
|
<span class="mdui-chip-title">{:lang('There are %s pictures in total', ['<small class="mdui-text-color-red num">0</small>'])}</span>
|
|
<span id="reset" class="mdui-chip-delete" mdui-tooltip="{content: '{:lang('Reset data')}', position: 'right'}"><i class="mdui-icon material-icons"></i></span>
|
|
</div>
|
|
<div class="mdui-clearfix mdui-m-t-1"></div>
|
|
<form action="" method="post" id="search-form">
|
|
<select class="operation mdui-select" name="state" mdui-select>
|
|
<option value="">{:lang('Selected items')}</option>
|
|
<option value="move">{:lang('Move')}</option>
|
|
<option value="delete">{:lang('Delete')}</option>
|
|
</select>
|
|
<div class="mdui-btn-group mdui-m-r-1 mdui-float-left">
|
|
<button type="button" id="all" class="mdui-btn mdui-ripple mdui-color-theme-accent mdui-float-right">{:lang('Select all')}</button>
|
|
</div>
|
|
<input class="mdui-textfield-input search-input mdui-float-right" type="text" name="keyword" placeholder="{:lang('Enter search...')}" value="" autocomplete="off"/>
|
|
</form>
|
|
<div class="mdui-clearfix"></div>
|
|
<ul class="breadcrumb mdui-m-t-1">
|
|
<li class="active"><a data-id="0">Home</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="mdui-divider mdui-m-b-1"></div>
|
|
<div class="mdui-row">
|
|
<div class="box mdui-row-xs-3 mdui-row-sm-9 mdui-row-md-9 mdui-row-lg-10 mdui-col-xl-12">
|
|
<div class="folders-box"></div>
|
|
<div class="images-box"></div>
|
|
</div>
|
|
</div>
|
|
<button class="mdui-btn mdui-ripple mdui-center mdui-color-grey-300 mdui-text-color-black-secondary mdui-m-t-2 more"></button>
|
|
<!-- Info Dialog -->
|
|
<div class="mdui-dialog" id="info">
|
|
<div class="mdui-dialog-title"></div>
|
|
<div class="mdui-dialog-content">
|
|
<div class="mdui-row">
|
|
<div class="mdui-col-xs-12 mdui-col-sm-3 mdui-col-md-3 mdui-col-lg-3 mdui-col-xl-3">
|
|
<img class="qrcode mdui-center" src="/static/app/images/loading.jpg" width="100%">
|
|
</div>
|
|
<div class="mdui-col-xs-12 mdui-col-sm-9 mdui-col-md-9 mdui-col-lg-9 mdui-col-xl-9">
|
|
<table>
|
|
<tbody>
|
|
<tr class="alias_name">
|
|
<td align="right">{:lang('Alias:')}</td>
|
|
<td align="left"></td>
|
|
</tr>
|
|
<tr class="url">
|
|
<td align="right">{:lang('Link:')}</td>
|
|
<td align="left">
|
|
<input class="mdui-textfield-input" type="text" placeholder="{:lang('Picture link')}" value=""/>
|
|
</td>
|
|
</tr>
|
|
<tr class="pathname">
|
|
<td align="right">{:lang('Position:')}</td>
|
|
<td align="left"></td>
|
|
</tr>
|
|
<tr class="size">
|
|
<td align="right">{:lang('Size:')}</td>
|
|
<td align="left"></td>
|
|
</tr>
|
|
<tr class="md5">
|
|
<td align="right">{:lang('MD5:')}</td>
|
|
<td align="left"></td>
|
|
</tr>
|
|
<tr class="mime">
|
|
<td align="right">{:lang('Type:')}</td>
|
|
<td align="left"></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mdui-dialog-actions">
|
|
<div class="mdui-btn-group">
|
|
<a href="" target="_blank" class="open-url mdui-btn mdui-color-theme-accent mdui-ripple mdui-btn-dense">{:lang('Open link')}</a>
|
|
<button data-clipboard-action="copy" data-clipboard-text="" class="copy-url mdui-btn mdui-color-teal mdui-ripple mdui-btn-dense">{:lang('Copy link')}</button>
|
|
<button data-id="" class="delete-image mdui-btn mdui-color-red mdui-ripple mdui-btn-dense">{:lang('Delete')}</button>
|
|
<button class="mdui-btn mdui-ripple mdui-color-grey-600 mdui-btn-dense" mdui-dialog-cancel>{:lang('Close')}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Folders Dialog -->
|
|
<div class="mdui-dialog" id="folders">
|
|
<div class="mdui-dialog-content mdui-p-a-0">
|
|
<ul class="breadcrumb">
|
|
<li class="active"><a data-id="0">Home</a></li>
|
|
</ul>
|
|
<ul class="mdui-list">
|
|
<!-- folders -->
|
|
</ul>
|
|
</div>
|
|
<div class="mdui-dialog-actions">
|
|
<button class="mdui-btn mdui-ripple" mdui-dialog-close>{:lang('Cancel')}</button>
|
|
<button class="mdui-btn mdui-ripple" mdui-dialog-confirm>{:lang('Confirm')}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
<!-- 用于右键复制 -->
|
|
<span id="copy-url" class="none copy-url" data-clipboard-action="copy" data-clipboard-text=""></span>
|
|
{/block}
|
|
|
|
{block name="js"}
|
|
<script src="/static/contextjs/js/context.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/viewerjs@1.5.0/dist/viewer.min.js"></script>
|
|
<script src="/static/jquery-viewer/1.2.0/js/jquery-viewer.js"></script>
|
|
<script>
|
|
$(function () {
|
|
|
|
var params = {},
|
|
viewer,
|
|
foldersBox = $('.folders-box'),
|
|
imagesBox = $('.images-box'),
|
|
totalBox = $('small.num'),
|
|
foldersDialog = new mdui.Dialog('.mdui-dialog#folders', {
|
|
modal: true
|
|
}),
|
|
selectedImagesId = [],
|
|
infoDialog = $(".mdui-dialog#info"),
|
|
qrcodeApi = 'https://api.wispx.cn/qrcode/generate?text=';
|
|
params.page = 1;
|
|
|
|
|
|
// 函数库
|
|
var methods = {
|
|
getData: function (options) {
|
|
params = options || params;
|
|
var more = $(".more");
|
|
more.attr('disabled', true).text(lang('Loading...'));
|
|
app.ajax("{:url('user/images')}", params, function (response) {
|
|
if (response.code) {
|
|
var images = response.data.images.data;
|
|
var folders = response.data.folders;
|
|
totalBox.text(response.data.images.total);
|
|
|
|
if (folders.length) {
|
|
for (var f = 0; f < folders.length; f++) {
|
|
foldersBox.append(
|
|
' <div class="mdui-col">' +
|
|
' <div class="item" data-id="' + folders[f].id + '" data-parent-id="' + folders[f].parent_id + '" data-name="' + folders[f].name + '">' +
|
|
' <div class="info">' +
|
|
' <img src="/static/app/images/folder.svg">' +
|
|
' </div>' +
|
|
' <p class="name">' + folders[f].name + '</p>' +
|
|
' </div>' +
|
|
'</div>'
|
|
);
|
|
}
|
|
}
|
|
if (images.length) {
|
|
for (var i = 0; i < images.length; i++) {
|
|
var filename = images[i].alias_name || images[i].name;
|
|
|
|
imagesBox.append(
|
|
'<div class="mdui-col">' +
|
|
' <div class="item" data-id="' + images[i].id + '" data-json=\'' + JSON.stringify(images[i]) + '\' title=' + filename + '>' +
|
|
' <i class="choice iconfont icon-choice"></i>' +
|
|
' <i class="info iconfont icon-info"></i>' +
|
|
' <div class="info image">' +
|
|
' <img data-original="' + images[i].url + '" src="' + images[i].url + '">' +
|
|
' </div>' +
|
|
' <p class="name">' + filename + '</p>' +
|
|
' </div>' +
|
|
'</div>');
|
|
}
|
|
|
|
// 图片预览插件
|
|
if (!viewer) {
|
|
viewer = $('.images-box').viewer({
|
|
url: 'data-original',
|
|
zIndex: 999999999
|
|
});
|
|
} else {
|
|
viewer.data('viewer').update();
|
|
}
|
|
|
|
if (response.data.images.current_page == response.data.images.last_page) {
|
|
return more.attr('disabled', true).text(lang('No more'));
|
|
}
|
|
params.page++;
|
|
return more.attr('disabled', false).text(lang('Loading more'));
|
|
} else {
|
|
more.attr('disabled', true).text(lang('No data available'));
|
|
}
|
|
}
|
|
});
|
|
},
|
|
resetData: function (options) {
|
|
foldersBox.html('');
|
|
imagesBox.html('');
|
|
methods.getData(options);
|
|
},
|
|
// 删除
|
|
delete: function (id, batch, callback) {
|
|
var msg = lang('Are you sure to delete this picture?');
|
|
if (batch) {
|
|
msg = lang('Are you sure to delete the selected picture?');
|
|
}
|
|
mdui.confirm(msg, function () {
|
|
app.request("{:url('user/deleteImages')}", {id: id}, function () {
|
|
callback && callback();
|
|
});
|
|
}, function () {
|
|
|
|
}, {confirmText: lang('Confirm'), cancelText: lang('Cancel')});
|
|
},
|
|
getFolders: function (options, openDialog, callback) {
|
|
openDialog = openDialog || false;
|
|
app.ajax("{:url('user/getFolders')}", options, function (response) {
|
|
if (response.code) {
|
|
$('#folders ul.mdui-list').html('');
|
|
var folders = response.data;
|
|
if (folders.length) {
|
|
for (var i = 0; i < folders.length; i++) {
|
|
$('#folders ul.mdui-list').append(
|
|
'<li class="mdui-list-item mdui-ripple" data-id="' + folders[i].id + '" data-parent-id="' + folders[i].parent_id + '">' +
|
|
' <i class="mdui-list-item-avatar mdui-icon material-icons"></i>' +
|
|
' <div class="mdui-list-item-content">' +
|
|
' <div class="mdui-list-item-title">' + folders[i].name + '</div>' +
|
|
' <div class="mdui-list-item-text">' + folders[i].create_time + '</div>' +
|
|
' </div>' +
|
|
'</li>'
|
|
);
|
|
}
|
|
} else {
|
|
$('#folders ul.mdui-list').html('<li class="mdui-text-center mdui-text-color-black-secondary">' + lang('Folder not found') + '</li>');
|
|
}
|
|
foldersDialog.handleUpdate();
|
|
openDialog && foldersDialog.open();
|
|
callback && callback();
|
|
}
|
|
})
|
|
}
|
|
};
|
|
|
|
methods.getData();
|
|
|
|
// 监听复制操作
|
|
var clipboard = new ClipboardJS('.copy-url');
|
|
clipboard.on('success', function(e) {
|
|
app.msg(true, lang('Copy successful'));
|
|
e.clearSelection();
|
|
});
|
|
|
|
clipboard.on('error', function(e) {
|
|
console.error('Action:', e.action);
|
|
console.error('Trigger:', e.trigger);
|
|
app.msg(false, lang('Copy failed'));
|
|
});
|
|
|
|
// Context Start
|
|
context.init({
|
|
fadeSpeed: 100,
|
|
filter: function ($obj) {},
|
|
above: 'auto',
|
|
preventDoubleContext: true,
|
|
compress: false
|
|
});
|
|
|
|
// 右键操作
|
|
$('.images-container').on('contextmenu', '.box', function(e) {
|
|
var $that = $(e.target), $item = $that.closest('.item');
|
|
if ($that.parents().hasClass('folders-box')) {
|
|
context.attach('.folders-box .item', [
|
|
{header: 'Compressed Menu'},
|
|
{text: lang('Open'), action: function (e) {
|
|
$item.click();
|
|
}
|
|
},
|
|
{text: lang('Rename'), action: function (e) {
|
|
e.preventDefault();
|
|
mdui.prompt(lang('Please enter a folder name'),
|
|
function (value) {
|
|
app.ajax("{:url('user/renameFolder')}", {
|
|
id: $item.data('id'),
|
|
parent_id: $item.data('parent-id'),
|
|
name: value
|
|
}, function (response) {
|
|
if (response.code) {
|
|
$item.attr('data-name', value).find('p.name').text(value);
|
|
return app.msg(true, response.msg);
|
|
}
|
|
mdui.alert(response.msg);
|
|
})
|
|
}
|
|
);
|
|
}
|
|
},
|
|
{divider: true},
|
|
{text: lang('Delete'), action: function (e) {
|
|
e.preventDefault();
|
|
mdui.confirm(lang('Are you sure to delete this folder?'), function() {
|
|
app.ajax("{:url('user/deleteFolder')}", {id: $item.data('id')}, function (response) {
|
|
if (response.code) {
|
|
$item.parent().remove();
|
|
return app.msg(true, response.msg);
|
|
}
|
|
mdui.alert(response.msg);
|
|
})
|
|
});
|
|
}
|
|
},
|
|
]);
|
|
} else if ($that.parents().hasClass('images-box')) {
|
|
var $item = $that.closest('.item'), data = $item.data('json');
|
|
context.attach('.images-box .item', [
|
|
{header: 'Compressed Menu'},
|
|
{text: lang('See picture'), action: function (e) {
|
|
e.preventDefault();
|
|
$item.find('img').click();
|
|
}
|
|
},
|
|
{text: lang('Open picture in new window'), href: data.url, target: '_blank'},
|
|
{divider: true},
|
|
{text: lang('Rename'), action: function (e) {
|
|
e.preventDefault();
|
|
mdui.prompt(lang('Please enter a picture name'),
|
|
function (value) {
|
|
app.ajax("{:url('user/renameImage')}", {
|
|
id: data.id,
|
|
name: value
|
|
}, function (response) {
|
|
if (response.code) {
|
|
methods.resetData();
|
|
return app.msg(true, response.msg);
|
|
}
|
|
mdui.alert(response.msg);
|
|
})
|
|
}
|
|
);
|
|
}
|
|
},
|
|
{text: lang('Copy link'), action: function (e) {
|
|
e.preventDefault();
|
|
$('#copy-url').attr('data-clipboard-text', data.url).click();
|
|
}
|
|
},
|
|
{
|
|
text: lang('Delete'), action: function (e) {
|
|
e.preventDefault();
|
|
methods.delete(data.id, false, function () {
|
|
$item.parent().remove();
|
|
totalBox.text(parseInt(totalBox.text()) - 1);
|
|
})
|
|
}
|
|
},
|
|
{
|
|
text: lang('Attribute'), action: function (e) {
|
|
e.preventDefault();
|
|
$item.find('i.info').click();
|
|
}
|
|
}
|
|
]);
|
|
} else {
|
|
context.attach('.box', [
|
|
{header: 'Compressed Menu'},
|
|
{text: lang('New folder'), action: function (e) {
|
|
e.preventDefault();
|
|
mdui.prompt(lang('Please enter a folder name'),
|
|
function (value) {
|
|
app.ajax("{:url('user/createFolder')}", {
|
|
parent_id: $('ul.breadcrumb li.active:last-child a').data('id'),
|
|
name: value
|
|
}, function (response) {
|
|
if (response.code) {
|
|
methods.resetData();
|
|
return app.msg(true, response.msg);
|
|
}
|
|
mdui.alert(response.msg);
|
|
})
|
|
}
|
|
);
|
|
}
|
|
},
|
|
{divider: true},
|
|
{text: lang('Refresh'), action: function (e) {
|
|
// e.preventDefault();
|
|
methods.resetData();
|
|
}
|
|
},
|
|
]);
|
|
}
|
|
});
|
|
|
|
// Context End
|
|
|
|
// 文件夹点击操作
|
|
$('.folders-box').on('click', '.mdui-col', function (e) {
|
|
var $that = $(e.target), $item = $that.closest('.item');
|
|
if ($item.length === 0) return false;
|
|
$('.screen-box ul.breadcrumb li:last-child').removeClass('active');
|
|
$('.screen-box ul.breadcrumb').append(
|
|
'<li class="active">' +
|
|
' <a data-id="' + $item.data('id') + '">' + $item.data('name') + '</a>' +
|
|
'</li>'
|
|
);
|
|
methods.resetData({
|
|
page: 1,
|
|
folderId: $item.data('id')
|
|
});
|
|
});
|
|
|
|
// 面包屑导航点击
|
|
$('.screen-box ul.breadcrumb').on('click', 'li:not(.active) a', function (e) {
|
|
e.preventDefault();
|
|
methods.resetData({
|
|
page: 1,
|
|
folderId: $(this).data('id')
|
|
});
|
|
$(this).parent('li').addClass('active').nextAll().remove();
|
|
});
|
|
|
|
// 模态框面包屑导航点击
|
|
$('.mdui-dialog ul.breadcrumb').on('click', 'li:not(.active) a', function (e) {
|
|
e.preventDefault();
|
|
methods.getFolders({
|
|
id: $(this).data('id')
|
|
});
|
|
$(this).parent('li').addClass('active').nextAll().remove();
|
|
});
|
|
|
|
// 模态框内文件夹点击操作
|
|
$('#folders').on('click', 'ul.mdui-list li.mdui-list-item', function (e) {
|
|
var that = this;
|
|
methods.getFolders({parentId: $(that).data('id')}, false, function () {
|
|
$('#folders ul.breadcrumb li:last-child').removeClass('active');
|
|
$('#folders ul.breadcrumb').append(
|
|
'<li class="active">' +
|
|
' <a data-id="' + $(that).data('id') + '">' + $(that).find('.mdui-list-item-title').text() + '</a>' +
|
|
'</li>'
|
|
);
|
|
});
|
|
});
|
|
|
|
// 确认移动文件夹事件
|
|
mdui.JQ('#folders').on('confirm.mdui.dialog', function (e) {
|
|
app.ajax("{:url('user/moveImages')}", {
|
|
ids: selectedImagesId,
|
|
folderId: $('#folders ul.breadcrumb li:last-child a').data('id')
|
|
}, function (response) {
|
|
if (response.code) {
|
|
methods.resetData();
|
|
return app.msg(true, response.msg);
|
|
}
|
|
mdui.alert(response.msg);
|
|
})
|
|
});
|
|
|
|
// 加载更多
|
|
$('.more').click(function () {
|
|
methods.getData();
|
|
});
|
|
|
|
// 筛选
|
|
$('.screen-box form').submit(function (e) {
|
|
e.preventDefault();
|
|
// 清空内容
|
|
foldersBox.html('')
|
|
imagesBox.html('');
|
|
params.keyword = $(this).find("input[name='keyword']").val();
|
|
params.page = 1;
|
|
methods.getData();
|
|
});
|
|
|
|
// 选中项操作
|
|
$('.screen-box .mdui-select.operation').on('close.mdui.select', function () {
|
|
if ($(this).val() !== '') {
|
|
var selected = $('.images-box .item.choice');
|
|
selectedImagesId = [];
|
|
if (selected.length) {
|
|
selected.each(function (index, value) {
|
|
selectedImagesId.push($(value).data('id'));
|
|
});
|
|
|
|
// 删除
|
|
if ('delete' === $(this).val()) {
|
|
methods.delete(selectedImagesId, true, function () {
|
|
selected.remove();
|
|
totalBox.text(parseInt(totalBox.text()) - selected.length);
|
|
// methods.getData();
|
|
});
|
|
}
|
|
|
|
// 移动
|
|
if ('move' === $(this).val()) {
|
|
methods.getFolders({parentId: $('#folders ul.breadcrumb li:last-child a').data('id')}, true);
|
|
}
|
|
|
|
} else {
|
|
app.msg(false, lang('Select at least one data!'))
|
|
}
|
|
}
|
|
});
|
|
|
|
// 全选
|
|
var all = false;
|
|
$('#all').click(function () {
|
|
var item = $('.images-box .item');
|
|
if (0 === item.length) {
|
|
return mdui.snackbar({
|
|
position: 'right-top',
|
|
message: lang('No data available!')
|
|
});
|
|
}
|
|
if (all) {
|
|
item.removeClass('choice');
|
|
$(this).text(lang('Select all'));
|
|
all = false;
|
|
} else {
|
|
item.removeClass('choice').addClass('choice');
|
|
$(this).text(lang('Deselect all'));
|
|
all = true;
|
|
}
|
|
});
|
|
|
|
// 单选
|
|
imagesBox.on('click', '.item i.choice', function () {
|
|
$(this).parent('.item').toggleClass('choice');
|
|
});
|
|
|
|
// 图片信息
|
|
var info = new mdui.Dialog('#info');
|
|
imagesBox.on('click', '.item i.info', function () {
|
|
var data = $(this).parent('.item').data('json');
|
|
if (data) {
|
|
// 标题
|
|
infoDialog.find('.mdui-dialog-title').text(data.name);
|
|
// 二维码
|
|
infoDialog.find('img.qrcode').attr('src', qrcodeApi + data.url);
|
|
// 信息
|
|
for (x in data) {
|
|
var tr = infoDialog.find('tr.' + x);
|
|
if (tr.length) {
|
|
var value = data[x];
|
|
if (x === 'size') {
|
|
value = app.bytesToSize(data[x]);
|
|
}
|
|
if (tr.find('td:last-child input').length) {
|
|
tr.find('td:last-child input').val(value);
|
|
} else {
|
|
tr.find('td:last-child').text(value);
|
|
}
|
|
}
|
|
}
|
|
// 按钮
|
|
infoDialog.find('.open-url').attr('href', data.url);
|
|
infoDialog.find('.copy-url').attr('data-clipboard-text', data.url);
|
|
infoDialog.find('.delete-image').attr('data-id', data.id);
|
|
info.open();
|
|
} else {
|
|
app.msg(false, lang('Data exception!'));
|
|
}
|
|
});
|
|
|
|
// 删除单张图片
|
|
infoDialog.find('.delete-image').click(function () {
|
|
var id = $(this).data('id');
|
|
if (id) {
|
|
info.close();
|
|
methods.delete(id, false, function () {
|
|
imagesBox.find(".item[data-id='" + id + "']").parent().remove();
|
|
totalBox.text(parseInt(totalBox.text()) - 1);
|
|
});
|
|
} else {
|
|
app.msg(false, lang('Data exception!'));
|
|
}
|
|
});
|
|
|
|
// 重置数据
|
|
$('#reset').click(function () {
|
|
methods.resetData();
|
|
});
|
|
})
|
|
</script>
|
|
{/block}
|