wg-basic/module-article/src/main/resources/templates/content/update.html
2023-06-16 18:05:43 +08:00

467 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#request.getContextPath() + '/'} ">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<link rel="stylesheet" href="assets/js/vendor/viewer/viewer.min.css" media="all">\
<style>
ul, ol {list-style: unset;}
ul li, ol li {list-style-type: unset;}
:root {
--ck-sample-base-spacing: 2em;
--ck-sample-color-white: #fff;
--ck-sample-color-green: #279863;
}
.document-editor #editor {
background: var(--ck-sample-color-white);
box-shadow: 2px 2px 2px rgba(0,0,0,.1);
border: 1px solid #DFE4E6;
border-bottom-color: #cdd0d2;
border-right-color: #cdd0d2;
}
.document-editor .ck.ck-editor {
box-shadow: 2px 2px 2px rgba(0,0,0,.1);
}
.document-editor .ck.ck-content {
font-size: 1em;
line-height: 1.6em;
margin-bottom: 0.8em;
min-height: 200px;
padding: 1.5em 2em;
}
/* --------- MAIN / DOCUMENT EDITOR --------------------------------------------------------------- */
.document-editor {
border: 1px solid #DFE4E6;
border-bottom-color: #cdd0d2;
border-right-color: #cdd0d2;
border-radius: 2px;
max-height: 700px;
display: flex;
flex-flow: column nowrap;
box-shadow: 2px 2px 2px rgba(0,0,0,.1);
}
.document-editor .toolbar-container {
z-index: 1;
position: relative;
box-shadow: 2px 2px 1px rgba(0,0,0,.05);
}
.document-editor .toolbar-container .ck.ck-toolbar {
border-top-width: 0;
border-left-width: 0;
border-right-width: 0;
border-radius: 0;
}
.document-editor .content-container {
padding: var(--ck-sample-base-spacing);
background: #eee;
overflow-y: scroll;
}
.document-editor .content-container #editor {
border-top-left-radius: 0;
border-top-right-radius: 0;
width: 15.8cm;
min-height: 21cm;
padding: 1cm 1cm 2cm;
margin: 0 auto;
box-shadow: 2px 2px 1px rgba(0,0,0,.05);
}
</style>
</head>
<body style="overflow: hidden;">
<div class="layui-fluid layui-anim layui-anim-fadein">
<div class="layui-card">
<div class="layui-card-header">
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
<a href="javascript:void(0);"><cite>编辑内容</cite></a>
</span>
</div>
<div class="layui-card-body" style="padding: 15px;">
<form class="layui-form layui-form-pane" lay-filter="dataForm">
<div class="layui-row layui-col-space10">
<div class="layui-col-xs8">
<div class="document-editor">
<div class="toolbar-container"></div>
<div class="content-container">
<div id="editor"></div>
<textarea id="content" name="content" style="display: none;"></textarea>
</div>
</div>
</div>
<div class="layui-col-xs4" id="prop">
<div class="layui-form-item">
<label class="layui-form-label">文章类别*</label>
<div class="layui-input-block layui-form" id="categoryIdTemplateBox" lay-filter="categoryIdTemplateBox"></div>
<script id="categoryIdTemplate" type="text/html">
<select name="categoryId" lay-verify="required" lay-search>
<option value="">选择文章类别</option>
{{# for(var i = 0, item; item = d[i++];) { }}
<option value="{{item.categoryId}}">{{item.title}}</option>
{{# } }}
</select>
</script>
</div>
<div class="layui-form-item">
<label class="layui-form-label">标题*</label>
<div class="layui-input-block">
<input type="text" id="title" name="title" class="layui-input" value="" placeholder="请输入标题" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">子标题</label>
<div class="layui-input-block">
<input type="text" id="subTitle" name="subTitle" class="layui-input" value="" placeholder="请输入子标题" >
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">概述</label>
<div class="layui-input-block">
<textarea id="summary" name="summary" class="layui-textarea" placeholder="请输入概述"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">外链地址</label>
<div class="layui-input-block">
<input type="text" id="link" name="link" class="layui-input" value="" placeholder="请输入外链地址http或https开头列表点击跳转到对应页面。">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">来源</label>
<div class="layui-input-block">
<input type="text" id="source" name="source" class="layui-input" value="" placeholder="请输入来源" >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">作者</label>
<div class="layui-input-block">
<input type="text" id="author" name="author" class="layui-input" value="" placeholder="请输入作者" >
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发布时间*</label>
<div class="layui-input-block">
<input type="text" id="publishDate" name="publishDate" class="layui-input" value="" placeholder="请选择发布时间" readonly style="cursor: pointer;" lay-verify="required">
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">是否发布*</label>
<div class="layui-input-block">
<input type="radio" name="isPublish" value="1" title="是" checked>
<input type="radio" name="isPublish" value="0" title="否">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">封面图片</label>
<div class="layui-input-block">
<input type="hidden" id="coverPhotos" name="coverPhotos">
<div class="layui-btn-container" id="coverPhotosFileBox" style="border: 1px solid #e6e6e6;"></div>
<script id="coverPhotosFileDownload" type="text/html">
{{# var fileName = 'coverPhotos'; }}
{{# if(d[fileName].length > 0) { }}
{{# var files = d[fileName];}}
{{# for(var i = 0, item = files[i]; item = files[i++];) { }}
<div class="upload-image-box">
<span class="upload-image-span">
<img src="route/file/download/false/{{item.fileId}}" align="加载失败">
</span>
<a class="layui-btn layui-btn-xs layui-btn-danger text-danger remove-image" href="javascript:void(0);" lay-form-button data-id="{{item.fileId}}" data-name="{{fileName}}" lay-filter="coverPhotosRemoveFile">
<i class="fa fa-trash-o"></i>
</a>
</div>
{{# } }}
{{# } }}
{{# if(d[fileName].length < 3) { }}
<div class="upload-image-box" style="width: auto; height: auto; padding: 5px;">
<a href="javascript:void(0);" lay-form-button data-explain="封面图片" data-name="coverPhotos" lay-filter="coverPhotosUploadFile">
<i class="fa fa-plus-square-o" style="font-size: 70px;"></i>
</a>
</div>
{{# } }}
</script>
</div>
</div>
</div>
</div>
<div class="layui-form-item layui-layout-admin">
<div class="layui-input-block">
<div class="layui-footer" style="left: 0;">
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="assets/js/vendor/ckeditor/ckeditor.js"></script>
<script src="assets/js/vendor/ckeditor/translations/zh-cn.js"></script>
<script src="assets/js/vendor/viewer/viewer.min.js"></script>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: 'assets/layuiadmin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'laydate', 'laytpl'], function(){
var $ = layui.$;
var $win = $(window);
var form = layui.form;
var laytpl = layui.laytpl;
var laydate = layui.laydate;
var contentId = top.restAjax.params(window.location.href).contentId;
var ueEditorObj = {};
var viewerObj = {};
function closeBox() {
parent.layer.close(parent.layer.getFrameIndex(window.name));
}
function resize() {
let height = $win.height();
$('.content-container').css({
height: (height - 260) + 'px',
})
$('#prop').css({
height: (height - 150) + 'px',
overflow: 'auto'
})
}
resize();
function refreshDownloadTemplet(fileName, file) {
var dataRander = {};
dataRander[fileName] = file;
laytpl(document.getElementById(fileName +'FileDownload').innerHTML).render(dataRander, function(html) {
document.getElementById(fileName +'FileBox').innerHTML = html;
});
}
// 初始化文件列表
function initFileList(fileName, ids, callback) {
var dataForm = {};
dataForm[fileName] = ids;
form.val('dataForm', dataForm);
if(!ids) {
refreshDownloadTemplet(fileName, []);
if(callback) {
callback(fileName, []);
}
return;
}
top.restAjax.get(top.restAjax.path('api/file/list', []), {
ids: ids
}, null, function(code, data) {
refreshDownloadTemplet(fileName, data);
if(callback) {
callback(fileName, data);
}
}, function(code, data) {
top.dialog.msg(data.msg);
});
}
// 初始化封面图片上传
function initCoverPhotosUploadFile() {
var files = $('#coverPhotos').val();
initFileList('coverPhotos', files, function(fileName) {
var viewer = new Viewer(document.getElementById(fileName +'FileBox'), {navbar: false});
viewerObj[fileName] = viewer;
});
form.on('button(coverPhotosUploadFile)', function(obj) {
var name = this.dataset.name;
var explain = this.dataset.explain;
top.dialog.file({
type: 'image',
title: '上传'+ explain,
width: '400px',
height: '420px',
maxFileCount: '1',
onClose: function() {
var uploadFileArray = top.dialog.dialogData.uploadFileArray;
if(typeof(uploadFileArray) != 'undefined' && uploadFileArray.length > 0) {
var files = $('#'+ name).val();
for(var j = 0, file = uploadFileArray[j]; file = uploadFileArray[j++];) {
if(files.length > 0) {
files += ',';
}
files += file.data;
}
initFileList(name, files, function(fileName) {
viewerObj[fileName].update();
});
}
}
});
});
form.on('button(coverPhotosRemoveFile)', function(obj) {
var name = this.dataset.name;
var id = this.dataset.id;
var files = $('#'+ name).val().replace(id, '');
files = files.replace(/\,+/g, ',');
if(files.charAt(0) == ',') {
files = files.substring(1);
}
if(files.charAt(files.length - 1) == ',') {
files = files.substring(0, files.length - 1);
}
initFileList(name, files, function(fileName) {
viewerObj[fileName].update();
});
});
}
// 初始化发布时间日期
function initPublishDateDate() {
laydate.render({
elem: '#publishDate',
type: 'date',
value: new Date(),
trigger: 'click'
});
}
// 初始化正文富文本
function initContentRichText(value) {
DecoupledEditor.create(document.querySelector('#editor'), {
language: 'zh-cn',
toolbar: ['undo', 'redo', '|',
'fontColor', 'fontBackgroundColor', 'highlight', '|',
'alignment', '|',
'bold', 'italic', 'link', 'blockQuote', '|',
'bulletedList', 'numberedList', '|',
'uploadImage', 'insertTable', '|',
'sourceEditing'
],
}).then(editor => {
const toolbarContainer = document.querySelector('.toolbar-container');
toolbarContainer.appendChild(editor.ui.view.toolbar.element);
editor.setData(value);
editor.model.document.on('change:data', function() {
let content = editor.getData();
$('#content').val(content);
})
editor.plugins.get("FileRepository").createUploadAdapter = function(loader) {
return {
upload: function () {
// 因为编辑器插件需要返回一个promise对象
return new Promise(function (resolve, reject) {
// 读取选中的文件
loader.file.then(function (file) {
// 我们通过formData进行图片上传
let form = new FormData();
form.append('image', file);
top.restAjax.postFile('api/file/v2/upload-image', form, null, function (code, data) {
// 定义插件返回格式
resolve({
default: 'route/file/v2/download/true/'+ data.data.fileId
});
}, function (code, data) {
reject(data.msg);
});
})
});
},
abort: function () {
// 图片删除方法可以调用后端api进行文件删除
}
}
};
}).catch(error => {
console.log(error)
});
}
// 初始化文章类别联表
function initArticleCategoryIdJoinTable(joinValue){
top.restAjax.get(top.restAjax.path('api/category/list', []), {}, null, function(code, data, args) {
laytpl(document.getElementById('categoryIdTemplate').innerHTML).render(data, function(html) {
document.getElementById('categoryIdTemplateBox').innerHTML = html;
});
form.render('select', 'categoryIdTemplateBox');
var formSelectData = {};
formSelectData['categoryId'] = joinValue;
form.val('dataForm', formSelectData);
}, function(code, data) {
top.dialog.msg(data.msg);
});
}
// 初始化内容
function initData() {
var loadLayerIndex;
top.restAjax.get(top.restAjax.path('api/content/get/{contentId}', [contentId]), {}, null, function(code, data) {
var dataFormData = {};
for(var i in data) {
dataFormData[i] = data[i] +'';
}
form.val('dataForm', dataFormData);
form.render(null, 'dataForm');
initCoverPhotosUploadFile();
initPublishDateDate();
initContentRichText(data['content']);
initArticleCategoryIdJoinTable(data['categoryId']);
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
}
initData();
// 提交表单
form.on('submit(submitForm)', function(formData) {
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.put(top.restAjax.path('api/content/update/{contentId}', [contentId]), formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
shade: 0.3,
yes: function(index) {
top.dialog.close(index);
window.location.reload();
},
btn2: function() {
closeBox();
}
});
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
});
return false;
});
$('.close').on('click', function() {
closeBox();
});
// 校验
form.verify({
});
});
</script>
</body>
</html>