yujialong 6 months ago
parent 0174ea45c0
commit 0a7e561fea
  1. 156
      src/components/editor.js
  2. 161
      src/components/img-upload/Cropper.vue
  3. 130
      src/components/modules/content.vue
  4. 291
      src/components/modules/module.vue
  5. 2717
      src/const/modules.js
  6. 32
      src/mixins/page/index.js
  7. 163
      src/pages/article/add/editor.js
  8. 933
      src/pages/article/add/index.vue
  9. 290
      src/pages/column/list/index.vue
  10. 462
      src/pages/column/page/home.vue
  11. 42
      src/pages/seo/index.vue

@ -4,10 +4,10 @@ import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
export default { export default {
//skin:'oxide-dark', //skin:'oxide-dark',
language:'zh_CN', language: 'zh_CN',
language_url: './styles/tinymce/langs/zh_CN.js', language_url: './styles/tinymce/langs/zh_CN.js',
plugins: 'print powerpaste preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template advcode codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize formatpainter paragraphspacing', plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize formatpainter paragraphspacing',
toolbar: 'code undo redo restoredraft | cut copy powerpaste pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \ toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \
styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter | paragraphspacing', table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter | paragraphspacing',
style_formats: [ style_formats: [
@ -22,40 +22,40 @@ export default {
{ {
title: '行高', title: '行高',
items: [{ items: [{
title: '1', title: '1',
styles: { styles: {
'line-height': '1' 'line-height': '1'
},
inline: 'span'
}, },
{ inline: 'span'
title: '1.5', },
styles: { {
'line-height': '1.5' title: '1.5',
}, styles: {
inline: 'span' 'line-height': '1.5'
}, },
{ inline: 'span'
title: '2', },
styles: { {
'line-height': '2' title: '2',
}, styles: {
inline: 'span' 'line-height': '2'
}, },
{ inline: 'span'
title: '2.5', },
styles: { {
'line-height': '2.5' title: '2.5',
}, styles: {
inline: 'span' 'line-height': '2.5'
}, },
{ inline: 'span'
title: '3', },
styles: { {
'line-height': '3' title: '3',
}, styles: {
inline: 'span' 'line-height': '3'
} },
inline: 'span'
}
] ]
}, },
//默认的配置 //默认的配置
@ -186,33 +186,34 @@ export default {
fontsize_formats: '12px 14px 16px 18px 19px 22px 24px 36px 48px 56px 72px', fontsize_formats: '12px 14px 16px 18px 19px 22px 24px 36px 48px 56px 72px',
font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif', font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif',
link_list: [ link_list: [
{ title: '预置链接1', value: 'http://www.tinymce.com' }, { title: '预置链接1', value: 'http://www.tinymce.com' },
{ title: '预置链接2', value: 'http://tinymce.ax-z.cn' } { title: '预置链接2', value: 'http://tinymce.ax-z.cn' }
], ],
image_list: [ image_list: [
{ title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' }, { title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' },
{ title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' } { title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' }
], ],
image_class_list: [ image_class_list: [
{ title: 'None', value: '' }, { title: 'None', value: '' },
{ title: 'Some class', value: 'class-name' } { title: 'Some class', value: 'class-name' }
], ],
//importcss_append: true, //importcss_append: true,
//自定义文件选择器的回调内容 //自定义文件选择器的回调内容
file_picker_callback: function (callback, value, meta) { file_picker_callback: function (callback, value, meta) {
if (meta.filetype === 'file') { if (meta.filetype === 'file') {
callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' }); callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' });
} }
if (meta.filetype === 'image') { if (meta.filetype === 'image') {
callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' }); callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' });
} }
if (meta.filetype === 'media') { if (meta.filetype === 'media') {
callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' }); callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' });
} }
}, },
//为内容模板插件提供预置模板 //为内容模板插件提供预置模板
templates: [ templates: [
{ title: '中文文章模板1', description: '图片文字流', content: ` {
title: '中文文章模板1', description: '图片文字流', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block"> <div class="block">
<div class="fl"> <div class="fl">
@ -235,9 +236,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '英文文章模板1', description: '图片文字流', content: ` {
title: '英文文章模板1', description: '图片文字流', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block en-block"> <div class="block en-block">
<div class="fr"> <div class="fr">
@ -254,9 +256,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '新闻模板', description: '', content: ` {
title: '新闻模板', description: '', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block" style="margin-bottom: 70px;"> <div class="block" style="margin-bottom: 70px;">
<div class="fr"> <div class="fr">
@ -284,9 +287,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '图片描述', description: '', content: ` {
title: '图片描述', description: '', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block"> <div class="block">
<div class="img-wrap"> <div class="img-wrap">
@ -295,8 +299,8 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
} }
], ],
// content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js", // content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js",
// extended_valid_elements:'script[src]', // extended_valid_elements:'script[src]',
@ -304,7 +308,7 @@ export default {
// template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]', // template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]',
// template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]', // template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]',
// autosave_ask_before_unload: false, // autosave_ask_before_unload: false,
toolbar_mode : 'wrap', toolbar_mode: 'wrap',
// automatic_uploads: true, // automatic_uploads: true,
// images_upload_base_path: '/demo', // images_upload_base_path: '/demo',
paste_data_images: true, paste_data_images: true,
@ -315,17 +319,17 @@ export default {
images_upload_handler: function (blobInfo, succFun, failFun) { images_upload_handler: function (blobInfo, succFun, failFun) {
const form = new FormData() const form = new FormData()
form.append('file', blobInfo.blob()), form.append('file', blobInfo.blob()),
Axios({ Axios({
method: 'post', method: 'post',
url: Api.upload, url: Api.upload,
data: form, data: form,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
token: Util.local.get(Setting.tokenKey) token: Util.local.get(Setting.tokenKey)
}, },
}).then(({ data }) => { }).then(({ data }) => {
succFun(data.url) succFun(data.url)
}).catch(res => {}) }).catch(res => { })
}, },
//自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发 //自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发
file_picker_callback: function (callback, value, meta) { file_picker_callback: function (callback, value, meta) {
@ -341,7 +345,7 @@ export default {
let input = document.createElement('input');//创建一个隐藏的input let input = document.createElement('input');//创建一个隐藏的input
input.setAttribute('type', 'file'); input.setAttribute('type', 'file');
input.setAttribute("accept", ".mp4"); input.setAttribute("accept", ".mp4");
input.onchange = function(){ input.onchange = function () {
let file = this.files[0]; let file = this.files[0];
let fd = new FormData(); let fd = new FormData();
fd.append("file", file); fd.append("file", file);
@ -355,16 +359,16 @@ export default {
}, },
}).then(({ data }) => { }).then(({ data }) => {
callback(data.url) callback(data.url)
}).catch(res => {}) }).catch(res => { })
} }
//触发点击 //触发点击
input.click(); input.click();
} }
}, },
// 初始化事件 // 初始化事件
setup: function(editor) { setup: function (editor) {
const that = this const that = this
editor.on('init', function(ed) { editor.on('init', function (ed) {
// 设置默认字体(新增才需要设置) // 设置默认字体(新增才需要设置)
if (editor.iframeElement.contentWindow.document.body.innerText === '\n') { if (editor.iframeElement.contentWindow.document.body.innerText === '\n') {
ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei") ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei")

@ -3,31 +3,18 @@
<div class="cropper-content"> <div class="cropper-content">
<!-- 剪裁框 --> <!-- 剪裁框 -->
<div class="cropper"> <div class="cropper">
<vueCropper ref="cropper" <vueCropper ref="cropper" :img="option.img" :output-size="option.size" :output-type="option.outputType"
:img="option.img" :info="true" :full="option.full" :can-move="option.canMove" :can-move-box="option.canMoveBox"
:output-size="option.size" :original="option.original" :auto-crop="option.autoCrop" :auto-crop-width="autoCropWidth"
:output-type="option.outputType" :auto-crop-height="autoCropHeight" :fixed-box="option.fixedBox" :fixed="fixed" :fixed-number="fixedNumber"
:info="true" @realTime="realTime" />
:full="option.full"
:can-move="option.canMove"
:can-move-box="option.canMoveBox"
:original="option.original"
:auto-crop="option.autoCrop"
:auto-crop-width="autoCropWidth"
:auto-crop-height="autoCropHeight"
:fixed-box="option.fixedBox"
:fixed="fixed"
:fixed-number="fixedNumber"
@realTime="realTime" />
<!-- <vueCropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType"></vueCropper> --> <!-- <vueCropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType"></vueCropper> -->
</div> </div>
<!-- 预览框 --> <!-- 预览框 -->
<div class="show-preview" <div class="show-preview"
:style="{'width': '500px', 'height': '400px', 'overflow': 'hidden', 'margin': '0 25px', 'display':'flex', 'align-items' : 'center'}"> :style="{ 'width': '500px', 'height': '400px', 'overflow': 'hidden', 'margin': '0 25px', 'display': 'flex', 'align-items': 'center' }">
<div :style="previews.div" <div :style="previews.div" class="preview">
class="preview"> <img :src="previews.url" :style="previews.img" />
<img :src="previews.url"
:style="previews.img" />
</div> </div>
</div> </div>
</div> </div>
@ -41,10 +28,7 @@
</div>--> </div>-->
<!-- 确认上传按钮 --> <!-- 确认上传按钮 -->
<div class="upload-btn"> <div class="upload-btn">
<el-button type="primary" <el-button type="primary" :loading="isUpload" :disabled="isDisabled" @click.prevent="uploadImg('blob')">
:loading="isUpload"
:disabled="isDisabled"
@click.prevent="uploadImg('blob')">
上传 上传
</el-button> </el-button>
</div> </div>
@ -95,7 +79,11 @@ export default {
autoCropHeight: { autoCropHeight: {
type: Number, type: Number,
default: 124 default: 124
} },
dataType: {
type: String,
default: 'form'
},
}, },
data () { data () {
return { return {
@ -114,6 +102,7 @@ export default {
fixedNumber: [1, 0.26], // (:[1:1]) fixedNumber: [1, 0.26], // (:[1:1])
enlarge: 1 enlarge: 1
}, },
imgType: this.dataType === 'form' ? 'image/png' : 'image/jpeg',
isDisabled: false isDisabled: false
} }
}, },
@ -147,9 +136,13 @@ export default {
const that = this const that = this
if (type === 'blob') { if (type === 'blob') {
this.$refs.cropper.getCropBlob(data => { this.$refs.cropper.getCropBlob(data => {
// compress(data, 1).then(res => { compress(data, {
that.$emit('upload', data) size: 100,
// }) quality: 0.9,
type: this.imgType
}).then(res => {
that.$emit('upload', res)
})
}) })
} else { } else {
this.$refs.cropper.getCropData(data => { this.$refs.cropper.getCropData(data => {
@ -162,81 +155,81 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.cropper-content { .cropper-content {
display: flex; display: flex;
display: -webkit-flex; display: -webkit-flex;
justify-content: flex-end; justify-content: flex-end;
-webkit-justify-content: flex-end; -webkit-justify-content: flex-end;
} }
.cropper-content .cropper { .cropper-content .cropper {
width: 500px; width: 500px;
height: 400px; height: 400px;
} }
.cropper-content .show-preview { .cropper-content .show-preview {
flex: 1; flex: 1;
-webkit-flex: 1; -webkit-flex: 1;
display: flex; display: flex;
display: -webkit-flex; display: -webkit-flex;
justify-content: center; justify-content: center;
-webkit-justify-content: center; -webkit-justify-content: center;
overflow: hidden; overflow: hidden;
border: 1px solid #cccccc; border: 1px solid #cccccc;
background: #cccccc; background: #cccccc;
margin-left: 40px; margin-left: 40px;
} }
.preview { .preview {
overflow: hidden; overflow: hidden;
border: 1px solid #cccccc; border: 1px solid #cccccc;
background: #cccccc; background: #cccccc;
} }
.footer-btn { .footer-btn {
margin-top: 30px; margin-top: 30px;
display: flex; display: flex;
display: -webkit-flex; display: -webkit-flex;
justify-content: flex-end; justify-content: flex-end;
-webkit-justify-content: flex-end; -webkit-justify-content: flex-end;
} }
.footer-btn .scope-btn { .footer-btn .scope-btn {
width: 500px; width: 500px;
display: flex; display: flex;
display: -webkit-flex; display: -webkit-flex;
justify-content: space-between; justify-content: space-between;
-webkit-justify-content: space-between; -webkit-justify-content: space-between;
} }
.footer-btn .upload-btn { .footer-btn .upload-btn {
flex: 1; flex: 1;
-webkit-flex: 1; -webkit-flex: 1;
display: flex; display: flex;
display: -webkit-flex; display: -webkit-flex;
justify-content: center; justify-content: center;
-webkit-justify-content: center; -webkit-justify-content: center;
} }
.footer-btn .btn { .footer-btn .btn {
outline: none; outline: none;
display: inline-block; display: inline-block;
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
-webkit-appearance: none; -webkit-appearance: none;
text-align: center; text-align: center;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
outline: 0; outline: 0;
margin: 0; margin: 0;
-webkit-transition: 0.1s; -webkit-transition: 0.1s;
transition: 0.1s; transition: 0.1s;
font-weight: 500; font-weight: 500;
padding: 8px 15px; padding: 8px 15px;
font-size: 12px; font-size: 12px;
border-radius: 3px; border-radius: 3px;
color: #fff; color: #fff;
background-color: #67c23a; background-color: #67c23a;
border-color: #67c23a; border-color: #67c23a;
} }
</style> </style>

@ -1,117 +1,64 @@
<template> <template>
<!-- 内容 --> <!-- 内容 -->
<div> <div>
<el-dialog title="编辑内容" <el-dialog title="编辑内容" :visible.sync="visible" width="700px" custom-class="module" :close-on-click-modal="false"
:visible.sync="visible" :before-close="close">
width="700px" <el-form ref="form" :model="data.form" :rules="rules" :label-width="data.labelWidth">
custom-class="module" <el-form-item v-for="(item, i) in data.forms" :key="i" :prop="item.prop" :label="item.label">
:close-on-click-modal="false" <el-input v-if="item.type === 'input'" v-model="data.form[item.prop]" placeholder="请输入"
:before-close="close"> maxlength="100"></el-input>
<el-form ref="form" <el-input v-if="item.type === 'textarea'" v-model="data.form[item.prop]" type="textarea" placeholder="请输入"
:model="data.form" maxlength="300"></el-input>
:rules="rules" <Editor v-if="item.type === 'editor'" api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda'
:label-width="data.labelWidth"> v-model="data.form[item.prop]" :init="editorConfig" />
<el-form-item v-for="(item, i) in data.forms" <el-upload v-if="item.type === 'upload' && item.width" class="uploader" accept=".jpg,.png,.jpeg,.gif"
:key="i" :on-change="res => changeFile(res, data.form)" :show-file-list="false" :action="api.upload"
:prop="item.prop" :auto-upload="false">
:label="item.label"> <img v-if="data.form[item.prop]" :src="data.form[item.prop]" class="avatar">
<el-input v-if="item.type === 'input'" <div class="uploader-default" v-else>
v-model="data.form[item.prop]"
placeholder="请输入"
maxlength="100"></el-input>
<el-input v-if="item.type === 'textarea'"
v-model="data.form[item.prop]"
type="textarea"
placeholder="请输入"
maxlength="300"></el-input>
<Editor v-if="item.type === 'editor'"
api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda'
v-model="data.form[item.prop]"
:init="editorConfig" />
<el-upload v-if="item.type === 'upload' && item.width"
class="uploader"
accept=".jpg,.png,.jpeg,.gif"
:on-change="res => changeFile(res, data.form)"
:show-file-list="false"
:action="api.upload"
:auto-upload="false">
<img v-if="data.form[item.prop]"
:src="data.form[item.prop]"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传图片</p> <p>上传图片</p>
</div> </div>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip">
<p>只支持.jpg,.png格式</p> <p>只支持.jpg,.png格式</p>
</div> </div>
</el-upload> </el-upload>
<el-upload v-if="item.type === 'upload' && !item.width" <el-upload v-if="item.type === 'upload' && !item.width" class="uploader" accept=".jpg,.png,.jpeg"
class="uploader" :on-success="res => uploadSuccess(res, data.form)" :show-file-list="false" :headers="headers"
accept=".jpg,.png,.jpeg" :action="api.upload">
:on-success="res => uploadSuccess(res, data.form)" <img v-if="data.form[item.prop]" :src="data.form[item.prop]" class="avatar">
:show-file-list="false" <div class="uploader-default" v-else>
:headers="headers"
:action="api.upload">
<img v-if="data.form[item.prop]"
:src="data.form[item.prop]"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传图片</p> <p>上传图片</p>
</div> </div>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip">
<p>只支持.jpg,.png格式</p> <p>只支持.jpg,.png格式</p>
</div> </div>
</el-upload> </el-upload>
<template v-if="item.type === 'pic'"> <template v-if="item.type === 'pic'">
<img v-if="data.form[item.prop]" <img v-if="data.form[item.prop]" :src="data.form[item.prop]" class="avatar">
:src="data.form[item.prop]" <div class="uploader-default" v-else>
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-picture-outline"></i> <i class="el-icon-picture-outline"></i>
</div> </div>
</template> </template>
<div v-if="item.type === 'link'" <div v-if="item.type === 'link'" class="flex">
class="flex"> <el-input class="m-r-10" v-model="data.form.link.linkName"></el-input>
<el-input class="m-r-10"
v-model="data.form.link.linkName"></el-input>
<el-button @click="toLink(data.form)">设置链接</el-button> <el-button @click="toLink(data.form)">设置链接</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="$emit('update:visible', false)">取消</el-button> <el-button @click="$emit('update:visible', false)">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="contentSubmit">确定</el-button>
@click="contentSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<Link ref="link" <Link ref="link" :visible.sync="linkVisible" :data.sync="linkForm" @linkSubmit="linkSubmit" />
:visible.sync="linkVisible"
:data.sync="linkForm"
@linkSubmit="linkSubmit" />
<!-- 剪裁组件弹窗 --> <!-- 剪裁组件弹窗 -->
<el-dialog title="图片裁剪" <el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false">
append-to-body <Cropper ref="cropper" :img-file.sync="file" :is-upload="isUpload" :fixed="fixed" :fixedNumber.sync="fixedNumber"
:visible.sync="cropperModel" :autoCropWidth="autoCropWidth" :autoCropHeight="autoCropHeight" :dataType="data.type" @upload="customUpload" />
width="1100px"
:close-on-click-modal="false">
<Cropper ref="cropper"
:img-file.sync="file"
:is-upload="isUpload"
:fixed="fixed"
:fixedNumber.sync="fixedNumber"
:autoCropWidth="autoCropWidth"
:autoCropHeight="autoCropHeight"
@upload="customUpload" />
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -292,11 +239,12 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.radio-wrap { .radio-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
.el-input {
width: 200px; .el-input {
margin-left: -40px; width: 200px;
} margin-left: -40px;
}
} }
</style> </style>

@ -3,283 +3,161 @@
<!-- <!--
模块type: introduce | form | forms | column | columns | history 模块type: introduce | form | forms | column | columns | history
--> -->
<el-dialog title="模块管理" <el-dialog title="模块管理" :visible.sync="visible" :width="dialogWidth" custom-class="module"
:visible.sync="visible" :close-on-click-modal="false" :before-close="close">
:width="dialogWidth"
custom-class="module"
:close-on-click-modal="false"
:before-close="close">
<template v-if="data.type === 'introduce'"> <template v-if="data.type === 'introduce'">
<el-table class="module-table" <el-table class="module-table" :data="data.list" header-align="center" row-key="id">
:data="data.list" <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
header-align="center"
row-key="id">
<el-table-column type="index"
width="60"
label="序号"
align="center"></el-table-column>
<el-table-column v-for="(item, i) in data.forms" <el-table-column v-for="(item, i) in data.forms" :key="i" :prop="item.prop" :label="item.label"
:key="i" min-width="130" align="center">
:prop="item.prop"
:label="item.label"
min-width="130"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-if="item.type === 'link' && scope.row.link" <div v-if="item.type === 'link' && scope.row.link" class="link-wrap">
class="link-wrap">
<span>{{ scope.row.link.linkName }}</span> <span>{{ scope.row.link.linkName }}</span>
</div> </div>
<template v-else-if="item.type === 'upload'"> <template v-else-if="item.type === 'upload'">
<img v-if="scope.row.pic" <img v-if="scope.row.pic" :src="scope.row.pic" class="upload-pic">
:src="scope.row.pic" <div class="upload-none" v-else>
class="upload-pic">
<div class="upload-none"
v-else>
<i class="el-icon-picture-outline"></i> <i class="el-icon-picture-outline"></i>
</div> </div>
</template> </template>
<div v-else-if="item.type === 'editor'" v-html="scope.row[item.prop]"></div> <div v-else-if="item.type === 'editor'" v-html="scope.row[item.prop]"></div>
<p v-else>{{ scope.row[item.prop] }}</p> <p v-else>{{ scope.row[item.prop] }}</p>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" :width="data.sort ? 150 : 100" align="center">
:width="data.sort ? 150 : 100"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex a-center"> <div class="flex a-center">
<el-switch v-model="scope.row.isEnable" <el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0">
:active-value="1"
:inactive-value="0">
</el-switch> </el-switch>
<i class="el-icon-edit-outline del" <i class="el-icon-edit-outline del" @click="editIntro(scope.row, scope.$index)"></i>
@click="editIntro(scope.row, scope.$index)"></i>
<template v-if="data.sort"> <template v-if="data.sort">
<i v-if="scope.$index != data.list.length - 1" <i v-if="scope.$index != data.list.length - 1" class="el-icon-bottom del"
class="el-icon-bottom del" @click="sort(1, scope.$index)"></i>
@click="sort(1, scope.$index)"></i> <i v-if="scope.$index" class="el-icon-top del" @click="sort(0, scope.$index)"></i>
<i v-if="scope.$index"
class="el-icon-top del"
@click="sort(0, scope.$index)"></i>
</template> </template>
<i class="el-icon-delete del" <i class="el-icon-delete del" @click="delRow(data.list, scope.$index)"></i>
@click="delRow(data.list, scope.$index)"></i>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="plus"> <div class="plus">
<i class="el-icon-circle-plus-outline" <i class="el-icon-circle-plus-outline" @click="addRow"></i>
@click="addRow"></i>
</div> </div>
</template> </template>
<el-form v-else-if="data.type === 'form' || data.type === 'forms'" <el-form v-else-if="data.type === 'form' || data.type === 'forms'" ref="form" :model="data.form" :rules="rules"
ref="form" :label-width="data.labelWidth">
:model="data.form" <el-form-item v-for="(item, i) in data.forms" :key="i" :prop="item.prop" :label="item.label">
:rules="rules" <el-input v-if="item.type === 'input'" v-model="data.form[item.prop]" placeholder="请输入"
:label-width="data.labelWidth"> maxlength="100"></el-input>
<el-form-item v-for="(item, i) in data.forms" <el-input v-if="item.type === 'textarea'" v-model="data.form[item.prop]" type="textarea" placeholder="请输入"
:key="i" maxlength="300"></el-input>
:prop="item.prop" <div v-if="item.type === 'upload' || item.type === 'video' || item.type === 'media'" class="uploader-wrap">
:label="item.label"> <el-upload v-if="item.type === 'upload'" class="uploader" accept=".jpg,.png,.jpeg,.gif"
<el-input v-if="item.type === 'input'" :on-change="res => changeFile(res, data.form)" :show-file-list="false" :headers="headers"
v-model="data.form[item.prop]" :action="api.upload">
placeholder="请输入" <img v-if="data.form.pic && !isVideo(data.form.mediaType)" :src="data.form.pic" class="avatar">
maxlength="100"></el-input> <div class="uploader-default" v-else>
<el-input v-if="item.type === 'textarea'"
v-model="data.form[item.prop]"
type="textarea"
placeholder="请输入"
maxlength="300"></el-input>
<div v-if="item.type === 'upload' || item.type === 'video' || item.type === 'media'"
class="uploader-wrap">
<el-upload v-if="item.type === 'upload'"
class="uploader"
accept=".jpg,.png,.jpeg,.gif"
:on-change="res => changeFile(res, data.form)"
:show-file-list="false"
:headers="headers"
:action="api.upload">
<img v-if="data.form.pic && !isVideo(data.form.mediaType)"
:src="data.form.pic"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传图片</p> <p>上传图片</p>
</div> </div>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip">
<p>只支持.jpg,.png格式</p> <p>只支持.jpg,.png格式</p>
</div> </div>
</el-upload> </el-upload>
<el-upload v-if="item.type === 'video'" <el-upload v-if="item.type === 'video'" accept=".mp4,.mov,.avi"
accept=".mp4,.mov,.avi" :on-success="res => uploadSuccess(res, data.form, item)" :before-remove="beforeRemove"
:on-success="res => uploadSuccess(res, data.form, item)" :on-remove="(file, fileList) => handleRemove(file, fileList, data.form, item.prop)" :file-list="fileList"
:before-remove="beforeRemove" :headers="headers" :action="api.upload">
:on-remove="(file, fileList) => handleRemove(file, fileList, data.form, item.prop)"
:file-list="fileList"
:headers="headers"
:action="api.upload">
<el-button>上传视频</el-button> <el-button>上传视频</el-button>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip">
<p>请上传大小1G以内的视频</p> <p>请上传大小1G以内的视频</p>
</div> </div>
</el-upload> </el-upload>
<!-- 图片视频都可上传 --> <!-- 图片视频都可上传 -->
<el-upload v-if="item.type === 'media'" <el-upload v-if="item.type === 'media'" :on-success="res => uploadSuccess(res, data.form, item)"
:on-success="res => uploadSuccess(res, data.form, item)" :before-remove="beforeRemove"
:before-remove="beforeRemove" :on-remove="(file, fileList) => handleRemove(file, fileList, data.form, item.prop)" :file-list="fileList"
:on-remove="(file, fileList) => handleRemove(file, fileList, data.form, item.prop)" :headers="headers" :action="api.upload">
:file-list="fileList"
:headers="headers"
:action="api.upload">
<el-button>上传资源</el-button> <el-button>上传资源</el-button>
</el-upload> </el-upload>
<i v-if="!item.required" <i v-if="!item.required" class="el-icon-delete del" @click="data.form[item.prop] = ''"></i>
class="el-icon-delete del"
@click="data.form[item.prop] = ''"></i>
</div> </div>
<div v-if="item.type === 'link'" <div v-if="item.type === 'link'" class="flex">
class="flex"> <el-input class="m-r-10" v-model="data.form.link.linkName"></el-input>
<el-input class="m-r-10"
v-model="data.form.link.linkName"></el-input>
<el-button @click="toLink(data.form)">设置链接</el-button> <el-button @click="toLink(data.form)">设置链接</el-button>
</div> </div>
<Editor v-if="item.type === 'editor'" <Editor v-if="item.type === 'editor'" api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda'
api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' v-model="data.form[item.prop]" :init="editorConfig" />
v-model="data.form[item.prop]"
:init="editorConfig" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-else-if="data.type === 'column' || data.type === 'columns'" <el-form v-else-if="data.type === 'column' || data.type === 'columns'" ref="form" :model="data.form"
ref="form" :rules="columnRules" label-width="100px">
:model="data.form" <el-form-item prop="site" label="站点选择">
:rules="columnRules" <el-select v-model="data.form.site" @change="siteChange">
label-width="100px"> <el-option v-for="item in $refs.link.sites" :key="item.id" :label="item.siteName" :value="item.id">
<el-form-item prop="site"
label="站点选择">
<el-select v-model="data.form.site"
@change="siteChange">
<el-option v-for="item in $refs.link.sites"
:key="item.id"
:label="item.siteName"
:value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="column" <el-form-item prop="column" label="关联栏目">
label="关联栏目"> <el-cascader ref="links" v-model="data.form.column" :options="columns" :props="columnProps" clearable
<el-cascader ref="links" @change="columnChange"></el-cascader>
v-model="data.form.column"
:options="columns"
:props="columnProps"
clearable
@change="columnChange"></el-cascader>
</el-form-item> </el-form-item>
<el-form-item label="文章展示数量"> <el-form-item label="文章展示数量">
<el-select v-model="data.form.articleNum"> <el-select v-model="data.form.articleNum">
<el-option v-for="item in articleNums" <el-option v-for="item in articleNums" :key="item.id" :label="item.name" :value="item.id">
:key="item.id"
:label="item.name"
:value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="栏目标题"> <el-form-item label="栏目标题">
<el-radio v-model="data.form.columnTitle" <el-radio v-model="data.form.columnTitle" :label="1" @change="columnTitleChange">默认读取关联栏目</el-radio>
:label="1"
@change="columnTitleChange">默认读取关联栏目</el-radio>
<div class="radio-wrap"> <div class="radio-wrap">
<el-radio v-model="data.form.columnTitle" <el-radio v-model="data.form.columnTitle" :label="2" @change="columnTitleChange"></el-radio>
:label="2" <el-input v-model="data.form.columnTitleCustom" :disabled="data.form.columnTitle == 1" size="small"
@change="columnTitleChange"></el-radio> maxlength="100"></el-input>
<el-input v-model="data.form.columnTitleCustom"
:disabled="data.form.columnTitle == 1"
size="small"
maxlength="100"></el-input>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template v-else-if="data.type === 'history'"> <template v-else-if="data.type === 'history'">
<el-table class="module-table" <el-table class="module-table" :data="data.list" header-align="center" row-key="id">
:data="data.list" <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
header-align="center" <el-table-column prop="title" label="标题" min-width="140" align="center">
row-key="id">
<el-table-column type="index"
width="60"
label="序号"
align="center"></el-table-column>
<el-table-column prop="title"
label="标题"
min-width="140"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model="scope.row.title" <el-input v-model="scope.row.title" placeholder="请输入" maxlength="100"></el-input>
placeholder="请输入"
maxlength="100"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" width="100" align="center">
width="100"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex a-center"> <div class="flex a-center">
<el-switch v-model="scope.row.isEnable" <el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0">
:active-value="1"
:inactive-value="0">
</el-switch> </el-switch>
<i class="el-icon-edit-outline del" <i class="el-icon-edit-outline del" @click="editHistory(scope.row, scope.$index)"></i>
@click="editHistory(scope.row, scope.$index)"></i> <i class="el-icon-delete del" @click="delRow(data.list, scope.$index)"></i>
<i class="el-icon-delete del"
@click="delRow(data.list, scope.$index)"></i>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="plus"> <div class="plus">
<i class="el-icon-circle-plus-outline" <i class="el-icon-circle-plus-outline" @click="addRow"></i>
@click="addRow"></i>
</div> </div>
</template> </template>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="$emit('update:visible', false)">取消</el-button> <el-button @click="$emit('update:visible', false)">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="moduleSubmit">确定</el-button>
@click="moduleSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<Link ref="link" <Link ref="link" :data.sync="linkForm" :visible.sync="linkVisible" @linkSubmit="linkSubmit" />
:data.sync="linkForm" <Content :data.sync="data" :visible.sync="contentVisible" @contentSubmit="contentSubmit" />
:visible.sync="linkVisible" <History :data.sync="data" :list.sync="historyData" :form.sync="data.form" :visible.sync="historyVisible"
@linkSubmit="linkSubmit" /> @historySubmit="historySubmit" />
<Content :data.sync="data"
:visible.sync="contentVisible"
@contentSubmit="contentSubmit" />
<History :data.sync="data"
:list.sync="historyData"
:form.sync="data.form"
:visible.sync="historyVisible"
@historySubmit="historySubmit" />
<!-- 剪裁组件弹窗 --> <!-- 剪裁组件弹窗 -->
<el-dialog title="图片裁剪" <el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false">
append-to-body <Cropper ref="cropper" :img-file.sync="file" :is-upload="isUpload" :fixed="fixed" :fixedNumber.sync="fixedNumber"
:visible.sync="cropperModel" :autoCropWidth="autoCropWidth" :autoCropHeight="autoCropHeight" :dataType="data.type" @upload="customUpload" />
width="1100px"
:close-on-click-modal="false">
<Cropper ref="cropper"
:img-file.sync="file"
:is-upload="isUpload"
:fixed="fixed"
:fixedNumber.sync="fixedNumber"
:autoCropWidth="autoCropWidth"
:autoCropHeight="autoCropHeight"
@upload="customUpload" />
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -432,7 +310,7 @@ export default {
this.articleNums = nums this.articleNums = nums
} }
form && form.site && this.siteChange(form.site) form && form.site && this.siteChange(form.site)
this.dialogWidth = dialogWidth || '800px' this.dialogWidth = dialogWidth || '1000px'
}, },
// //
siteChange (siteId) { siteChange (siteId) {
@ -651,11 +529,12 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.radio-wrap { .radio-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
.el-input {
width: 200px; .el-input {
margin-left: -40px; width: 200px;
} margin-left: -40px;
}
} }
</style> </style>

File diff suppressed because it is too large Load Diff

@ -3,7 +3,7 @@ import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import { Loading } from 'element-ui' import { Loading } from 'element-ui'
export default { export default {
data() { data () {
return { return {
userId: +this.$store.state.user.userId, userId: +this.$store.state.user.userId,
site: this.$store.state.content.site, site: this.$store.state.content.site,
@ -23,7 +23,7 @@ export default {
Module, Module,
}, },
// 页面离开的时候如果没有保存则提示 // 页面离开的时候如果没有保存则提示
beforeRouteLeave(to, from, next) { beforeRouteLeave (to, from, next) {
// 更改了信息才需要提示 // 更改了信息才需要提示
if (!this.pass && this.modules.length && this.originModules !== JSON.stringify(this.modules)) { if (!this.pass && this.modules.length && this.originModules !== JSON.stringify(this.modules)) {
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', {
@ -38,12 +38,12 @@ export default {
next() next()
} }
}, },
mounted() { mounted () {
this.getInfo() this.getInfo()
}, },
methods: { methods: {
// 获取详情 // 获取详情
getInfo() { getInfo () {
const siteId = this.$store.state.content.site.id const siteId = this.$store.state.content.site.id
this.modules.map(e => { this.modules.map(e => {
const { type, list, form } = e const { type, list, form } = e
@ -73,8 +73,8 @@ export default {
const list = JSON.parse(str) const list = JSON.parse(str)
this.modules.map((e, i) => { this.modules.map((e, i) => {
e.form = list[i].form e.form = list[i].form
if (list[i].list) e.list = list[i].list if (list[i].list) e.list = list[i].list
if (this.withOriginForm.includes(e.type) && !e.originForm) { if (this.withOriginForm.includes(e.type) && !e.originForm) {
e.originForm = modules[i].originForm e.originForm = modules[i].originForm
} }
@ -82,10 +82,10 @@ export default {
this.originModules = JSON.stringify(this.modules) // 原始json,用以页面离开的时候判断是否需要提示保存 this.originModules = JSON.stringify(this.modules) // 原始json,用以页面离开的时候判断是否需要提示保存
console.log("🚀 ~ file: index.js:85 ~ this.$post ~ list:", this.modules) console.log("🚀 ~ file: index.js:85 ~ this.$post ~ list:", this.modules)
} }
}).catch(err => {}) }).catch(err => { })
}, },
// 展开模块设置 // 展开模块设置
toSet(i, listIndex) { toSet (i, listIndex) {
this.curModule = i this.curModule = i
this.curData = JSON.parse(JSON.stringify(this.modules[i])) this.curData = JSON.parse(JSON.stringify(this.modules[i]))
@ -97,7 +97,7 @@ export default {
this.diaVisible = true this.diaVisible = true
}, },
// 模块设置提交 // 模块设置提交
moduleSubmited() { moduleSubmited () {
this.diaVisible = false this.diaVisible = false
const { type } = this.curData const { type } = this.curData
if (type === 'columns' || type === 'forms') { if (type === 'columns' || type === 'forms') {
@ -109,7 +109,7 @@ export default {
} }
}, },
// 模块设置提交验证 // 模块设置提交验证
moduleSubmit() { moduleSubmit () {
const formEle = this.$refs.module.$refs.form const formEle = this.$refs.module.$refs.form
// 有表单的要验证必填,没有的直接关闭弹框 // 有表单的要验证必填,没有的直接关闭弹框
if (formEle) { if (formEle) {
@ -121,11 +121,11 @@ export default {
} }
}, },
// 处理预览和保存的json // 处理预览和保存的json
handleJson() { handleJson () {
return JSON.stringify(this.modules) return JSON.stringify(this.modules)
}, },
// 预览 // 预览
preview() { preview () {
const load = Loading.service() const load = Loading.service()
this.$post(this.api.saveRedisPage, { this.$post(this.api.saveRedisPage, {
columnId: this.columnId, columnId: this.columnId,
@ -138,7 +138,7 @@ export default {
}) })
}, },
// 保存 // 保存
save(state, leave) { save (state, leave) {
const json = this.handleJson() const json = this.handleJson()
const data = { const data = {
id: this.id, id: this.id,
@ -152,12 +152,12 @@ export default {
if (state) data.theEditedJson = json if (state) data.theEditedJson = json
this.$post(this.api[this.id ? 'updatePage' : 'savePage'], data).then(res => { this.$post(this.api[this.id ? 'updatePage' : 'savePage'], data).then(res => {
this.originModules = json this.originModules = json
Util.successMsg((state ? '发布' : '保存') + '成功') Util.successMsg((state ? '发布' : '保存') + '成功')
leave || this.$router.back() leave || this.$router.back()
}).catch(err => {}) }).catch(err => { })
}, },
// 返回 // 返回
back() { back () {
this.pass = true this.pass = true
// 更改了信息才需要提示 // 更改了信息才需要提示
if (this.originModules !== JSON.stringify(this.modules)) { if (this.originModules !== JSON.stringify(this.modules)) {

@ -4,10 +4,10 @@ import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
export default { export default {
//skin:'oxide-dark', //skin:'oxide-dark',
language:'zh_CN', language: 'zh_CN',
language_url: './styles/tinymce/langs/zh_CN.js', language_url: './styles/tinymce/langs/zh_CN.js',
plugins: 'print powerpaste preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template advcode codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize formatpainter', plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize formatpainter',
toolbar: 'code undo redo restoredraft | cut copy powerpaste pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \ toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \
styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter', table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter',
style_formats: [ style_formats: [
@ -22,40 +22,40 @@ export default {
{ {
title: '行高', title: '行高',
items: [{ items: [{
title: '1', title: '1',
styles: { styles: {
'line-height': '1' 'line-height': '1'
},
inline: 'span'
}, },
{ inline: 'span'
title: '1.5', },
styles: { {
'line-height': '1.5' title: '1.5',
}, styles: {
inline: 'span' 'line-height': '1.5'
}, },
{ inline: 'span'
title: '2', },
styles: { {
'line-height': '2' title: '2',
}, styles: {
inline: 'span' 'line-height': '2'
}, },
{ inline: 'span'
title: '2.5', },
styles: { {
'line-height': '2.5' title: '2.5',
}, styles: {
inline: 'span' 'line-height': '2.5'
}, },
{ inline: 'span'
title: '3', },
styles: { {
'line-height': '3' title: '3',
}, styles: {
inline: 'span' 'line-height': '3'
} },
inline: 'span'
}
] ]
}, },
//默认的配置 //默认的配置
@ -188,33 +188,34 @@ export default {
fontsize_formats: '12px 14px 16px 19px 24px 36px 48px 56px 72px', fontsize_formats: '12px 14px 16px 19px 24px 36px 48px 56px 72px',
font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif', font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif',
link_list: [ link_list: [
{ title: '预置链接1', value: 'http://www.tinymce.com' }, { title: '预置链接1', value: 'http://www.tinymce.com' },
{ title: '预置链接2', value: 'http://tinymce.ax-z.cn' } { title: '预置链接2', value: 'http://tinymce.ax-z.cn' }
], ],
image_list: [ image_list: [
{ title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' }, { title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' },
{ title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' } { title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' }
], ],
image_class_list: [ image_class_list: [
{ title: 'None', value: '' }, { title: 'None', value: '' },
{ title: 'Some class', value: 'class-name' } { title: 'Some class', value: 'class-name' }
], ],
//importcss_append: true, //importcss_append: true,
//自定义文件选择器的回调内容 //自定义文件选择器的回调内容
file_picker_callback: function (callback, value, meta) { file_picker_callback: function (callback, value, meta) {
if (meta.filetype === 'file') { if (meta.filetype === 'file') {
callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' }); callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' });
} }
if (meta.filetype === 'image') { if (meta.filetype === 'image') {
callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' }); callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' });
} }
if (meta.filetype === 'media') { if (meta.filetype === 'media') {
callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' }); callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' });
} }
}, },
//为内容模板插件提供预置模板 //为内容模板插件提供预置模板
templates: [ templates: [
{ title: '中文文章模板1', description: '图片文字流', content: ` {
title: '中文文章模板1', description: '图片文字流', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block"> <div class="block">
<div class="fl"> <div class="fl">
@ -237,9 +238,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '英文文章模板1', description: '图片文字流', content: ` {
title: '英文文章模板1', description: '图片文字流', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block en-block"> <div class="block en-block">
<div class="fr"> <div class="fr">
@ -256,9 +258,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '新闻模板', description: '', content: ` {
title: '新闻模板', description: '', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block" style="margin-bottom: 70px;"> <div class="block" style="margin-bottom: 70px;">
<div class="fr"> <div class="fr">
@ -286,9 +289,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '图片描述', description: '', content: ` {
title: '图片描述', description: '', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="block"> <div class="block">
<div class="img-wrap"> <div class="img-wrap">
@ -297,9 +301,10 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
}, },
{ title: '人物详情', description: '', content: ` {
title: '人物详情', description: '', content: `
<div class="tiny-wrap"> <div class="tiny-wrap">
<div class="people"> <div class="people">
<img class="pic" src="http://139.159.254.212/images/team/5.png"/> <img class="pic" src="http://139.159.254.212/images/team/5.png"/>
@ -374,8 +379,8 @@ export default {
</div> </div>
</div> </div>
</div> </div>
` `
} }
], ],
// content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js", // content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js",
// extended_valid_elements:'script[src]', // extended_valid_elements:'script[src]',
@ -383,7 +388,7 @@ export default {
// template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]', // template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]',
// template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]', // template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]',
// autosave_ask_before_unload: false, // autosave_ask_before_unload: false,
toolbar_mode : 'wrap', toolbar_mode: 'wrap',
// automatic_uploads: true, // automatic_uploads: true,
// images_upload_base_path: '/demo', // images_upload_base_path: '/demo',
// images_upload_url: 'http://139.159.254.212:10000/iasf/sysFiles/upload', // images_upload_url: 'http://139.159.254.212:10000/iasf/sysFiles/upload',
@ -395,17 +400,17 @@ export default {
images_upload_handler: function (blobInfo, succFun, failFun) { images_upload_handler: function (blobInfo, succFun, failFun) {
const form = new FormData() const form = new FormData()
form.append('file', blobInfo.blob()), form.append('file', blobInfo.blob()),
Axios({ Axios({
method: 'post', method: 'post',
url: Api.upload, url: Api.upload,
data: form, data: form,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
token: Util.local.get(Setting.tokenKey) token: Util.local.get(Setting.tokenKey)
}, },
}).then(({ data }) => { }).then(({ data }) => {
succFun(data.url) succFun(data.url)
}).catch(res => {}) }).catch(res => { })
}, },
//自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发 //自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发
file_picker_callback: function (callback, value, meta) { file_picker_callback: function (callback, value, meta) {
@ -421,7 +426,7 @@ export default {
let input = document.createElement('input');//创建一个隐藏的input let input = document.createElement('input');//创建一个隐藏的input
input.setAttribute('type', 'file'); input.setAttribute('type', 'file');
input.setAttribute("accept", ".mp4"); input.setAttribute("accept", ".mp4");
input.onchange = function(){ input.onchange = function () {
let file = this.files[0]; let file = this.files[0];
let fd = new FormData(); let fd = new FormData();
fd.append("file", file); fd.append("file", file);
@ -435,16 +440,16 @@ export default {
}, },
}).then(({ data }) => { }).then(({ data }) => {
callback(data.url) callback(data.url)
}).catch(res => {}) }).catch(res => { })
} }
//触发点击 //触发点击
input.click(); input.click();
} }
}, },
// 初始化事件 // 初始化事件
setup: function(editor) { setup: function (editor) {
const that = this const that = this
editor.on('init', function(ed) { editor.on('init', function (ed) {
// 设置默认字体(新增才需要设置) // 设置默认字体(新增才需要设置)
if (editor.iframeElement.contentWindow.document.body.innerText === '\n') { if (editor.iframeElement.contentWindow.document.body.innerText === '\n') {
ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei") ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei")

File diff suppressed because it is too large Load Diff

@ -2,185 +2,107 @@
<div class="page"> <div class="page">
<div class="tool"> <div class="tool">
<div class="search-wrap"> <div class="search-wrap">
<el-input placeholder="请输入栏目名称" <el-input placeholder="请输入栏目名称" v-model.trim="keyword" clearable></el-input>
v-model.trim="keyword"
clearable></el-input>
</div> </div>
<div class="actions"> <div class="actions">
<el-dropdown class="setting" <el-dropdown class="setting" trigger="click" :hide-on-click="false">
trigger="click" <img class="icon" src="@/assets/images/setting.png" alt="">
:hide-on-click="false">
<img class="icon"
src="@/assets/images/setting.png"
alt="">
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item> <el-dropdown-item>
<el-button @click="resetColumns" <el-button @click="resetColumns" type="text">列重置</el-button>
type="text">列重置</el-button>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item v-for="(column, i) in settings" <el-dropdown-item v-for="(column, i) in settings" :key="i" :divided="i === 0">
:key="i"
:divided="i === 0">
<el-checkbox v-model="column.show">{{ column.name }}</el-checkbox> <el-checkbox v-model="column.show">{{ column.name }}</el-checkbox>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:新增'" <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:新增'" type="primary" @click="add">新增</el-button>
type="primary" <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:删除'" @click="batchDel">删除</el-button>
@click="add">新增</el-button> <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:更改排序'" class="lg" @click="sort">更改排序</el-button>
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:删除'" <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:导航样式设置'" class="lg"
@click="batchDel">删除</el-button> @click="styleSet">导航样式设置</el-button>
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:更改排序'"
class="lg"
@click="sort">更改排序</el-button>
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:导航样式设置'"
class="lg"
@click="styleSet">导航样式设置</el-button>
</div> </div>
</div> </div>
<el-table v-loading="listLoading" <el-table v-loading="listLoading" ref="table" :data="list" default-expand-all class="table" header-align="center"
ref="table" @selection-change="handleSelectionChange" @select-all="selectAll" row-key="id">
:data="list" <el-table-column v-if="settings[0].show" type="selection" width="50" align="center"
default-expand-all :reserve-selection="true"></el-table-column>
class="table" <el-table-column prop="columnName" show-overflow-tooltip label="名称" min-width="140"></el-table-column>
header-align="center" <el-table-column v-if="settings[1].show" prop="typeId" label="栏目类型" min-width="100">
@selection-change="handleSelectionChange"
@select-all="selectAll"
row-key="id">
<el-table-column v-if="settings[0].show"
type="selection"
width="50"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column prop="columnName"
show-overflow-tooltip
label="名称"
min-width="140"></el-table-column>
<el-table-column v-if="settings[1].show"
prop="typeId"
label="栏目类型"
min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ types.find(e => e.id == scope.row.typeId) && types.find(e => e.id == scope.row.typeId).name }} {{ types.find(e => e.id == scope.row.typeId) && types.find(e => e.id == scope.row.typeId).name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="settings[2].show" <el-table-column v-if="settings[2].show" prop="templateName" label="栏目模板" min-width="100">
prop="templateName"
label="栏目模板"
min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.typeId === 2 ? '--' : scope.row.templateName }} {{ scope.row.typeId === 2 ? '--' : scope.row.templateName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="settings[3].show" <el-table-column v-if="settings[3].show" prop="listStyle" label="列表/长页样式" min-width="100">
prop="listStyle"
label="列表/长页样式"
min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.typeId === 2 ? '--' : scope.row.listStyle }} {{ scope.row.typeId === 2 ? '--' : scope.row.listStyle }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="settings[4].show" <el-table-column v-if="settings[4].show" prop="detailStyle" label="详情样式" min-width="100">
prop="detailStyle"
label="详情样式"
min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ (scope.row.typeId === 1 || scope.row.typeId === 4) ? scope.row.detailStyle : '--' }} {{ (scope.row.typeId === 1 || scope.row.typeId === 4) ? scope.row.detailStyle : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="settings[5].show" <el-table-column v-if="settings[5].show" prop="menuVisible" label="导航菜单" min-width="100">
prop="menuVisible"
label="导航菜单"
min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.menuVisible" <el-switch v-model="scope.row.menuVisible" :active-value="0" :inactive-value="1"
:active-value="0" @change="switchOff($event, scope.row, scope.$index)">
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="settings[6].show" <el-table-column v-if="settings[6].show" prop="id" label="ID" min-width="80"></el-table-column>
prop="id" <el-table-column v-if="settings[7].show" label="操作" width="270">
label="ID"
min-width="80"></el-table-column>
<el-table-column v-if="settings[7].show"
label="操作"
width="270">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:新增下级'" <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:新增下级'" type="text"
type="text" @click="edit(scope.row, 'add')">新增下级</el-button>
@click="edit(scope.row, 'add')">新增下级</el-button> <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:编辑'" type="text"
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:编辑'" @click="edit(scope.row, 'edit')">编辑</el-button>
type="text" <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:删除'" type="text"
@click="edit(scope.row, 'edit')">编辑</el-button> @click="del(scope.row)">删除</el-button>
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:删除'" <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:预览'" v-if="scope.row.typeId != 2" type="text"
type="text" @click="preview(scope.row)">预览</el-button>
@click="del(scope.row)">删除</el-button> <el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:页面管理'" v-if="scope.row.typeId == 3" class="page-set"
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:预览'" type="primary" size="mini" @click="page(scope.row)">页面设置</el-button>
v-if="scope.row.typeId != 2"
type="text"
@click="preview(scope.row)">预览</el-button>
<el-button v-auth="'/site/list:' + siteName + ':内容管理:栏目管理:页面管理'"
v-if="scope.row.typeId == 3"
class="page-set"
type="primary"
size="mini"
@click="page(scope.row)">页面设置</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-dialog title="编辑栏目排序" <el-dialog title="编辑栏目排序" :visible.sync="sortVisible" width="750px" :close-on-click-modal="false">
:visible.sync="sortVisible"
width="750px"
:close-on-click-modal="false">
<div class="sort-wrap"> <div class="sort-wrap">
<ul class="thead"> <ul class="thead">
<li style="width: 395px;padding-left: 30px">栏目</li> <li style="width: 395px;padding-left: 30px">栏目</li>
<li style="width: 205px">栏目类型</li> <li style="width: 205px">栏目类型</li>
<li>前台可见</li> <li>前台可见</li>
</ul> </ul>
<el-tree class="sort" <el-tree class="sort" :data="sortColumns" node-key="id" default-expand-all draggable>
:data="sortColumns" <ul class="sort-line" slot-scope="{ node, data }">
node-key="id"
default-expand-all
draggable>
<ul class="sort-line"
slot-scope="{ node, data }">
<li>{{ data.columnName }}</li> <li>{{ data.columnName }}</li>
<li>{{ types.find(e => e.id == data.typeId) && types.find(e => e.id == data.typeId).name }}</li> <li>{{ types.find(e => e.id == data.typeId) && types.find(e => e.id == data.typeId).name }}</li>
<li> <li>
<el-switch v-model="data.menuVisible" <el-switch v-model="data.menuVisible" :active-value="0" :inactive-value="1"
:active-value="0" @change="switchOff($event, data)">
:inactive-value="1"
@change="switchOff($event, data)">
</el-switch> </el-switch>
</li> </li>
</ul> </ul>
</el-tree> </el-tree>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="sortVisible = false"> </el-button> <el-button @click="sortVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="sortSubmit"> </el-button>
@click="sortSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="导航样式设置" <el-dialog title="导航样式设置" :visible.sync="styleVisible" width="850px" :close-on-click-modal="false">
:visible.sync="styleVisible" <el-form class="input-form" label-width="100px">
width="850px"
:close-on-click-modal="false">
<el-form class="input-form"
label-width="100px">
<el-form-item label="导航样式"> <el-form-item label="导航样式">
<el-select v-model="form.navigationStyle"> <el-select v-model="form.navigationStyle">
<el-option v-for="item in styleTypes" <el-option v-for="item in styleTypes" :key="item.id" :label="item.name" :value="item.id">
:key="item.id"
:label="item.name"
:value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -188,11 +110,9 @@
<ul class="styles"> <ul class="styles">
<li> <li>
<div class="review"> <div class="review">
<img src="@/assets/images/style1.png" <img src="@/assets/images/style1.png" alt="">
alt="">
</div> </div>
<el-radio v-model="form.styleTemplate" <el-radio v-model="form.styleTemplate" :label="1">竖行导航</el-radio>
:label="1">竖行导航</el-radio>
</li> </li>
<!-- <li> <!-- <li>
<div class="review"> <div class="review">
@ -203,11 +123,9 @@
</ul> </ul>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="styleVisible = false"> </el-button> <el-button @click="styleVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="styleSubmit"> </el-button>
@click="styleSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -364,7 +282,7 @@ export default {
// //
preview (row) { preview (row) {
// /column // /column
window.open((Setting.isDev ? `http://${location.hostname}:8097` : this.$store.state.content.site.domainName) + `#/${row.typeId === 3 ? row.path : 'column'}?id=${row.id}&siteId=${row.siteId}`) window.open((Setting.isDev ? `http://${location.hostname}:8097` : this.$store.state.content.site.domainName) + `#/${row.typeId === 3 ? row.path : 'column'}?id=${row.id}&siteId=${row.siteId}&listPreview=1`)
}, },
// //
page (row) { page (row) {
@ -480,65 +398,79 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.sort-wrap { .sort-wrap {
max-height: 400px; max-height: 400px;
overflow: auto; overflow: auto;
} }
.thead { .thead {
display: flex; display: flex;
line-height: 44px; line-height: 44px;
background-color: #f7f7f7; background-color: #f7f7f7;
li {
padding: 0 10px; li {
font-size: 12px; padding: 0 10px;
font-weight: 500; font-size: 12px;
font-family: PingFangSC-Medium, PingFang SC; font-weight: 500;
color: #323232; font-family: PingFangSC-Medium, PingFang SC;
} color: #323232;
}
} }
/deep/.sort { /deep/.sort {
.el-tree-node__content { .el-tree-node__content {
height: auto; height: auto;
border-bottom: 1px solid #ebedf0; border-bottom: 1px solid #ebedf0;
} }
// .el-tree-node__expand-icon {
// display: none; // .el-tree-node__expand-icon {
// } // display: none;
// }
} }
.sort-line { .sort-line {
display: flex; display: flex;
width: 100%; width: 100%;
li {
padding: 12px 0; li {
&:first-child { padding: 12px 0;
width: 230px;
} &:first-child {
&:nth-child(2) { width: 230px;
position: absolute;
left: 400px;
}
&:last-child {
position: absolute;
right: 50px;
}
} }
&:nth-child(2) {
position: absolute;
left: 400px;
}
&:last-child {
position: absolute;
right: 50px;
}
}
} }
.styles { .styles {
display: inline-flex; display: inline-flex;
li {
margin-right: 20px; li {
text-align: center; margin-right: 20px;
&:hover .review { text-align: center;
border-color: #2962ff;
} &:hover .review {
} border-color: #2962ff;
.review {
padding: 18px;
margin-bottom: 10px;
border: 1px solid #dcdee0;
border-radius: 2px;
} }
}
.review {
padding: 18px;
margin-bottom: 10px;
border: 1px solid #dcdee0;
border-radius: 2px;
}
} }
.page-set { .page-set {
padding: 6px; padding: 6px;
} }
</style> </style>

@ -3,11 +3,9 @@
<div class="actions"> <div class="actions">
<p class="page-name">页面设置/HOME</p> <p class="page-name">页面设置/HOME</p>
<div> <div>
<el-button type="primary" <el-button type="primary" @click="preview">预览</el-button>
@click="preview">预览</el-button>
<el-button @click="save(0)">保存为草稿</el-button> <el-button @click="save(0)">保存为草稿</el-button>
<el-button type="primary" <el-button type="primary" @click="save(1)">发布</el-button>
@click="save(1)">发布</el-button>
<el-button @click="back">放弃编辑</el-button> <el-button @click="back">放弃编辑</el-button>
</div> </div>
</div> </div>
@ -15,19 +13,14 @@
<div class="modules"> <div class="modules">
<div class="relative"> <div class="relative">
<el-carousel height="500px" <el-carousel height="500px"
:indicator-position="modules[0].list.filter(e => e.isEnable).length > 1 ? '' : 'none'"> :indicator-position="modules[0].list.filter(e => e.isEnable).length > 1 ? '' : 'none'">
<template v-for="(item, i) in modules[0].list"> <template v-for="(item, i) in modules[0].list">
<el-carousel-item v-if="item.pic && item.isEnable" <el-carousel-item v-if="item.pic && item.isEnable" :key="i">
:key="i"> <img width="100%" height="100%" :src="item.pic" alt="">
<img width="100%"
height="100%"
:src="item.pic"
alt="">
</el-carousel-item> </el-carousel-item>
</template> </template>
</el-carousel> </el-carousel>
<div class="cover" <div class="cover" @click="toSet(0)">点击更换banner与链接</div>
@click="toSet(0)">点击更换banner与链接</div>
</div> </div>
<div class="block"> <div class="block">
@ -35,37 +28,26 @@
<div class="c-wrap"> <div class="c-wrap">
<h2 class="b-title">{{ modules[1].form.title }}</h2> <h2 class="b-title">{{ modules[1].form.title }}</h2>
<p class="intro">{{ modules[1].form.des }}</p> <p class="intro">{{ modules[1].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(1)">点击更换标题与描述</div>
@click="toSet(1)">点击更换标题与描述</div>
</div> </div>
<ul class="card"> <ul class="card">
<li> <li>
<img width="100%" <img width="100%" :src="modules[2].form.pic" alt="">
:src="modules[2].form.pic"
alt="">
<div class="texts"> <div class="texts">
<h6>{{ modules[2].form.title }}</h6> <h6>{{ modules[2].form.title }}</h6>
<p class="des">{{ modules[2].form.des }}</p> <p class="des">{{ modules[2].form.des }}</p>
<img class="arrow" <img class="arrow" src="@/assets/images/arrow.png" alt="">
src="@/assets/images/arrow.png"
alt="">
</div> </div>
<div class="cover" <div class="cover" @click="toSet(2)">点击更改图片标题概述与链接</div>
@click="toSet(2)">点击更改图片标题概述与链接</div>
</li> </li>
<li> <li>
<img width="100%" <img width="100%" :src="modules[3].form.pic" alt="">
:src="modules[3].form.pic"
alt="">
<div class="texts"> <div class="texts">
<h6>{{ modules[3].form.title }}</h6> <h6>{{ modules[3].form.title }}</h6>
<p class="des">{{ modules[3].form.des }}</p> <p class="des">{{ modules[3].form.des }}</p>
<img class="arrow" <img class="arrow" src="@/assets/images/arrow.png" alt="">
src="@/assets/images/arrow.png"
alt="">
</div> </div>
<div class="cover" <div class="cover" @click="toSet(3)">点击更改图片标题概述与链接</div>
@click="toSet(3)">点击更改图片标题概述与链接</div>
</li> </li>
</ul> </ul>
</div> </div>
@ -76,66 +58,70 @@
<div class="c-wrap"> <div class="c-wrap">
<h2 class="b-title">{{ modules[4].form.title }}</h2> <h2 class="b-title">{{ modules[4].form.title }}</h2>
<p class="intro">{{ modules[4].form.des }}</p> <p class="intro">{{ modules[4].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(4)">点击更换标题与描述</div>
@click="toSet(4)">点击更换标题与描述</div>
</div> </div>
<ul class="news"> <ul class="news">
<li> <li>
<img src="https://huorantech.com/images/home/3.png" <img src="https://huorantech.com/images/home/3.png" alt="">
alt="">
<div class="texts"> <div class="texts">
<h6>2022 New Year Message from President Sun Dongbai</h6> <h6>2022 New Year Message from President Sun Dongbai</h6>
<p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities, Shenzhen (IASF)</p> <p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities,
Shenzhen
(IASF)</p>
<span class="meta">2022.08.12</span> <span class="meta">2022.08.12</span>
</div> </div>
</li> </li>
<li> <li>
<img src="https://huorantech.com/images/home/3.png" <img src="https://huorantech.com/images/home/3.png" alt="">
alt="">
<div class="texts"> <div class="texts">
<h6>2022 New Year Message from President Sun Dongbai</h6> <h6>2022 New Year Message from President Sun Dongbai</h6>
<p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities, Shenzhen (IASF)</p> <p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities,
Shenzhen
(IASF)</p>
<span class="meta">2022.08.12</span> <span class="meta">2022.08.12</span>
</div> </div>
</li> </li>
<li> <li>
<img src="https://huorantech.com/images/home/3.png" <img src="https://huorantech.com/images/home/3.png" alt="">
alt="">
<div class="texts"> <div class="texts">
<h6>2022 New Year Message from President Sun Dongbai</h6> <h6>2022 New Year Message from President Sun Dongbai</h6>
<p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities, Shenzhen (IASF)</p> <p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities,
Shenzhen
(IASF)</p>
<span class="meta">2022.08.12</span> <span class="meta">2022.08.12</span>
</div> </div>
</li> </li>
<li> <li>
<img src="https://huorantech.com/images/home/3.png" <img src="https://huorantech.com/images/home/3.png" alt="">
alt="">
<div class="texts"> <div class="texts">
<h6>2022 New Year Message from President Sun Dongbai</h6> <h6>2022 New Year Message from President Sun Dongbai</h6>
<p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities, Shenzhen (IASF)</p> <p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities,
Shenzhen
(IASF)</p>
<span class="meta">2022.08.12</span> <span class="meta">2022.08.12</span>
</div> </div>
</li> </li>
<li> <li>
<img src="https://huorantech.com/images/home/3.png" <img src="https://huorantech.com/images/home/3.png" alt="">
alt="">
<div class="texts"> <div class="texts">
<h6>2022 New Year Message from President Sun Dongbai</h6> <h6>2022 New Year Message from President Sun Dongbai</h6>
<p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities, Shenzhen (IASF)</p> <p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities,
Shenzhen
(IASF)</p>
<span class="meta">2022.08.12</span> <span class="meta">2022.08.12</span>
</div> </div>
</li> </li>
<li> <li>
<img src="https://huorantech.com/images/home/3.png" <img src="https://huorantech.com/images/home/3.png" alt="">
alt="">
<div class="texts"> <div class="texts">
<h6>2022 New Year Message from President Sun Dongbai</h6> <h6>2022 New Year Message from President Sun Dongbai</h6>
<p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities, Shenzhen (IASF)</p> <p class="des">2021 is another challenging year for the Institute of Advanced Science Facilities,
Shenzhen
(IASF)</p>
<span class="meta">2022.08.12</span> <span class="meta">2022.08.12</span>
</div> </div>
</li> </li>
<div class="cover" <div class="cover" @click="toSet(5)">点击更换标题与描述</div>
@click="toSet(5)">点击更换标题与描述</div>
</ul> </ul>
</div> </div>
</div> </div>
@ -145,98 +131,77 @@
<div class="c-wrap"> <div class="c-wrap">
<h2 class="b-title">{{ modules[6].form.title }}</h2> <h2 class="b-title">{{ modules[6].form.title }}</h2>
<p class="intro">{{ modules[6].form.des }}</p> <p class="intro">{{ modules[6].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(6)">点击更换标题与描述</div>
@click="toSet(6)">点击更换标题与描述</div>
</div> </div>
<ul class="people"> <ul class="people">
<template v-for="(item, i) in modules[7].list"> <template v-for="(item, i) in modules[7].list">
<li v-if="item.isEnable" <li v-if="item.isEnable" :key="i">
:key="i"> <img class="pic" :src="item.pic" alt="">
<img class="pic"
:src="item.pic"
alt="">
<div class="texts"> <div class="texts">
<h6>{{ item.title }}</h6> <h6>{{ item.title }}</h6>
<p class="des">{{ item.des }}</p> <p class="des">{{ item.des }}</p>
<img class="arrow" <img class="arrow" src="@/assets/images/arrow.png" alt="">
src="@/assets/images/arrow.png"
alt="">
</div> </div>
</li> </li>
</template> </template>
<div class="cover" <div class="cover" @click="toSet(7)">点击更改图片标题概述与链接</div>
@click="toSet(7)">点击更改图片标题概述与链接</div>
</ul> </ul>
</div> </div>
</div> </div>
<div class="about"> <div class="about" :style="{ backgroundImage: 'url(' + modules[8].form.pic + ')' }">
<div class="inner"> <div class="inner">
<img src="@/assets/images/about.png" <img src="@/assets/images/about.png" alt="">
alt="">
<div class="line"></div> <div class="line"></div>
<div class="text">{{ modules[8].form.title }}</div> <div class="text">{{ modules[8].form.title }}</div>
<div class="des" <div class="des" v-html="modules[8].form.des"></div>
v-html="modules[8].form.des"></div>
</div> </div>
<div class="cover" <div class="cover" @click="toSet(8)">点击更换标题与描述</div>
@click="toSet(8)">点击更换标题与描述</div>
</div> </div>
<div class="block" <div class="block" style="padding-bottom: 0">
style="padding-bottom: 0">
<div class="inner"> <div class="inner">
<div class="c-wrap"> <div class="c-wrap">
<h2 class="glance">{{ modules[9].form.title }}</h2> <h2 class="glance">{{ modules[9].form.title }}</h2>
<div class="cover" <div class="cover" @click="toSet(9)">点击更换标题与描述</div>
@click="toSet(9)">点击更换标题与描述</div>
</div> </div>
<ul class="stat"> <ul class="stat">
<li> <li>
<p class="num">{{ modules[10].form.title }}</p> <p class="num">{{ modules[10].form.title }}</p>
<p class="text">{{ modules[10].form.des }}</p> <p class="text">{{ modules[10].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(10)">点击更换标题与描述</div>
@click="toSet(10)">点击更换标题与描述</div>
</li> </li>
<li> <li>
<p class="num">{{ modules[11].form.title }}</p> <p class="num">{{ modules[11].form.title }}</p>
<p class="text">{{ modules[11].form.des }}</p> <p class="text">{{ modules[11].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(11)">点击更换标题与描述</div>
@click="toSet(11)">点击更换标题与描述</div>
</li> </li>
<li> <li>
<p class="num">{{ modules[12].form.title }}</p> <p class="num">{{ modules[12].form.title }}</p>
<p class="text">{{ modules[12].form.des }}</p> <p class="text">{{ modules[12].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(12)">点击更换标题与描述</div>
@click="toSet(12)">点击更换标题与描述</div>
</li> </li>
<li> <li>
<p class="num">{{ modules[13].form.title }}</p> <p class="num">{{ modules[13].form.title }}</p>
<p class="text">{{ modules[13].form.des }}</p> <p class="text">{{ modules[13].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(13)">点击更换标题与描述</div>
@click="toSet(13)">点击更换标题与描述</div>
</li> </li>
<li> <li>
<p class="num">{{ modules[14].form.title }}</p> <p class="num">{{ modules[14].form.title }}</p>
<p class="text">{{ modules[14].form.des }}</p> <p class="text">{{ modules[14].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(14)">点击更换标题与描述</div>
@click="toSet(14)">点击更换标题与描述</div>
</li> </li>
<li> <li>
<p class="num">{{ modules[15].form.title }}</p> <p class="num">{{ modules[15].form.title }}</p>
<p class="text">{{ modules[15].form.des }}</p> <p class="text">{{ modules[15].form.des }}</p>
<div class="cover" <div class="cover" @click="toSet(15)">点击更换标题与描述</div>
@click="toSet(15)">点击更换标题与描述</div>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<Module ref="module" <Module ref="module" :data.sync="curData" :visible.sync="diaVisible" @moduleSubmit="moduleSubmit" />
:data.sync="curData"
:visible.sync="diaVisible"
@moduleSubmit="moduleSubmit" />
</div> </div>
</template> </template>
@ -277,162 +242,191 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../../styles/page/page.scss'; @import '../../../styles/page/page.scss';
.block { .block {
.card { .card {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
li {
position: relative; li {
width: 660px; position: relative;
} width: 660px;
.texts {
padding-left: 22px;
margin-top: 60px;
border-left: 2px solid #dfe4e9;
}
h6 {
margin-bottom: 25px;
font-size: 24px;
color: #333;
}
.des {
font-size: 18px;
color: #222;
line-height: 30px;
}
.arrow {
cursor: pointer;
}
} }
&.news-block { .texts {
background: url(../../../assets/images/info-bg.png) 0 0/100% 100% no-repeat; padding-left: 22px;
margin-top: 60px;
border-left: 2px solid #dfe4e9;
} }
.news {
position: relative; h6 {
display: flex; margin-bottom: 25px;
flex-wrap: wrap; font-size: 24px;
li { color: #333;
display: inline-flex;
width: 686px;
padding: 34px;
margin-bottom: 28px;
background-color: #fff;
&:nth-child(odd) {
margin-right: 28px;
}
}
img {
width: 237px;
height: 167px;
}
.texts {
margin-left: 34px;
}
h6 {
font-size: 18px;
color: #0648a8;
}
.des {
margin: 14px 0;
font-size: 16px;
color: #333;
line-height: 22px;
}
.meta {
font-size: 16px;
color: #999;
}
} }
.people { .des {
position: relative; font-size: 18px;
li { color: #222;
display: flex; line-height: 30px;
justify-content: space-between;
margin-bottom: 126px;
&:nth-child(even) {
flex-direction: row-reverse;
}
}
.pic {
width: 660px;
height: 465px;
}
.texts {
width: 680px;
padding-top: 150px;
}
h6 {
font-size: 40px;
}
.des {
font-size: 18px;
color: #020202;
line-height: 30px;
}
} }
.glance { .arrow {
padding-bottom: 50px; cursor: pointer;
font-size: 45px;
font-weight: bold;
font-family: SFProDisplay-Bold, SFProDisplay;
text-align: center;
border-bottom: 1px solid #dedede;
} }
.stat { }
display: flex;
justify-content: space-around; &.news-block {
flex-wrap: wrap; background: url(../../../assets/images/info-bg.png) 0 0/100% 100% no-repeat;
margin-top: 60px; }
li {
position: relative; .news {
width: 30%; position: relative;
margin-bottom: 50px; display: flex;
} flex-wrap: wrap;
.num {
margin-bottom: 10px; li {
font-size: 60px; display: inline-flex;
font-weight: 800; width: 686px;
color: #035ce1; padding: 34px;
line-height: 49px; margin-bottom: 28px;
} background-color: #fff;
.text {
font-size: 24px; &:nth-child(odd) {
} margin-right: 28px;
}
} }
}
.about { img {
width: 237px;
height: 167px;
}
.texts {
margin-left: 34px;
}
h6 {
font-size: 18px;
color: #0648a8;
}
.des {
margin: 14px 0;
font-size: 16px;
color: #333;
line-height: 22px;
}
.meta {
font-size: 16px;
color: #999;
}
}
.people {
position: relative; position: relative;
padding: 77px 0 198px;
background: url(../../../assets/images/about-bg.png) 0 0/100% 100% no-repeat; li {
.line { display: flex;
display: flex; justify-content: space-between;
align-items: center; margin-bottom: 126px;
margin: 50px 0 30px;
width: 88px; &:nth-child(even) {
height: 6px; flex-direction: row-reverse;
background-color: #fff; }
&:after {
content: '';
width: 6px;
height: 6px;
}
} }
.text {
font-size: 30px; .pic {
color: #fff; width: 660px;
height: 465px;
}
.texts {
width: 680px;
padding-top: 150px;
} }
h6 {
font-size: 40px;
}
.des { .des {
padding: 38px 60px; font-size: 18px;
margin-top: 84px; color: #020202;
font-size: 30px; line-height: 30px;
color: #fff; }
line-height: 42px; }
text-align: center;
background: rgba(111, 69, 36, 0.56); .glance {
border-radius: 17px; padding-bottom: 50px;
font-size: 45px;
font-weight: bold;
font-family: SFProDisplay-Bold, SFProDisplay;
text-align: center;
border-bottom: 1px solid #dedede;
}
.stat {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
margin-top: 60px;
li {
position: relative;
width: 30%;
margin-bottom: 50px;
}
.num {
margin-bottom: 10px;
font-size: 60px;
font-weight: 800;
color: #035ce1;
line-height: 49px;
} }
.text {
font-size: 24px;
}
}
}
.about {
position: relative;
padding: 77px 0 198px;
background: url(../../../assets/images/about-bg.png) 0 0/100% 100% no-repeat;
.line {
display: flex;
align-items: center;
margin: 50px 0 30px;
width: 88px;
height: 6px;
background-color: #fff;
&:after {
content: '';
width: 6px;
height: 6px;
}
}
.text {
font-size: 30px;
color: #fff;
}
.des {
padding: 38px 60px;
margin-top: 84px;
font-size: 30px;
color: #fff;
line-height: 42px;
text-align: center;
background: rgba(111, 69, 36, 0.56);
border-radius: 17px;
}
} }
</style> </style>

@ -1,40 +1,23 @@
<template> <template>
<div class="page"> <div class="page">
<p class="page-name mb">SEO管理</p> <p class="page-name mb">SEO管理</p>
<el-form ref="form" <el-form ref="form" :model="form" :rules="rules" class="input-form" label-width="140px">
:model="form" <el-form-item prop="title" label="SEO标题">
:rules="rules" <el-input placeholder="SEO标题" v-model="form.title" clearable maxlength="100"></el-input>
class="input-form"
label-width="140px">
<el-form-item prop="title"
label="SEO标题">
<el-input placeholder="SEO标题"
v-model="form.title"
clearable
maxlength="100"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="keyword" <el-form-item prop="keyword" label="SEO关键词">
label="SEO关键词"> <el-input placeholder="SEO关键词" v-model="form.keyword" clearable></el-input>
<el-input placeholder="SEO关键词"
v-model="form.keyword"
clearable></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="description" <el-form-item prop="description" label="SEO描述">
label="SEO描述"> <el-input type="textarea" placeholder="SEO标题" v-model="form.description" clearable :rows="7"></el-input>
<el-input type="textarea"
placeholder="SEO标题"
v-model="form.description"
clearable></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="text-center"> <div class="text-center">
<el-button type="primary" <el-button type="primary" @click="submit">保存</el-button>
@click="submit">保存</el-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
export default { export default {
data () { data () {
@ -104,9 +87,10 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.input-form { .input-form {
.el-input,
.el-textarea { .el-input,
width: 940px; .el-textarea {
} width: 940px;
}
} }
</style> </style>
Loading…
Cancel
Save