parent
a6a1a54449
commit
9c208766b9
15 changed files with 3674 additions and 5 deletions
After Width: | Height: | Size: 287 B |
@ -0,0 +1,235 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="cropper-content"> |
||||||
|
<!-- 剪裁框 --> |
||||||
|
<div class="cropper"> |
||||||
|
<vueCropper |
||||||
|
ref="cropper" |
||||||
|
:img="option.img" |
||||||
|
:output-size="option.size" |
||||||
|
:output-type="option.outputType" |
||||||
|
:info="true" |
||||||
|
:full="option.full" |
||||||
|
:can-move="option.canMove" |
||||||
|
:can-move-box="option.canMoveBox" |
||||||
|
:original="option.original" |
||||||
|
:auto-crop="option.autoCrop" |
||||||
|
:auto-crop-width="option.autoCropWidth" |
||||||
|
:auto-crop-height="option.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> --> |
||||||
|
</div> |
||||||
|
<!-- 预览框 --> |
||||||
|
<div |
||||||
|
class="show-preview" |
||||||
|
:style="{'width': '500px', 'height': '400px', 'overflow': 'hidden', 'margin': '0 25px', 'display':'flex', 'align-items' : 'center'}"> |
||||||
|
<div :style="previews.div" class="preview"> |
||||||
|
<img :src="previews.url" :style="previews.img" /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="footer-btn"> |
||||||
|
<!-- 缩放旋转按钮 --> |
||||||
|
<!-- <div class="scope-btn"> |
||||||
|
<el-button type="primary" icon="el-icon-zoom-in" @click="changeScale(1)"></el-button> |
||||||
|
<el-button type="primary" icon="el-icon-zoom-out" @click="changeScale(-1)"></el-button> |
||||||
|
<el-button type="primary" @click="rotateLeft">逆时针旋转</el-button> |
||||||
|
<el-button type="primary" @click="rotateRight">顺时针旋转</el-button> |
||||||
|
</div>--> |
||||||
|
<!-- 确认上传按钮 --> |
||||||
|
<div class="upload-btn"> |
||||||
|
<el-button |
||||||
|
type="primary" |
||||||
|
:loading="isUpload" |
||||||
|
:disabled="isDisabled" |
||||||
|
@click.prevent="uploadImg('blob')"> |
||||||
|
上传 |
||||||
|
</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { |
||||||
|
VueCropper |
||||||
|
} from 'vue-cropper' |
||||||
|
import {compress, compressAccurately} from 'image-conversion' |
||||||
|
export default { |
||||||
|
components: { |
||||||
|
VueCropper |
||||||
|
}, |
||||||
|
props: { |
||||||
|
// 上传状态 |
||||||
|
isUpload: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
// 图片对象 |
||||||
|
imgFile: { |
||||||
|
type: Object, |
||||||
|
require: true, |
||||||
|
default: () => { |
||||||
|
return { url: '', size: 10 } |
||||||
|
} |
||||||
|
}, |
||||||
|
// 截图框比例 |
||||||
|
fixedNumber: { |
||||||
|
type: Array, |
||||||
|
default: () => { |
||||||
|
return [1, 0.26] |
||||||
|
} |
||||||
|
}, |
||||||
|
fixed: { |
||||||
|
type: Boolean, |
||||||
|
default: true |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
previews: {}, // 预览数据 |
||||||
|
option: { |
||||||
|
img: '', // 裁剪图片的地址 (默认:空) |
||||||
|
size: 0.8, // 裁剪生成图片的质量 (默认:1) |
||||||
|
full: true, // 是否输出原图比例的截图 选true生成的图片会非常大 (默认:false) |
||||||
|
outputType: 'jpg', // 裁剪生成图片的格式 (默认:jpg) |
||||||
|
canMove: true, // 上传图片是否可以移动 (默认:true) |
||||||
|
original: false, // 上传图片按照原始比例渲染 (默认:false) |
||||||
|
canMoveBox: true, // 截图框能否拖动 (默认:true) |
||||||
|
autoCrop: true, // 是否默认生成截图框 (默认:false) |
||||||
|
autoCropWidth: 480, // 默认生成截图框宽度 (默认:80%) |
||||||
|
autoCropHeight: 124, // 默认生成截图框高度 (默认:80%) |
||||||
|
fixedBox: false, // 固定截图框大小 不允许改变 (默认:false) |
||||||
|
fixed: true, // 是否开启截图框宽高固定比例 (默认:true) |
||||||
|
fixedNumber: [1, 0.26], // 截图框比例 (默认:[1:1]) |
||||||
|
enlarge: 1 |
||||||
|
}, |
||||||
|
isDisabled: false |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
changeScale(num) { |
||||||
|
// 图片缩放 |
||||||
|
num = num || 1 |
||||||
|
this.$refs.cropper.changeScale(num) |
||||||
|
}, |
||||||
|
rotateLeft() { |
||||||
|
// 向左旋转 |
||||||
|
this.$refs.cropper.rotateLeft() |
||||||
|
}, |
||||||
|
rotateRight() { |
||||||
|
// 向右旋转 |
||||||
|
this.$refs.cropper.rotateRight() |
||||||
|
}, |
||||||
|
updateImg(file) { |
||||||
|
this.option.img = file.url |
||||||
|
this.option.size = file.size / 1024 > 200 ? 0.9 : 0.95 |
||||||
|
}, |
||||||
|
realTime(data) { |
||||||
|
// 实时预览 |
||||||
|
this.previews = data |
||||||
|
}, |
||||||
|
close() { |
||||||
|
}, |
||||||
|
uploadImg(type) { |
||||||
|
this.isDisabled = true |
||||||
|
// 将剪裁好的图片回传给父组件 |
||||||
|
const that = this |
||||||
|
if (type === 'blob') { |
||||||
|
this.$refs.cropper.getCropBlob(data => { |
||||||
|
compress(data, 0.8).then(res => { |
||||||
|
that.$emit('upload', res) |
||||||
|
}) |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.$refs.cropper.getCropData(data => { |
||||||
|
that.$emit('upload', data) |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss" scoped> |
||||||
|
.cropper-content { |
||||||
|
display: flex; |
||||||
|
display: -webkit-flex; |
||||||
|
justify-content: flex-end; |
||||||
|
-webkit-justify-content: flex-end; |
||||||
|
} |
||||||
|
|
||||||
|
.cropper-content .cropper { |
||||||
|
width: 500px; |
||||||
|
height: 400px; |
||||||
|
} |
||||||
|
|
||||||
|
.cropper-content .show-preview { |
||||||
|
flex: 1; |
||||||
|
-webkit-flex: 1; |
||||||
|
display: flex; |
||||||
|
display: -webkit-flex; |
||||||
|
justify-content: center; |
||||||
|
-webkit-justify-content: center; |
||||||
|
overflow: hidden; |
||||||
|
border: 1px solid #cccccc; |
||||||
|
background: #cccccc; |
||||||
|
margin-left: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.preview { |
||||||
|
overflow: hidden; |
||||||
|
border: 1px solid #cccccc; |
||||||
|
background: #cccccc; |
||||||
|
} |
||||||
|
|
||||||
|
.footer-btn { |
||||||
|
margin-top: 30px; |
||||||
|
display: flex; |
||||||
|
display: -webkit-flex; |
||||||
|
justify-content: flex-end; |
||||||
|
-webkit-justify-content: flex-end; |
||||||
|
} |
||||||
|
|
||||||
|
.footer-btn .scope-btn { |
||||||
|
width: 500px; |
||||||
|
display: flex; |
||||||
|
display: -webkit-flex; |
||||||
|
justify-content: space-between; |
||||||
|
-webkit-justify-content: space-between; |
||||||
|
} |
||||||
|
|
||||||
|
.footer-btn .upload-btn { |
||||||
|
flex: 1; |
||||||
|
-webkit-flex: 1; |
||||||
|
display: flex; |
||||||
|
display: -webkit-flex; |
||||||
|
justify-content: center; |
||||||
|
-webkit-justify-content: center; |
||||||
|
} |
||||||
|
|
||||||
|
.footer-btn .btn { |
||||||
|
outline: none; |
||||||
|
display: inline-block; |
||||||
|
line-height: 1; |
||||||
|
white-space: nowrap; |
||||||
|
cursor: pointer; |
||||||
|
-webkit-appearance: none; |
||||||
|
text-align: center; |
||||||
|
-webkit-box-sizing: border-box; |
||||||
|
box-sizing: border-box; |
||||||
|
outline: 0; |
||||||
|
margin: 0; |
||||||
|
-webkit-transition: 0.1s; |
||||||
|
transition: 0.1s; |
||||||
|
font-weight: 500; |
||||||
|
padding: 8px 15px; |
||||||
|
font-size: 12px; |
||||||
|
border-radius: 3px; |
||||||
|
color: #fff; |
||||||
|
background-color: #67c23a; |
||||||
|
border-color: #67c23a; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,535 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<!-- 多图片上传 --> |
||||||
|
<el-upload |
||||||
|
ref="upload" |
||||||
|
drag |
||||||
|
action="string" |
||||||
|
:list-type="listType" |
||||||
|
accept="image/*" |
||||||
|
:on-preview="handlePreview" |
||||||
|
:auto-upload="false" |
||||||
|
:on-change="handleChange" |
||||||
|
:file-list="uploadList" |
||||||
|
class="img-upload clearfix" |
||||||
|
:class="{ 'max-num': !isShowPlus || isPreview, describes: describe }"> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<div class="el-upload__text"> |
||||||
|
<slot name="el-upload__text"></slot> |
||||||
|
</div> |
||||||
|
<div v-if="describe" slot="tip" class="el-upload__tip"> |
||||||
|
{{ describe }} |
||||||
|
</div> |
||||||
|
<div slot="file" slot-scope="{ scope }" class="upload-item-container"> |
||||||
|
<img |
||||||
|
class="el-upload-list__item-thumbnail" |
||||||
|
:class="{ cover: isSingle && !isNeedChange }" |
||||||
|
:src="scope.url" |
||||||
|
alt |
||||||
|
@click="handlePreview(scope)" /> |
||||||
|
<div |
||||||
|
v-if="!isSingle && !isPreview" |
||||||
|
class="el-upload-list__item-handover"> |
||||||
|
<i |
||||||
|
class="el-icon-arrow-left" |
||||||
|
:class="{ disabled: scope.prevDisabled }" |
||||||
|
@click.stop="movePrev(scope)"></i> |
||||||
|
<i |
||||||
|
class="el-icon-arrow-right" |
||||||
|
:class="{ disabled: scope.nextDisabled }" |
||||||
|
@click.stop="moveNext(scope)"></i> |
||||||
|
</div> |
||||||
|
<div v-if="isSingle && !isPreview"> |
||||||
|
<p v-if="isNeedChange" class="tac" @click="changeImg($event)"> |
||||||
|
更 换 |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
<span |
||||||
|
v-if="!isPreview" |
||||||
|
class="el-upload-list__item-delete" |
||||||
|
@click="handleRemove(scope)"> |
||||||
|
<i class="el-icon-close"></i> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
<!-- 多图片预览弹窗 --> |
||||||
|
<el-dialog |
||||||
|
append-to-body |
||||||
|
:visible.sync="dialogVisible" |
||||||
|
class="img_view" |
||||||
|
top="20vh" |
||||||
|
width="560px"> |
||||||
|
<!-- <span class="el-carousel__arrow el-carousel__arrow--left" @click="prevAction"> |
||||||
|
<i class="el-icon-arrow-left"></i> |
||||||
|
</span> |
||||||
|
<span class="el-carousel__arrow el-carousel__arrow--right" @click="nextAction"> |
||||||
|
<i class="el-icon-arrow-right"></i> |
||||||
|
</span>--> |
||||||
|
<el-carousel |
||||||
|
v-if="dialogVisible" |
||||||
|
ref="el_carousel" |
||||||
|
height="420px" |
||||||
|
:autoplay="false" |
||||||
|
:class="[uploadList.length < 2 ? 'isShowCutBtn' : '']" |
||||||
|
:initial-index="currentNum"> |
||||||
|
<el-carousel-item v-for="(item, index) in uploadList" :key="index"> |
||||||
|
<img :src="item.url" alt style="width:100%" /> |
||||||
|
</el-carousel-item> |
||||||
|
</el-carousel> |
||||||
|
</el-dialog> |
||||||
|
<!-- 剪裁组件弹窗 --> |
||||||
|
<el-dialog append-to-body :visible.sync="cropperModel" width="1100px"> |
||||||
|
<Cropper |
||||||
|
ref="vueCropper" |
||||||
|
:is-upload="isUpload" |
||||||
|
:img-file="file" |
||||||
|
:fixed-number="fixedNumber" |
||||||
|
:fixed="fixed" |
||||||
|
:fixed-box="fixedBox" |
||||||
|
@upload="customUpload" /> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import Cropper from './Cropper' |
||||||
|
export default { |
||||||
|
name: 'Uploader', |
||||||
|
components: { |
||||||
|
Cropper |
||||||
|
}, |
||||||
|
props: { |
||||||
|
// 上传api方法 |
||||||
|
uploadMethodName: { |
||||||
|
type: String, |
||||||
|
default: '', |
||||||
|
required: true |
||||||
|
}, |
||||||
|
// 最大图片数量 |
||||||
|
maxImages: { |
||||||
|
type: Number, |
||||||
|
default: 9 |
||||||
|
}, |
||||||
|
// 是否单图 |
||||||
|
isSingle: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
// 单图模式是否显示更改按钮 |
||||||
|
isNeedChange: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
// 初始化filelist |
||||||
|
initFileList: { |
||||||
|
type: Array, |
||||||
|
default: () => [] |
||||||
|
}, |
||||||
|
// 剪裁框比例设置 |
||||||
|
fixedNumber: { |
||||||
|
type: Array, |
||||||
|
default: () => [4, 3] |
||||||
|
}, |
||||||
|
// 是否固定宽高比例 |
||||||
|
fixed: { |
||||||
|
type: Boolean, |
||||||
|
default: true |
||||||
|
}, |
||||||
|
// 开启查看模式 |
||||||
|
isPreview: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
}, |
||||||
|
// 推荐上传描述 |
||||||
|
describe: { |
||||||
|
type: String, |
||||||
|
default: '' |
||||||
|
}, |
||||||
|
// 是否固定截图框大小 不允许改变 |
||||||
|
fixedBox: { |
||||||
|
type: Boolean, |
||||||
|
default: false |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
isUpload: false, |
||||||
|
file: {}, // 当前被选择的图片文件 |
||||||
|
// dialogImageUrl: '', // 弹窗内图片链接 |
||||||
|
uploadList: [], // 上传图片列表 |
||||||
|
dialogVisible: false, // 展示弹窗开关 |
||||||
|
cropperModel: false, // 剪裁组件弹窗开关 |
||||||
|
currentNum: 0 // 当前点击的是第几张图片 |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
isShowPlus() { |
||||||
|
if (this.isSingle && this.uploadList.length > 0) { |
||||||
|
return false |
||||||
|
} |
||||||
|
if (!this.isSingle && this.uploadList.length >= this.maxImages) { |
||||||
|
return false |
||||||
|
} |
||||||
|
return true |
||||||
|
}, |
||||||
|
listType() { |
||||||
|
return 'picture-card' |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
uploadList(newVal) { |
||||||
|
if (!newVal.length) { |
||||||
|
return |
||||||
|
} |
||||||
|
this.uploadList.map((item, index) => { |
||||||
|
item.prevDisabled = index === 0 |
||||||
|
item.nextDisabled = index === this.uploadList.length - 1 |
||||||
|
}) |
||||||
|
this.$emit('imgupload', newVal) |
||||||
|
}, |
||||||
|
initFileList(newVal) { |
||||||
|
this.updateList(newVal) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.updateList(this.initFileList) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
handlePreview(file) { |
||||||
|
// 点击进行图片展示 |
||||||
|
this.currentNum = this.uploadList.findIndex( |
||||||
|
item => item.uid === file.uid |
||||||
|
) |
||||||
|
console.log('file--', file, this.currentNum) |
||||||
|
// this.dialogImageUrl = file.url; |
||||||
|
|
||||||
|
this.dialogVisible = true |
||||||
|
}, |
||||||
|
// 切换图片 |
||||||
|
prevAction() { |
||||||
|
this.$refs.el_carousel.prev() |
||||||
|
}, |
||||||
|
nextAction() { |
||||||
|
this.$refs.el_carousel.next() |
||||||
|
}, |
||||||
|
handleRemove(file) { |
||||||
|
const index = this.uploadList.findIndex(item => item.uid === file.uid) |
||||||
|
this.uploadList.splice(index, 1) |
||||||
|
this.$emit('imgupload', this.uploadList) |
||||||
|
console.log('查看删除文件', file, this.uploadList) |
||||||
|
}, |
||||||
|
handleChange(file, fileList) { |
||||||
|
// var fileSize = file.size / 1024 > 300 |
||||||
|
// if (fileSize) { |
||||||
|
// this.$message.info('图片大小不能超过300k'); |
||||||
|
// return |
||||||
|
// } |
||||||
|
this.file = file |
||||||
|
this.uploadList = this.uploadList.filter( |
||||||
|
item => item.status === 'success' |
||||||
|
) |
||||||
|
console.log(fileList, this.uploadList) |
||||||
|
// 弹出剪裁框,将当前文件设置为文件 |
||||||
|
this.cropperModel = true |
||||||
|
this.$nextTick(() => { |
||||||
|
if (this.$refs.vueCropper) { |
||||||
|
this.$refs.vueCropper.isDisabled = false |
||||||
|
this.$refs.vueCropper.updateImg() |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
movePrev(file) { |
||||||
|
if (file.prevDisabled) { |
||||||
|
return |
||||||
|
} |
||||||
|
const index = this.uploadList.findIndex(item => item.uid === file.uid) |
||||||
|
this.swapArray(this.uploadList, index, index - 1) |
||||||
|
}, |
||||||
|
moveNext(file) { |
||||||
|
if (file.nextDisabled) { |
||||||
|
return |
||||||
|
} |
||||||
|
const index = this.uploadList.findIndex(item => item.uid === file.uid) |
||||||
|
this.swapArray(this.uploadList, index, index + 1) |
||||||
|
}, |
||||||
|
swapArray(arr, index1, index2) { |
||||||
|
arr[index1] = arr.splice(index2, 1, arr[index1])[0] |
||||||
|
return arr |
||||||
|
}, |
||||||
|
changeImg($e) { |
||||||
|
console.log($e) |
||||||
|
}, |
||||||
|
customUpload(data) { |
||||||
|
// 自定义upload事件 |
||||||
|
// console.log(data); |
||||||
|
// let _data = this.compress(img); |
||||||
|
const blob = this.dataURItoBlob(data) |
||||||
|
const formData = new FormData() |
||||||
|
formData.append('file', blob, this.file.name) // 有的后台需要传文件名,不然会报错 |
||||||
|
this.imgUpload(formData) |
||||||
|
}, |
||||||
|
async imgUpload(formData) { |
||||||
|
this.isUpload = true |
||||||
|
await this.$api[this.uploadMethodName]({ |
||||||
|
data: formData, |
||||||
|
showLoading: false |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
// 上传成功将照片传回父组件 |
||||||
|
console.log(this.uploadList) |
||||||
|
this.uploadList = this.isSingle ? res : this.uploadList.concat(res) |
||||||
|
this.uploadList.forEach(item => { |
||||||
|
item.name = item.fileId |
||||||
|
item.url = `/common-service/file/downloadFileFromOSS?key=${item.fileId}` |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
this.$refs.vueCropper.isDisabled = false |
||||||
|
}) |
||||||
|
this.isUpload = false |
||||||
|
this.cropperModel = false |
||||||
|
}, |
||||||
|
formatImgArr(arr) { |
||||||
|
const result = arr.map((item, index) => { |
||||||
|
if (typeof item === 'string') { |
||||||
|
return { |
||||||
|
url: item, |
||||||
|
uid: `index${index}` |
||||||
|
} |
||||||
|
} |
||||||
|
return item.url |
||||||
|
|
||||||
|
}) |
||||||
|
return result |
||||||
|
}, |
||||||
|
// 压缩图片 |
||||||
|
compress(img) { |
||||||
|
const canvas = document.createElement('canvas') |
||||||
|
const ctx = canvas.getContext('2d') |
||||||
|
// let initSize = img.src.length; |
||||||
|
const width = img.width |
||||||
|
const height = img.height |
||||||
|
canvas.width = width |
||||||
|
canvas.height = height |
||||||
|
// 铺底色 |
||||||
|
ctx.fillStyle = '#fff' |
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height) |
||||||
|
ctx.drawImage(img, 0, 0, width, height) |
||||||
|
// 进行压缩 |
||||||
|
const ndata = canvas.toDataURL('image/jpeg', 0.8) |
||||||
|
return ndata |
||||||
|
}, |
||||||
|
// base64转成bolb对象 |
||||||
|
dataURItoBlob(base64Data) { |
||||||
|
let byteString |
||||||
|
if (base64Data.split(',')[0].indexOf('base64') >= 0) { |
||||||
|
byteString = atob(base64Data.split(',')[1]) |
||||||
|
} else { |
||||||
|
byteString = unescape(base64Data.split(',')[1]) |
||||||
|
} |
||||||
|
const mimeString = base64Data |
||||||
|
.split(',')[0] |
||||||
|
.split(':')[1] |
||||||
|
.split(';')[0] |
||||||
|
// const mimeString = 'image/jpeg' |
||||||
|
console.log(mimeString, 'fsnajkcbnjkscsa---') |
||||||
|
const ia = new Uint8Array(byteString.length) |
||||||
|
for (let i = 0; i < byteString.length; i++) { |
||||||
|
ia[i] = byteString.charCodeAt(i) |
||||||
|
} |
||||||
|
return new Blob([ia], { |
||||||
|
type: mimeString |
||||||
|
}) |
||||||
|
}, |
||||||
|
updateList(val) { |
||||||
|
this.uploadList = this.$copy(val).map(item => ({ |
||||||
|
...item, |
||||||
|
businessId: item.businessId || null, |
||||||
|
fileId: item.fileId || item, |
||||||
|
name: item.fileId || item, |
||||||
|
url: `/common-service/file/downloadFileFromOSS?key=${item.fileId || |
||||||
|
item}` |
||||||
|
})) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style lang="scss"> |
||||||
|
.img-upload { |
||||||
|
// width: 840px; |
||||||
|
margin-left: 20px; |
||||||
|
text-align: left; |
||||||
|
.el-upload--picture-card { |
||||||
|
width: 120px; |
||||||
|
height: 120px; |
||||||
|
line-height: inherit; |
||||||
|
} |
||||||
|
&.max-num { |
||||||
|
.el-upload { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
||||||
|
.el-upload { |
||||||
|
border: 0; |
||||||
|
.el-upload-dragger { |
||||||
|
width: 120px; |
||||||
|
height: 120px; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
background: #fafafa; |
||||||
|
flex-direction: column; |
||||||
|
.el-icon-plus { |
||||||
|
font-size: 37px; |
||||||
|
color: #ccc; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-upload-list--picture-card { |
||||||
|
.el-upload-list__item { |
||||||
|
overflow: visible; |
||||||
|
position: relative; |
||||||
|
height: 120px; |
||||||
|
width: 120px; |
||||||
|
margin: 0 24px 32px 0; |
||||||
|
// @include borderBase; |
||||||
|
outline: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.upload-item-container { |
||||||
|
display: flex; |
||||||
|
height: 100%; |
||||||
|
background: rgba(237, 237, 237, 0.28); |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
.el-upload-list__item-thumbnail { |
||||||
|
border-radius: 5px; |
||||||
|
height: 76%; |
||||||
|
&.cover { |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
p.tac { |
||||||
|
line-height: 28px; |
||||||
|
color: #5f5d5d; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.el-upload-list__item-handover { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
padding: 0 20px; |
||||||
|
|
||||||
|
> i { |
||||||
|
cursor: pointer; |
||||||
|
&::before { |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
display: inline-block; |
||||||
|
box-sizing: border-box; |
||||||
|
border-radius: 50%; |
||||||
|
border: 1px solid #5f5d5d; |
||||||
|
font-size: 12px; |
||||||
|
line-height: 16px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
&.disabled { |
||||||
|
&::before { |
||||||
|
border: 1px solid #939393; |
||||||
|
color: #939393; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-upload-list__item-delete { |
||||||
|
position: absolute; |
||||||
|
right: -9px; |
||||||
|
top: -9px; |
||||||
|
display: block; |
||||||
|
height: 24px; |
||||||
|
width: 24px; |
||||||
|
background-color: #ffffff; |
||||||
|
border: 1px solid #d5341e; |
||||||
|
border-radius: 50%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
> i { |
||||||
|
position: static; |
||||||
|
font-size: 14px; |
||||||
|
color: #d5341e; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.describes { |
||||||
|
display: flex; |
||||||
|
.el-upload__tip { |
||||||
|
margin-left: 8px; |
||||||
|
color: #939393; |
||||||
|
} |
||||||
|
} |
||||||
|
.v-modal { |
||||||
|
opacity: 0.3; |
||||||
|
} |
||||||
|
.img_view.el-dialog__wrapper { |
||||||
|
.el-dialog { |
||||||
|
background: none; |
||||||
|
box-shadow: none; |
||||||
|
} |
||||||
|
.el-dialog__header { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.el-dialog__body { |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
.title { |
||||||
|
display: flex; |
||||||
|
justify-content: flex-end; |
||||||
|
span { |
||||||
|
line-height: 48px; |
||||||
|
width: 80px; |
||||||
|
height: 48px; |
||||||
|
text-align: right; |
||||||
|
cursor: pointer; |
||||||
|
font-size: 14px; |
||||||
|
color: #ffffff; |
||||||
|
} |
||||||
|
} |
||||||
|
.el-carousel__indicators--horizontal { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.el-carousel__arrow { |
||||||
|
width: 40px; |
||||||
|
height: 40px; |
||||||
|
box-sizing: border-box; |
||||||
|
color: #5f5d5d; |
||||||
|
background: rgba(255, 255, 255, 0.5); |
||||||
|
border: 1px solid #5f5d5d; |
||||||
|
i { |
||||||
|
&::before { |
||||||
|
font-size: 28px; |
||||||
|
line-height: 40px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.el-carousel { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
.isShowCutBtn { |
||||||
|
.el-carousel__arrow { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
||||||
|
.el-carousel__arrow.el-carousel__arrow--left { |
||||||
|
left: 0; |
||||||
|
} |
||||||
|
.el-carousel__arrow.el-carousel__arrow--right { |
||||||
|
right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,69 @@ |
|||||||
|
<template> |
||||||
|
<div class="page system" style="padding: 0"> |
||||||
|
<div class="tabs"> |
||||||
|
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{ item }}</a> |
||||||
|
</div> |
||||||
|
|
||||||
|
<staff v-if="active == 'staff'"></staff> |
||||||
|
<pc-role v-if="active == 'pcRole'"></pc-role> |
||||||
|
<mobile-role v-if="active == 'mobileRole'"></mobile-role> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from "@/setting"; |
||||||
|
import staff from "./staff"; |
||||||
|
import pcRole from "./pcRole"; |
||||||
|
import mobileRole from "./mobileRole"; |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
active: this.$route.query.type || 'staff', |
||||||
|
tabs: { |
||||||
|
staff: "合伙人学习管理", |
||||||
|
pcRole: "合伙人资讯管理", |
||||||
|
mobileRole: "方案管理" |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
staff, |
||||||
|
pcRole, |
||||||
|
mobileRole |
||||||
|
}, |
||||||
|
created() { |
||||||
|
Setting.dynamicRoute && this.initTabs(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
tabChange(index) { |
||||||
|
this.active = index |
||||||
|
this.$router.push({ |
||||||
|
path: 'parnerOperation', |
||||||
|
query: { |
||||||
|
...this.$route.query, |
||||||
|
type: index |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
initTabs() { |
||||||
|
const btns = this.$store.state.btns |
||||||
|
const tab1 = btns.includes('/parner:合伙人学习管理') |
||||||
|
const tab2 = btns.includes('/parner:合伙人资讯管理') |
||||||
|
const tab3 = btns.includes('/parner:方案管理') |
||||||
|
|
||||||
|
tab1 || delete this.tabs.staff |
||||||
|
tab2 || delete this.tabs.pcRole |
||||||
|
tab3 || delete this.tabs.mobileRole |
||||||
|
const type = this.$route.query.type |
||||||
|
const keys = Object.keys(this.tabs) |
||||||
|
this.active = keys.includes(type) ? type : keys[0] |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.system { |
||||||
|
min-height: calc(100vh - 170px); |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,967 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<p class="page-name mb">文章详情</p> |
||||||
|
<el-form :model="form" :rules="rules" class="input-form model" label-width="140px"> |
||||||
|
<el-form-item prop="title" label="标题"> |
||||||
|
<el-input |
||||||
|
id="articleTitle" |
||||||
|
style="width: 940px" |
||||||
|
placeholder="请输入标题" |
||||||
|
v-model="form.title" |
||||||
|
clearable |
||||||
|
maxlength="100" |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item prop="releaseTime" label="发布日期"> |
||||||
|
<el-date-picker |
||||||
|
v-model="form.releaseTime" |
||||||
|
type="date" |
||||||
|
placeholder="选择日期" |
||||||
|
format="yyyy-MM-dd" |
||||||
|
:clearable="false" |
||||||
|
value-format="yyyy-MM-dd"> |
||||||
|
</el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item prop="source" label="来源"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入来源" |
||||||
|
v-model.trim="form.source" |
||||||
|
clearable |
||||||
|
maxlength="50" |
||||||
|
class="inline-input" |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="author" label="作者"> |
||||||
|
<el-input |
||||||
|
v-model="form.author" |
||||||
|
clearable |
||||||
|
maxlength="50" |
||||||
|
class="inline-input" |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item prop="edit" label="编辑"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入编辑" |
||||||
|
v-model.trim="form.edit" |
||||||
|
clearable |
||||||
|
maxlength="50" |
||||||
|
class="inline-input" |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="audit" label="审核"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入审核" |
||||||
|
v-model.trim="form.audit" |
||||||
|
clearable |
||||||
|
maxlength="50" |
||||||
|
class="inline-input" |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item prop="source" label="所属分类"> |
||||||
|
<el-select style="width: 234px;" v-model="form.classificationId"> |
||||||
|
<template v-for="item in classifications"> |
||||||
|
<el-option |
||||||
|
v-if="item.id" |
||||||
|
:key="item.id" |
||||||
|
:label="item.classificationName" |
||||||
|
:value="item.id"> |
||||||
|
</el-option> |
||||||
|
</template> |
||||||
|
</el-select> |
||||||
|
<el-button class="set-btn" type="primary" @click="setClass">设置</el-button> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="author" label="主题标签"> |
||||||
|
<el-select style="width: 234px;" v-model="form.lableId" multiple> |
||||||
|
<template v-for="item in labels"> |
||||||
|
<el-option |
||||||
|
v-if="item.id" |
||||||
|
:key="item.id" |
||||||
|
:label="item.labelName" |
||||||
|
:value="item.id"> |
||||||
|
</el-option> |
||||||
|
</template> |
||||||
|
</el-select> |
||||||
|
<el-button class="set-btn" type="primary" @click="setLabel">设置</el-button> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<el-form-item prop="summary" label="摘要"> |
||||||
|
<el-input |
||||||
|
style="width: 940px" |
||||||
|
type="textarea" |
||||||
|
v-model.trim="form.summary" |
||||||
|
:rows="3" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="titleImg" label="封面图"> |
||||||
|
<el-upload |
||||||
|
class="avatar-uploader" |
||||||
|
accept=".jpg,.png,.jpeg,.gif" |
||||||
|
:on-change="file => changeFile(file, 0)" |
||||||
|
:show-file-list="false" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:auto-upload="false" |
||||||
|
> |
||||||
|
<img v-if="form.titleImg" :src="form.titleImg" class="avatar"> |
||||||
|
<div class="uploader-default" v-else> |
||||||
|
<img class="plus" src="@/assets/img/plus.png" alt=""> |
||||||
|
<p>点击上传</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="mainBody" label="正文"> |
||||||
|
<Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' v-model="form.mainBody" :init="editorConfig" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="file" label="文件上传"> |
||||||
|
<el-upload |
||||||
|
:before-upload="fileBeforeUpload" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-success="uploadSuccessFile" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:file-list="form.fileList" |
||||||
|
:headers="headers" |
||||||
|
> |
||||||
|
<el-button>上传</el-button> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div class="btns"> |
||||||
|
<el-button type="primary" @click="submit(1)">发布</el-button> |
||||||
|
<el-button @click="submit(0)">保存草稿</el-button> |
||||||
|
<el-button @click="back">取消</el-button> |
||||||
|
</div> |
||||||
|
<!-- 剪裁组件弹窗 --> |
||||||
|
<el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false"> |
||||||
|
<Cropper |
||||||
|
ref="cropper" |
||||||
|
:img-file.sync="file" |
||||||
|
:is-upload="isUpload" |
||||||
|
:fixed="true" |
||||||
|
:fixedNumber.sync="fixedNumber" |
||||||
|
@upload="customUpload" /> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="所属分类设置" :visible.sync="classVisible" width="500px" :close-on-click-modal="false" class="manage-dia" :before-close="closeClass"> |
||||||
|
<div class="plus"> |
||||||
|
<i class="el-icon-circle-plus-outline" @click="addClass"></i> |
||||||
|
</div> |
||||||
|
<el-table :data="classifications" ref="table" header-align="center" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="classificationName" label="分类名称" align="center" min-width="130"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input |
||||||
|
v-if="scope.row.edit" |
||||||
|
placeholder="请输入分类名称" |
||||||
|
v-model="scope.row.classificationName" |
||||||
|
clearable |
||||||
|
maxlength="30" |
||||||
|
></el-input> |
||||||
|
<span v-else>{{ scope.row.classificationName }}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="updateTime1" label="是否引用" align="center" min-width="60">否</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" min-width="60"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<i v-if="scope.row.edit" class="el-icon-check edit" @click="submitClass(scope.row)"></i> |
||||||
|
<i v-else class="el-icon-edit edit" @click="editClass(scope.row)"></i> |
||||||
|
<i class="el-icon-delete del" @click="delClass(scope.row, scope.$index)"></i> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<span slot="footer"> |
||||||
|
<el-button @click="closeClass">返回</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="主题标签设置" :visible.sync="labelVisible" width="500px" :close-on-click-modal="false" class="manage-dia" :before-close="closeLabel"> |
||||||
|
<div class="plus"> |
||||||
|
<i class="el-icon-circle-plus-outline" @click="addLabel"></i> |
||||||
|
</div> |
||||||
|
<el-table :data="labels" ref="table" header-align="center" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="labelName" label="主题名称" align="center" min-width="130"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input |
||||||
|
v-if="scope.row.edit" |
||||||
|
placeholder="请输入主题名称" |
||||||
|
v-model="scope.row.labelName" |
||||||
|
clearable |
||||||
|
maxlength="30" |
||||||
|
></el-input> |
||||||
|
<span v-else>{{ scope.row.labelName }}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="updateTime1" label="是否引用" align="center" min-width="60">否</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" min-width="60"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<i v-if="scope.row.edit" class="el-icon-check edit" @click="submitLabel(scope.row)"></i> |
||||||
|
<i v-else class="el-icon-edit edit" @click="editLabel(scope.row)"></i> |
||||||
|
<i class="el-icon-delete del" @click="delLabel(scope.row, scope.$index)"></i> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<span slot="footer"> |
||||||
|
<el-button @click="closeLabel">返回</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import Util from '@/libs/util' |
||||||
|
import { mapState } from 'vuex' |
||||||
|
import Editor from 'tinymce' |
||||||
|
import editorConfig from './editor' |
||||||
|
import Cropper from '@/components/img-upload/Cropper' |
||||||
|
import Axios from 'axios' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
headers: { |
||||||
|
token: sessionStorage.getItem('token') |
||||||
|
}, |
||||||
|
nameRepeat: false, |
||||||
|
sites: [], |
||||||
|
detailStyle: [], |
||||||
|
columns: [], |
||||||
|
articles: [], |
||||||
|
otherArticles: [], |
||||||
|
columnProps: { |
||||||
|
checkStrictly: true, |
||||||
|
value: 'id', |
||||||
|
label: 'columnName' |
||||||
|
}, |
||||||
|
links: [], |
||||||
|
article: '', |
||||||
|
otherColumns: [], |
||||||
|
otherLink: [], |
||||||
|
otherArticle: '', |
||||||
|
form: { |
||||||
|
id: this.$route.query.id || '', |
||||||
|
templateStatus: 0, |
||||||
|
articleTemplate: '', |
||||||
|
doi: '', |
||||||
|
quote: '', |
||||||
|
articleKeyWord: '', |
||||||
|
publicationTypeId: '', |
||||||
|
publicationYear: '', |
||||||
|
periodicalName: '', |
||||||
|
reel: '', |
||||||
|
documentNumber: '', |
||||||
|
activityEndTime: '', |
||||||
|
activityStartTime: '', |
||||||
|
time: '', |
||||||
|
lectureSeries: '', |
||||||
|
onlineLocation: '', |
||||||
|
offlineLocation: '', |
||||||
|
keynoteSpeaker: '', |
||||||
|
eventProfile: '', |
||||||
|
author: '', |
||||||
|
edit: '', |
||||||
|
audit: '', |
||||||
|
bannerImg: '', |
||||||
|
lableId: [], |
||||||
|
classificationId: '', |
||||||
|
columnId: +this.$route.query.columnId, |
||||||
|
file: '', |
||||||
|
isRelease: 0, |
||||||
|
mainBody: '', |
||||||
|
releaseTime: new Date(), |
||||||
|
source: '', |
||||||
|
summary : '', |
||||||
|
title: '', |
||||||
|
titleImg: '', |
||||||
|
connectionType : 1, |
||||||
|
linkAddress: '', |
||||||
|
siteSelection: '', |
||||||
|
fileList: [], |
||||||
|
isOpen: 1 |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
title: [ |
||||||
|
{ required: true, message: '请输入标题', trigger: 'blur' } |
||||||
|
], |
||||||
|
columnId: [ |
||||||
|
{ required: true, message: '请选择所属栏目', trigger: 'change' } |
||||||
|
], |
||||||
|
time: [ |
||||||
|
{ required: true, message: '请选择起始时间', trigger: 'change' } |
||||||
|
], |
||||||
|
classificationId: [ |
||||||
|
{ required: false, message: '请选择所属分类', trigger: 'change' } |
||||||
|
], |
||||||
|
keynoteSpeaker: [ |
||||||
|
{ required: true, message: '请输入主讲人', trigger: 'blur' } |
||||||
|
], |
||||||
|
eventProfile: [ |
||||||
|
{ required: true, message: '请输入活动简介', trigger: 'blur' } |
||||||
|
], |
||||||
|
releaseTime: [ |
||||||
|
{ required: true, message: '请选择发布日期', trigger: 'change' } |
||||||
|
], |
||||||
|
publicationYear: [ |
||||||
|
{ required: true, message: '请选择出版年份', trigger: 'change' } |
||||||
|
], |
||||||
|
titleImg: [ |
||||||
|
{ required: true, message: '请上传封面图', trigger: 'change' } |
||||||
|
], |
||||||
|
mainBody: [ |
||||||
|
{ required: true, message: '请输入正文', trigger: 'blur' } |
||||||
|
], |
||||||
|
connectionType: [ |
||||||
|
{ required: true, message: '请选择连接类型', trigger: 'blur' } |
||||||
|
], |
||||||
|
}, |
||||||
|
columnInfo: {}, |
||||||
|
editorConfig, |
||||||
|
submiting: false, // 新增编辑防抖标识 |
||||||
|
pass: false, |
||||||
|
uploading: 0, |
||||||
|
updateTime: 0, |
||||||
|
cropperModel: false, |
||||||
|
isUpload: false, |
||||||
|
fixedNumber: [1.76, 1], |
||||||
|
file: {}, // 当前被选择的图片文件 |
||||||
|
isBanner: 0, |
||||||
|
classifications: [], |
||||||
|
classVisible: false, |
||||||
|
labels: [], |
||||||
|
labelVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
Editor, |
||||||
|
Cropper |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
// 监听信息是否有更改,有的话页面离开的时候要询问是否要保存 |
||||||
|
form: { |
||||||
|
handler(val){ |
||||||
|
this.updateTime++ |
||||||
|
}, |
||||||
|
deep:true |
||||||
|
} |
||||||
|
}, |
||||||
|
// 页面离开的时候如果没有保存则提示 |
||||||
|
beforeRouteLeave(to, from, next) { |
||||||
|
if (this.submiting) { |
||||||
|
next() |
||||||
|
} else if (!this.pass) { |
||||||
|
// 更改了信息才需要提示 |
||||||
|
if (this.updateTime > 1) { |
||||||
|
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.submit(this.form.isRelease, next) |
||||||
|
}).catch(() => { |
||||||
|
next() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
next() |
||||||
|
} |
||||||
|
} else { |
||||||
|
next() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getArticle() |
||||||
|
this.getLabel() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 文章列表 |
||||||
|
getArticle() { |
||||||
|
this.$post(this.api.queryArticle, { |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 1000, |
||||||
|
title: '', |
||||||
|
isDisable: 0 |
||||||
|
}).then(({ data }) => { |
||||||
|
this[inner ? 'articles' : 'otherArticles'] = data.records.filter(e => e.isRelease) // 只显示已发布的文章 |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
// 获取所属分类 |
||||||
|
getClassification() { |
||||||
|
this.$post(`${this.api.queryClassif}?siteId=${this.site.id}&templateId=${this.columnInfo.templateId}`).then(({ data }) => { |
||||||
|
this.classifications = data |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
// 显示所属分类弹框 |
||||||
|
setClass() { |
||||||
|
this.classVisible = true |
||||||
|
}, |
||||||
|
// 新增所属分类 |
||||||
|
addClass() { |
||||||
|
this.classifications.push({ |
||||||
|
edit: true, |
||||||
|
id: '', |
||||||
|
classificationName: '' |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 编辑所属分类 |
||||||
|
editClass(row) { |
||||||
|
this.$set(row, 'edit', 1) |
||||||
|
}, |
||||||
|
// 删除所属分类 |
||||||
|
delClass(row, i) { |
||||||
|
if (row.id) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.delClassif}?id=${row.id}`).then(res => { |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.getClassification() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
this.classifications.splice(i, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 提交所属分类 |
||||||
|
submitClass(row, showMsg = 1) { |
||||||
|
if (!row.classificationName) return Util.errorMsg('请输入分类名称') |
||||||
|
this.$post(`${this.api.checkClassif}?classificationName=${row.classificationName}&siteId=${this.site.id}&classificationId=${row.id}`).then(res => { |
||||||
|
this.$post(this.api[row.id ? 'updateClassif' : 'saveClassif'], { |
||||||
|
classificationName: row.classificationName, |
||||||
|
templateId: this.columnInfo.templateId, |
||||||
|
id: row.id, |
||||||
|
siteId: this.site.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId |
||||||
|
}).then(res => { |
||||||
|
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功') |
||||||
|
this.getClassification() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(res => {}) |
||||||
|
}, |
||||||
|
// 关闭所属分类 |
||||||
|
closeClass() { |
||||||
|
const list = this.classifications |
||||||
|
if (list.find(e => e.edit && e.classificationName)) { |
||||||
|
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
list.map(e => { |
||||||
|
e.edit && e.classificationName && this.submitClass(e, 0) |
||||||
|
}) |
||||||
|
this.classVisible = false |
||||||
|
}).catch(() => { |
||||||
|
this.classVisible = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.classVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
// 获取标签 |
||||||
|
getLabel() { |
||||||
|
this.$post(`${this.api.queryLabel}?siteId=${this.site.id}`).then(({ data }) => { |
||||||
|
this.labels = data |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
// 显示标签弹框 |
||||||
|
setLabel() { |
||||||
|
this.labelVisible = true |
||||||
|
}, |
||||||
|
// 新增标签 |
||||||
|
addLabel() { |
||||||
|
this.labels.push({ |
||||||
|
edit: true, |
||||||
|
id: '', |
||||||
|
labelName: '' |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 编辑标签 |
||||||
|
editLabel(row) { |
||||||
|
this.$set(row, 'edit', 1) |
||||||
|
}, |
||||||
|
// 删除标签 |
||||||
|
delLabel(row, i) { |
||||||
|
if (row.id) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.delLabel}?id=${row.id}`).then(res => { |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.getLabel() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
this.labels.splice(i, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 提交标签 |
||||||
|
submitLabel(row, showMsg = 1) { |
||||||
|
if (!row.labelName) return Util.errorMsg('请输入主题名称') |
||||||
|
this.$post(`${this.api.checkLabel}?labelName=${row.labelName}&siteId=${this.site.id}&labelId=${row.id}`).then(res => { |
||||||
|
this.$post(this.api[row.id ? 'updateLabel' : 'saveLabel'], { |
||||||
|
labelName: row.labelName, |
||||||
|
id: row.id, |
||||||
|
siteId: this.site.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId |
||||||
|
}).then(res => { |
||||||
|
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功') |
||||||
|
this.getLabel() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(res => {}) |
||||||
|
}, |
||||||
|
// 关闭所属分类 |
||||||
|
closeLabel() { |
||||||
|
const list = this.labels |
||||||
|
if (list.find(e => e.edit && e.labelName)) { |
||||||
|
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
list.map(e => { |
||||||
|
e.edit && e.labelName && this.submitLabel(e, 0) |
||||||
|
}) |
||||||
|
this.labelVisible = false |
||||||
|
}).catch(() => { |
||||||
|
this.labelVisible = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.labelVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 文章名称判重 |
||||||
|
nameChange(){ |
||||||
|
const { title, level, id } = this.form |
||||||
|
if(title && title !== this.originalName){ |
||||||
|
this.$post(this.api.checkIfTheTitleIsRepeat, { |
||||||
|
siteId: this.site.id, |
||||||
|
title, |
||||||
|
id: id || '' |
||||||
|
}).then(res => { |
||||||
|
this.nameRepeat = false |
||||||
|
}).catch(res => { |
||||||
|
this.nameRepeat = true |
||||||
|
}) |
||||||
|
}else{ |
||||||
|
this.nameRepeat = false |
||||||
|
} |
||||||
|
}, |
||||||
|
// 图片裁剪上传事件 |
||||||
|
customUpload(data) { |
||||||
|
const formData = new FormData() |
||||||
|
formData.append('file', data, this.file.name) |
||||||
|
this.imgUpload(formData) |
||||||
|
}, |
||||||
|
// 压缩图片 |
||||||
|
compress(img) { |
||||||
|
const canvas = document.createElement('canvas') |
||||||
|
const ctx = canvas.getContext('2d') |
||||||
|
// let initSize = img.src.length; |
||||||
|
const width = img.width |
||||||
|
const height = img.height |
||||||
|
canvas.width = width |
||||||
|
canvas.height = height |
||||||
|
// 铺底色 |
||||||
|
ctx.fillStyle = '#fff' |
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height) |
||||||
|
ctx.drawImage(img, 0, 0, width, height) |
||||||
|
// 进行压缩 |
||||||
|
const ndata = canvas.toDataURL('image/jpeg', 0.8) |
||||||
|
return ndata |
||||||
|
}, |
||||||
|
// base64转成bolb对象 |
||||||
|
dataURItoBlob(base64Data) { |
||||||
|
let byteString |
||||||
|
if (base64Data.split(',')[0].indexOf('base64') >= 0) { |
||||||
|
byteString = atob(base64Data.split(',')[1]) |
||||||
|
} else { |
||||||
|
byteString = unescape(base64Data.split(',')[1]) |
||||||
|
} |
||||||
|
const mimeString = base64Data |
||||||
|
.split(',')[0] |
||||||
|
.split(':')[1] |
||||||
|
.split(';')[0] |
||||||
|
const ia = new Uint8Array(byteString.length) |
||||||
|
for (let i = 0; i < byteString.length; i++) { |
||||||
|
ia[i] = byteString.charCodeAt(i) |
||||||
|
} |
||||||
|
return new Blob([ia], { |
||||||
|
type: mimeString |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 图片上传到服务器 |
||||||
|
imgUpload(formData) { |
||||||
|
this.isUpload = true |
||||||
|
Axios({ |
||||||
|
method: 'post', |
||||||
|
url: this.api.upload, |
||||||
|
data: formData, |
||||||
|
headers: { |
||||||
|
'Content-Type': 'multipart/form-data', |
||||||
|
token: Util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
}).then(({ data }) => { |
||||||
|
let url = this.form[this.isBanner ? 'bannerImg' : 'titleImg'] |
||||||
|
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => {}).catch(e => {}) // 删除替换掉的图片 |
||||||
|
this.form[this.isBanner ? 'bannerImg' : 'titleImg'] = data.url |
||||||
|
}).catch(res => {}) |
||||||
|
this.$refs.cropper.isDisabled = false |
||||||
|
this.isUpload = false |
||||||
|
this.cropperModel = false |
||||||
|
}, |
||||||
|
// 图片改变钩子 |
||||||
|
changeFile(file, isBanner) { |
||||||
|
this.fixedNumber = isBanner ? [1, 0.26] : [1.76, 1] |
||||||
|
this.isBanner = isBanner |
||||||
|
const { size, name } = file |
||||||
|
const ext = name.substring(name.lastIndexOf('.') + 1) |
||||||
|
if (!Util.isImg(ext)) { |
||||||
|
this.$message.error('请上传图片!') |
||||||
|
return false |
||||||
|
} |
||||||
|
// if (size / 1024 / 1024 > 5) { |
||||||
|
// this.$message.error('请上传5M以内的图片!') |
||||||
|
// return false |
||||||
|
// } |
||||||
|
this.file = file |
||||||
|
this.cropperModel = true |
||||||
|
this.$nextTick(() => { |
||||||
|
this.$refs.cropper.updateImg({ |
||||||
|
url: window.URL.createObjectURL(file.raw), |
||||||
|
size: file.size |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 附件删除 |
||||||
|
handleRemove(e, fileList) { |
||||||
|
e.id ? this.$post(`${this.api.delContentFile}?id=${e.id}`).then(res => { |
||||||
|
this.form.fileList = fileList |
||||||
|
}).catch(res => {}) : (this.form.fileList = fileList) |
||||||
|
}, |
||||||
|
// banner上传成功 |
||||||
|
uploadSuccessBanner(res) { |
||||||
|
let url = this.form.bannerImg |
||||||
|
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => {}).catch(e => {}) |
||||||
|
this.form.bannerImg = res.url |
||||||
|
}, |
||||||
|
// 附件上传之前的钩子 |
||||||
|
fileBeforeUpload(file) { |
||||||
|
this.uploading++ |
||||||
|
}, |
||||||
|
// 附件上传成功 |
||||||
|
uploadSuccessFile(res) { |
||||||
|
this.uploading-- |
||||||
|
this.form.id ? |
||||||
|
this.$post(this.api.saveContentFile, { |
||||||
|
contentId: this.form.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId, |
||||||
|
id: '', |
||||||
|
fileName: res.original, |
||||||
|
filePath: res.url |
||||||
|
}).then(({ data }) => { |
||||||
|
this.form.fileList.push({ |
||||||
|
name: res.original, |
||||||
|
url: res.url, |
||||||
|
id: data |
||||||
|
}) |
||||||
|
}).catch(res => {}) : |
||||||
|
this.form.fileList.push({ |
||||||
|
name: res.original, |
||||||
|
url: res.url |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 预览 |
||||||
|
preview() { |
||||||
|
window.open((Setting.isDev ? `http://${location.hostname}:8095` : this.$store.state.content.site.domainName) + `#/article?articleId=${this.form.id}&siteId=${this.form.siteId}&id=${this.form.columnId}`) |
||||||
|
}, |
||||||
|
// 返回 |
||||||
|
back() { |
||||||
|
this.pass = true |
||||||
|
const { updateTime } = this |
||||||
|
// 更改了信息才需要提示 |
||||||
|
if (updateTime > 1) { |
||||||
|
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.submit(this.form.isRelease) |
||||||
|
}).catch(() => { |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.$router.back() |
||||||
|
} |
||||||
|
}, |
||||||
|
// 更新附件的状态为发布 |
||||||
|
updateFile(files, form, quoteId) { |
||||||
|
files.map(e => { |
||||||
|
this.$post(this.api.updateFile, { |
||||||
|
id: e, |
||||||
|
isRelease: form.isRelease, |
||||||
|
quote: form.title, |
||||||
|
quoteId |
||||||
|
}).then(res => {}).catch(err => {}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 提交 |
||||||
|
submit(isRelease, next) { |
||||||
|
if (this.submiting) return false |
||||||
|
const form = JSON.parse(JSON.stringify(this.form)) |
||||||
|
if (!form.title) return Util.errorMsg('请填写标题') |
||||||
|
if (this.nameRepeat) return Util.errorMsg('该标题已重复!') |
||||||
|
if (typeof form.fatherId === 'object') form.fatherId = form.fatherId[form.fatherId.length - 1] |
||||||
|
const tId = form.articleTemplate |
||||||
|
// 如果是发布 |
||||||
|
if (isRelease) { |
||||||
|
if (tId !== 25) { |
||||||
|
if (!form.releaseTime) return Util.errorMsg('请选择发布日期') |
||||||
|
} |
||||||
|
if (tId === 22 || tId === 23 || tId === 24) { |
||||||
|
if (!form.titleImg ) return Util.errorMsg('请上传封面') |
||||||
|
} |
||||||
|
if (tId === 25) { |
||||||
|
if ((!form.time || !form.time.length) && isRelease) return Util.errorMsg('请选择起止时间') |
||||||
|
form.activityStartTime = form.time[0] |
||||||
|
form.activityEndTime = form.time[1] |
||||||
|
} |
||||||
|
if (tId === 24 && form.connectionType !== 2) { |
||||||
|
if (form.connectionType === 1) { |
||||||
|
if (!this.links.length) return Util.errorMsg('请选择站内链接') |
||||||
|
} |
||||||
|
if (!this.otherLink.length && form.connectionType === 3) { |
||||||
|
if (!this.otherLink.length) return Util.errorMsg('请选择栏目') |
||||||
|
} |
||||||
|
} |
||||||
|
if ((tId === 22 || tId === 23 || tId === 25) && !form.mainBody) return Util.errorMsg('请输入正文') |
||||||
|
} |
||||||
|
if (this.uploading) return Util.errorMsg('文件正在上传,请上传完成后再发布') |
||||||
|
if (form.connectionType === 1) { |
||||||
|
form.linkAddress = this.links.join() |
||||||
|
if (this.article) form.linkAddress += '-' + this.article |
||||||
|
} else if (form.connectionType === 3) { |
||||||
|
form.linkAddress = this.otherLink.join() |
||||||
|
if (this.otherArticle) form.linkAddress += '-' + this.otherArticle |
||||||
|
} |
||||||
|
const { columnId, bannerImg, fileList, titleImg } = form |
||||||
|
const fileId = [] |
||||||
|
if (typeof columnId === 'object') form.columnId = columnId[columnId.length - 1] // 如果更换了栏目id,值会变成数组,需要手动获取最后一个 |
||||||
|
// 获取几个附件的id,url后面的数字串即是附件id |
||||||
|
if (bannerImg) fileId.push(bannerImg.substr(bannerImg.lastIndexOf('/') + 1)) |
||||||
|
if (titleImg) fileId.push(titleImg.substr(titleImg.lastIndexOf('/') + 1)) |
||||||
|
fileList && fileList.map(e => { |
||||||
|
fileId.push(e[e.url ? 'url' : 'filePath'].substr(e[e.url ? 'url' : 'filePath'].lastIndexOf('/') + 1)) |
||||||
|
}) |
||||||
|
form.lableId = form.lableId.join(',') |
||||||
|
|
||||||
|
form.releaseTime = Util.formatDate('yyyy-MM-dd', new Date(form.releaseTime)) // 发布日期转化为年月日格式 |
||||||
|
|
||||||
|
form.isRelease = isRelease |
||||||
|
this.submiting = true |
||||||
|
if (form.id) { |
||||||
|
delete form.children |
||||||
|
form.editorId = +this.$store.state.user.userId |
||||||
|
this.$post(this.api.updateArticle, form).then(res => { |
||||||
|
this.updateFile(fileId, form, form.id) |
||||||
|
Util.successMsg('修改成功') |
||||||
|
next ? next() : this.$router.push(`list?columnId=` + form.columnId) |
||||||
|
}).catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.$post(this.api.saveArticle, form).then(({ data }) => { |
||||||
|
this.updateFile(fileId, form, data) |
||||||
|
// 新增文章完后需要把上传的附件添加到文章附件表 |
||||||
|
form.fileList.map(e => { |
||||||
|
this.$post(this.api.saveContentFile, { |
||||||
|
contentId: data, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId, |
||||||
|
id: '', |
||||||
|
fileName: e.name, |
||||||
|
filePath: e.url |
||||||
|
}).then(res => {}).catch(err => {}) |
||||||
|
}) |
||||||
|
Util.successMsg('创建成功') |
||||||
|
next ? next() : this.$router.back() |
||||||
|
}).catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$upload-width: 220px; |
||||||
|
$upload-height: 102px; |
||||||
|
$upload-lg-height: 102px; |
||||||
|
/deep/ .avatar-uploader { |
||||||
|
.el-upload { |
||||||
|
position: relative; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
border: 1px solid #DCDEE0; |
||||||
|
border-radius: 2px; |
||||||
|
cursor: pointer; |
||||||
|
overflow: hidden; |
||||||
|
.uploader-default { |
||||||
|
display: flex; |
||||||
|
height: $upload-height; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
text-align: center; |
||||||
|
background: #FAFAFA; |
||||||
|
p { |
||||||
|
margin-top: 10px; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
line-height: 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&.avatar-uploader-lg { |
||||||
|
.el-upload { |
||||||
|
width: 100%; |
||||||
|
max-width: 820px; |
||||||
|
height: $upload-lg-height; |
||||||
|
|
||||||
|
.uploader-default { |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.avatar { |
||||||
|
display: block; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
} |
||||||
|
.avatar-lg { |
||||||
|
display: block; |
||||||
|
width: 100%; |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
.el-upload__tip { |
||||||
|
margin-top: 0; |
||||||
|
p { |
||||||
|
font-size: 12px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.style-wrap { |
||||||
|
display: flex; |
||||||
|
margin-top: 10px; |
||||||
|
.label { |
||||||
|
margin-right: 30px; |
||||||
|
} |
||||||
|
} |
||||||
|
.styles { |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
width: 955px; |
||||||
|
// height: 320px; |
||||||
|
margin-top: 20px; |
||||||
|
overflow: auto; |
||||||
|
li { |
||||||
|
margin: 0 20px 10px 0; |
||||||
|
text-align: center; |
||||||
|
cursor: pointer; |
||||||
|
&:hover .review { |
||||||
|
border-color: #2962FF; |
||||||
|
} |
||||||
|
} |
||||||
|
.review { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
width: 170px; |
||||||
|
height: 112px; |
||||||
|
margin-bottom: 10px; |
||||||
|
border: 1px solid #DCDEE0; |
||||||
|
border-radius: 2px; |
||||||
|
img { |
||||||
|
width: 80px; |
||||||
|
} |
||||||
|
.is-link { |
||||||
|
width: 50px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.info { |
||||||
|
position: absolute; |
||||||
|
top: 8px; |
||||||
|
left: -32px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.plus { |
||||||
|
margin-bottom: 10px; |
||||||
|
font-size: 18px; |
||||||
|
color: #2962FF; |
||||||
|
text-align: right; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.set-btn { |
||||||
|
margin-left: 10px !important; |
||||||
|
} |
||||||
|
.manage-dia { |
||||||
|
.edit, .del { |
||||||
|
font-size: 14px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.edit { |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
.input-form { |
||||||
|
&.model { |
||||||
|
height: calc(100vh - 200px); |
||||||
|
padding-right: 20px; |
||||||
|
overflow: auto; |
||||||
|
.el-form-item__label { |
||||||
|
padding-right: 20px; |
||||||
|
} |
||||||
|
.lg .el-form-item__label { |
||||||
|
padding-right: 43px; |
||||||
|
} |
||||||
|
} |
||||||
|
.item-line { |
||||||
|
display: flex; |
||||||
|
.el-form-item:not(:last-child) { |
||||||
|
margin-right: 200px; |
||||||
|
} |
||||||
|
} |
||||||
|
.line { |
||||||
|
margin-bottom: 24px; |
||||||
|
border-bottom: 1px dashed #C2C2C2; |
||||||
|
} |
||||||
|
.el-form-item--small.el-form-item { |
||||||
|
margin-bottom: 24px; |
||||||
|
} |
||||||
|
.el-input, .el-select { |
||||||
|
width: 300px; |
||||||
|
} |
||||||
|
.el-select .el-input { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
.el-textarea { |
||||||
|
width: 550px; |
||||||
|
} |
||||||
|
.auto, .auto .el-input { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
.el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label:before { |
||||||
|
font-size: 18px; |
||||||
|
vertical-align: -4px; |
||||||
|
color: #F5222D; |
||||||
|
} |
||||||
|
} |
||||||
|
.btns { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,187 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<div class="tool"> |
||||||
|
<div class="search-wrap"> |
||||||
|
<el-input class="keyword" placeholder="请输入标题" v-model.trim="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
<div class="actions"> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:删除'" @click="batchDel">批量删除</el-button> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:新增'" type="primary" @click="add" >新增文章</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="list" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column show-overflow-tooltip prop="title" label="标题" align="center" min-width="150"></el-table-column> |
||||||
|
<el-table-column prop="classificationName" label="所属分类" align="center" min-width="120" sortable="custom"></el-table-column> |
||||||
|
<el-table-column prop="founderName" label="录入人" align="center" min-width="80"></el-table-column> |
||||||
|
<el-table-column prop="editorName" label="修改人" align="center" min-width="80"></el-table-column> |
||||||
|
<el-table-column prop="updateTime" label="修改日期" align="center" min-width="150"></el-table-column> |
||||||
|
<el-table-column prop="releaseTime" label="发布日期" align="center" min-width="100"></el-table-column> |
||||||
|
<el-table-column prop="totalBrowsing" label="已学习人数" align="center" min-width="70"></el-table-column> |
||||||
|
<el-table-column prop="workNumber" label="状态" align="center" min-width="80"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{ scope.row.isRelease ? '已发布' : '草稿' }} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="170"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:编辑'" type="text" @click="edit(scope.row)">编辑</el-button> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button> |
||||||
|
<el-switch |
||||||
|
class="m-l-10" |
||||||
|
v-model="scope.row.isDisable" |
||||||
|
:active-value="0" |
||||||
|
:inactive-value="1" |
||||||
|
@change="switchOff($event, scope.row, scope.$index)"> |
||||||
|
</el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import util from '@/libs/util' |
||||||
|
import { mapMutations } from 'vuex' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
list: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
modifiedTimeSort: '', |
||||||
|
publicationTimeSort: '', |
||||||
|
ordinalSort: 0, |
||||||
|
multipleSelection: [], |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.initData() |
||||||
|
}, 500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
// this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 文章列表 |
||||||
|
getData() { |
||||||
|
const { keyword } = this |
||||||
|
const data = { |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
ordinalSort: this.ordinalSort, |
||||||
|
title: this.field === 'title' ? keyword : '', |
||||||
|
founder: this.field === 'founder' ? keyword : '', |
||||||
|
column: this.field === 'column' ? keyword : '', |
||||||
|
editor: this.field === 'editor' ? keyword : '' |
||||||
|
} |
||||||
|
if (this.modifiedTimeSort !== '') data.modifiedTimeSort = this.modifiedTimeSort |
||||||
|
if (this.publicationTimeSort !== '') data.publicationTimeSort = this.publicationTimeSort |
||||||
|
this.$post(this.api.queryArticle, data).then(({ data }) => { |
||||||
|
this.list = data.records |
||||||
|
this.total = +data.total |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
currentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
initData() { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.page = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
// 批量删除 |
||||||
|
batchDel() { |
||||||
|
const list = this.multipleSelection |
||||||
|
if (list.length) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
const data = [] |
||||||
|
list.map(e => { |
||||||
|
data.push('ids=' + e.id) |
||||||
|
}) |
||||||
|
this.$post(`${this.api.deleteArticle}?${data.join('&')}`).then(res => { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
util.successMsg("删除成功") |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
util.errorMsg('请先选择数据 !') |
||||||
|
} |
||||||
|
}, |
||||||
|
// 删除 |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.deleteArticle}?ids=${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
}, |
||||||
|
// 禁用启用 |
||||||
|
switchOff(val, row) { |
||||||
|
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => {}).catch((res) => {}) |
||||||
|
}, |
||||||
|
// 新增 |
||||||
|
add() { |
||||||
|
this.$router.push(`/schemeSet`) |
||||||
|
}, |
||||||
|
// 排序回调 |
||||||
|
sortChange(column) { |
||||||
|
const { order } = column |
||||||
|
// 三个排序只能同时传1个,所以点了一个排序的时候要清除掉其余两个 |
||||||
|
// 两个时间0默认倒序 1升序 |
||||||
|
if (column.prop === 'updateTime') { |
||||||
|
this.modifiedTimeSort = order ? order === 'ascending' ? 1 : 0 : '' |
||||||
|
if (order) { |
||||||
|
this.publicationTimeSort = '' |
||||||
|
this.ordinalSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
if (column.prop === 'releaseTime') { |
||||||
|
this.publicationTimeSort = order ? order === 'ascending' ? 1 : 0 : '' |
||||||
|
if (order) { |
||||||
|
this.modifiedTimeSort = '' |
||||||
|
this.ordinalSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
// 序号排序 0默认升序 1倒序 |
||||||
|
if (column.prop === 'sequence') { |
||||||
|
this.ordinalSort = order ? order === 'ascending' ? 0 : 1 : '' |
||||||
|
if (order) { |
||||||
|
this.publicationTimeSort = '' |
||||||
|
this.modifiedTimeSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
// 编辑 |
||||||
|
edit(row) { |
||||||
|
this.$router.push(`add?id=${row.id}&columnId=${this.$refs.column.getCurrentKey()}&columnName=${this.$refs.column.getCurrentNode().columnName}`) |
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,187 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<div class="tool"> |
||||||
|
<div class="search-wrap"> |
||||||
|
<el-input class="keyword" placeholder="请输入标题" v-model.trim="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
<div class="actions"> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:删除'" @click="batchDel">批量删除</el-button> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:新增'" type="primary" @click="add" >新增文章</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="list" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column show-overflow-tooltip prop="title" label="标题" align="center" min-width="150"></el-table-column> |
||||||
|
<el-table-column prop="classificationName" label="所属分类" align="center" min-width="120" sortable="custom"></el-table-column> |
||||||
|
<el-table-column prop="founderName" label="录入人" align="center" min-width="80"></el-table-column> |
||||||
|
<el-table-column prop="editorName" label="修改人" align="center" min-width="80"></el-table-column> |
||||||
|
<el-table-column prop="updateTime" label="修改日期" align="center" min-width="150"></el-table-column> |
||||||
|
<el-table-column prop="releaseTime" label="发布日期" align="center" min-width="100"></el-table-column> |
||||||
|
<el-table-column prop="totalBrowsing" label="总浏览" align="center" min-width="70"></el-table-column> |
||||||
|
<el-table-column prop="workNumber" label="状态" align="center" min-width="80"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{ scope.row.isRelease ? '已发布' : '草稿' }} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="170"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:编辑'" type="text" @click="edit(scope.row)">编辑</el-button> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button> |
||||||
|
<el-switch |
||||||
|
class="m-l-10" |
||||||
|
v-model="scope.row.isDisable" |
||||||
|
:active-value="0" |
||||||
|
:inactive-value="1" |
||||||
|
@change="switchOff($event, scope.row, scope.$index)"> |
||||||
|
</el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import util from '@/libs/util' |
||||||
|
import { mapMutations } from 'vuex' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
list: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
modifiedTimeSort: '', |
||||||
|
publicationTimeSort: '', |
||||||
|
ordinalSort: 0, |
||||||
|
multipleSelection: [], |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.initData() |
||||||
|
}, 500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
// this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 文章列表 |
||||||
|
getData() { |
||||||
|
const { keyword } = this |
||||||
|
const data = { |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
ordinalSort: this.ordinalSort, |
||||||
|
title: this.field === 'title' ? keyword : '', |
||||||
|
founder: this.field === 'founder' ? keyword : '', |
||||||
|
column: this.field === 'column' ? keyword : '', |
||||||
|
editor: this.field === 'editor' ? keyword : '' |
||||||
|
} |
||||||
|
if (this.modifiedTimeSort !== '') data.modifiedTimeSort = this.modifiedTimeSort |
||||||
|
if (this.publicationTimeSort !== '') data.publicationTimeSort = this.publicationTimeSort |
||||||
|
this.$post(this.api.queryArticle, data).then(({ data }) => { |
||||||
|
this.list = data.records |
||||||
|
this.total = +data.total |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
currentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
initData() { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.page = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
// 批量删除 |
||||||
|
batchDel() { |
||||||
|
const list = this.multipleSelection |
||||||
|
if (list.length) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
const data = [] |
||||||
|
list.map(e => { |
||||||
|
data.push('ids=' + e.id) |
||||||
|
}) |
||||||
|
this.$post(`${this.api.deleteArticle}?${data.join('&')}`).then(res => { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
util.successMsg("删除成功") |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
util.errorMsg('请先选择数据 !') |
||||||
|
} |
||||||
|
}, |
||||||
|
// 删除 |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.deleteArticle}?ids=${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
}, |
||||||
|
// 禁用启用 |
||||||
|
switchOff(val, row) { |
||||||
|
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => {}).catch((res) => {}) |
||||||
|
}, |
||||||
|
// 新增 |
||||||
|
add() { |
||||||
|
this.$router.push(`/learnMg`) |
||||||
|
}, |
||||||
|
// 排序回调 |
||||||
|
sortChange(column) { |
||||||
|
const { order } = column |
||||||
|
// 三个排序只能同时传1个,所以点了一个排序的时候要清除掉其余两个 |
||||||
|
// 两个时间0默认倒序 1升序 |
||||||
|
if (column.prop === 'updateTime') { |
||||||
|
this.modifiedTimeSort = order ? order === 'ascending' ? 1 : 0 : '' |
||||||
|
if (order) { |
||||||
|
this.publicationTimeSort = '' |
||||||
|
this.ordinalSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
if (column.prop === 'releaseTime') { |
||||||
|
this.publicationTimeSort = order ? order === 'ascending' ? 1 : 0 : '' |
||||||
|
if (order) { |
||||||
|
this.modifiedTimeSort = '' |
||||||
|
this.ordinalSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
// 序号排序 0默认升序 1倒序 |
||||||
|
if (column.prop === 'sequence') { |
||||||
|
this.ordinalSort = order ? order === 'ascending' ? 0 : 1 : '' |
||||||
|
if (order) { |
||||||
|
this.publicationTimeSort = '' |
||||||
|
this.modifiedTimeSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
// 编辑 |
||||||
|
edit(row) { |
||||||
|
this.$router.push(`add?id=${row.id}&columnId=${this.$refs.column.getCurrentKey()}&columnName=${this.$refs.column.getCurrentNode().columnName}`) |
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,891 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<p class="page-name mb">方案设置</p> |
||||||
|
<el-form :model="form" :rules="rules" class="input-form model" label-width="140px"> |
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item prop="source" label="标题"> |
||||||
|
<el-input |
||||||
|
placeholder="请输入标题" |
||||||
|
v-model.trim="form.source" |
||||||
|
clearable |
||||||
|
maxlength="30" |
||||||
|
class="inline-input" |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="author" label="所属分类"> |
||||||
|
<el-select style="width: 234px;" v-model="form.classificationId"> |
||||||
|
<template v-for="item in classifications"> |
||||||
|
<el-option |
||||||
|
v-if="item.id" |
||||||
|
:key="item.id" |
||||||
|
:label="item.classificationName" |
||||||
|
:value="item.id"> |
||||||
|
</el-option> |
||||||
|
</template> |
||||||
|
</el-select> |
||||||
|
<el-button class="set-btn" type="primary" @click="setClass">设置</el-button> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<el-form-item prop="summary" label="适用专业"> |
||||||
|
<el-input |
||||||
|
style="width: 940px" |
||||||
|
type="textarea" |
||||||
|
v-model.trim="form.summary" |
||||||
|
:rows="3" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="summary" label="产品"> |
||||||
|
<el-input |
||||||
|
style="width: 940px" |
||||||
|
type="textarea" |
||||||
|
v-model.trim="form.summary" |
||||||
|
:rows="3" |
||||||
|
clearable |
||||||
|
></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="file" label="文件上传"> |
||||||
|
<el-upload |
||||||
|
:before-upload="fileBeforeUpload" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-success="uploadSuccessFile" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:file-list="form.fileList" |
||||||
|
:headers="headers" |
||||||
|
> |
||||||
|
<el-button>上传</el-button> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div class="btns"> |
||||||
|
<el-button type="primary" @click="submit(1)">发布</el-button> |
||||||
|
<el-button @click="submit(0)">保存草稿</el-button> |
||||||
|
<el-button @click="back">取消</el-button> |
||||||
|
</div> |
||||||
|
<!-- 剪裁组件弹窗 --> |
||||||
|
<el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false"> |
||||||
|
<Cropper |
||||||
|
ref="cropper" |
||||||
|
:img-file.sync="file" |
||||||
|
:is-upload="isUpload" |
||||||
|
:fixed="true" |
||||||
|
:fixedNumber.sync="fixedNumber" |
||||||
|
@upload="customUpload" /> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="所属分类设置" :visible.sync="classVisible" width="500px" :close-on-click-modal="false" class="manage-dia" :before-close="closeClass"> |
||||||
|
<div class="plus"> |
||||||
|
<i class="el-icon-circle-plus-outline" @click="addClass"></i> |
||||||
|
</div> |
||||||
|
<el-table :data="classifications" ref="table" header-align="center" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="classificationName" label="分类名称" align="center" min-width="130"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input |
||||||
|
v-if="scope.row.edit" |
||||||
|
placeholder="请输入分类名称" |
||||||
|
v-model="scope.row.classificationName" |
||||||
|
clearable |
||||||
|
maxlength="30" |
||||||
|
></el-input> |
||||||
|
<span v-else>{{ scope.row.classificationName }}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="updateTime1" label="是否引用" align="center" min-width="60">否</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" min-width="60"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<i v-if="scope.row.edit" class="el-icon-check edit" @click="submitClass(scope.row)"></i> |
||||||
|
<i v-else class="el-icon-edit edit" @click="editClass(scope.row)"></i> |
||||||
|
<i class="el-icon-delete del" @click="delClass(scope.row, scope.$index)"></i> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<span slot="footer"> |
||||||
|
<el-button @click="closeClass">返回</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="主题标签设置" :visible.sync="labelVisible" width="500px" :close-on-click-modal="false" class="manage-dia" :before-close="closeLabel"> |
||||||
|
<div class="plus"> |
||||||
|
<i class="el-icon-circle-plus-outline" @click="addLabel"></i> |
||||||
|
</div> |
||||||
|
<el-table :data="labels" ref="table" header-align="center" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="labelName" label="主题名称" align="center" min-width="130"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input |
||||||
|
v-if="scope.row.edit" |
||||||
|
placeholder="请输入主题名称" |
||||||
|
v-model="scope.row.labelName" |
||||||
|
clearable |
||||||
|
maxlength="30" |
||||||
|
></el-input> |
||||||
|
<span v-else>{{ scope.row.labelName }}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="updateTime1" label="是否引用" align="center" min-width="60">否</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" min-width="60"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<i v-if="scope.row.edit" class="el-icon-check edit" @click="submitLabel(scope.row)"></i> |
||||||
|
<i v-else class="el-icon-edit edit" @click="editLabel(scope.row)"></i> |
||||||
|
<i class="el-icon-delete del" @click="delLabel(scope.row, scope.$index)"></i> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<span slot="footer"> |
||||||
|
<el-button @click="closeLabel">返回</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import Util from '@/libs/util' |
||||||
|
import { mapState } from 'vuex' |
||||||
|
import Editor from 'tinymce' |
||||||
|
import editorConfig from './editor' |
||||||
|
import Cropper from '@/components/img-upload/Cropper' |
||||||
|
import Axios from 'axios' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
headers: { |
||||||
|
token: sessionStorage.getItem('token') |
||||||
|
}, |
||||||
|
nameRepeat: false, |
||||||
|
sites: [], |
||||||
|
detailStyle: [], |
||||||
|
columns: [], |
||||||
|
articles: [], |
||||||
|
otherArticles: [], |
||||||
|
columnProps: { |
||||||
|
checkStrictly: true, |
||||||
|
value: 'id', |
||||||
|
label: 'columnName' |
||||||
|
}, |
||||||
|
links: [], |
||||||
|
article: '', |
||||||
|
otherColumns: [], |
||||||
|
otherLink: [], |
||||||
|
otherArticle: '', |
||||||
|
form: { |
||||||
|
id: this.$route.query.id || '', |
||||||
|
templateStatus: 0, |
||||||
|
articleTemplate: '', |
||||||
|
doi: '', |
||||||
|
quote: '', |
||||||
|
articleKeyWord: '', |
||||||
|
publicationTypeId: '', |
||||||
|
publicationYear: '', |
||||||
|
periodicalName: '', |
||||||
|
reel: '', |
||||||
|
documentNumber: '', |
||||||
|
activityEndTime: '', |
||||||
|
activityStartTime: '', |
||||||
|
time: '', |
||||||
|
lectureSeries: '', |
||||||
|
onlineLocation: '', |
||||||
|
offlineLocation: '', |
||||||
|
keynoteSpeaker: '', |
||||||
|
eventProfile: '', |
||||||
|
author: '', |
||||||
|
edit: '', |
||||||
|
audit: '', |
||||||
|
bannerImg: '', |
||||||
|
lableId: [], |
||||||
|
classificationId: '', |
||||||
|
columnId: +this.$route.query.columnId, |
||||||
|
file: '', |
||||||
|
isRelease: 0, |
||||||
|
mainBody: '', |
||||||
|
releaseTime: new Date(), |
||||||
|
source: '', |
||||||
|
summary : '', |
||||||
|
title: '', |
||||||
|
titleImg: '', |
||||||
|
connectionType : 1, |
||||||
|
linkAddress: '', |
||||||
|
siteSelection: '', |
||||||
|
fileList: [], |
||||||
|
isOpen: 1 |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
title: [ |
||||||
|
{ required: true, message: '请输入标题', trigger: 'blur' } |
||||||
|
], |
||||||
|
columnId: [ |
||||||
|
{ required: true, message: '请选择所属栏目', trigger: 'change' } |
||||||
|
], |
||||||
|
time: [ |
||||||
|
{ required: true, message: '请选择起始时间', trigger: 'change' } |
||||||
|
], |
||||||
|
classificationId: [ |
||||||
|
{ required: false, message: '请选择所属分类', trigger: 'change' } |
||||||
|
], |
||||||
|
keynoteSpeaker: [ |
||||||
|
{ required: true, message: '请输入主讲人', trigger: 'blur' } |
||||||
|
], |
||||||
|
eventProfile: [ |
||||||
|
{ required: true, message: '请输入活动简介', trigger: 'blur' } |
||||||
|
], |
||||||
|
releaseTime: [ |
||||||
|
{ required: true, message: '请选择发布日期', trigger: 'change' } |
||||||
|
], |
||||||
|
publicationYear: [ |
||||||
|
{ required: true, message: '请选择出版年份', trigger: 'change' } |
||||||
|
], |
||||||
|
titleImg: [ |
||||||
|
{ required: true, message: '请上传封面图', trigger: 'change' } |
||||||
|
], |
||||||
|
mainBody: [ |
||||||
|
{ required: true, message: '请输入正文', trigger: 'blur' } |
||||||
|
], |
||||||
|
connectionType: [ |
||||||
|
{ required: true, message: '请选择连接类型', trigger: 'blur' } |
||||||
|
], |
||||||
|
}, |
||||||
|
columnInfo: {}, |
||||||
|
editorConfig, |
||||||
|
submiting: false, // 新增编辑防抖标识 |
||||||
|
pass: false, |
||||||
|
uploading: 0, |
||||||
|
updateTime: 0, |
||||||
|
cropperModel: false, |
||||||
|
isUpload: false, |
||||||
|
fixedNumber: [1.76, 1], |
||||||
|
file: {}, // 当前被选择的图片文件 |
||||||
|
isBanner: 0, |
||||||
|
classifications: [], |
||||||
|
classVisible: false, |
||||||
|
labels: [], |
||||||
|
labelVisible: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
Editor, |
||||||
|
Cropper |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
// 监听信息是否有更改,有的话页面离开的时候要询问是否要保存 |
||||||
|
form: { |
||||||
|
handler(val){ |
||||||
|
this.updateTime++ |
||||||
|
}, |
||||||
|
deep:true |
||||||
|
} |
||||||
|
}, |
||||||
|
// 页面离开的时候如果没有保存则提示 |
||||||
|
beforeRouteLeave(to, from, next) { |
||||||
|
if (this.submiting) { |
||||||
|
next() |
||||||
|
} else if (!this.pass) { |
||||||
|
// 更改了信息才需要提示 |
||||||
|
if (this.updateTime > 1) { |
||||||
|
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.submit(this.form.isRelease, next) |
||||||
|
}).catch(() => { |
||||||
|
next() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
next() |
||||||
|
} |
||||||
|
} else { |
||||||
|
next() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getArticle() |
||||||
|
this.getLabel() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 文章列表 |
||||||
|
getArticle() { |
||||||
|
this.$post(this.api.queryArticle, { |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 1000, |
||||||
|
title: '', |
||||||
|
isDisable: 0 |
||||||
|
}).then(({ data }) => { |
||||||
|
this[inner ? 'articles' : 'otherArticles'] = data.records.filter(e => e.isRelease) // 只显示已发布的文章 |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
// 获取所属分类 |
||||||
|
getClassification() { |
||||||
|
this.$post(`${this.api.queryClassif}?siteId=${this.site.id}&templateId=${this.columnInfo.templateId}`).then(({ data }) => { |
||||||
|
this.classifications = data |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
// 显示所属分类弹框 |
||||||
|
setClass() { |
||||||
|
this.classVisible = true |
||||||
|
}, |
||||||
|
// 新增所属分类 |
||||||
|
addClass() { |
||||||
|
this.classifications.push({ |
||||||
|
edit: true, |
||||||
|
id: '', |
||||||
|
classificationName: '' |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 编辑所属分类 |
||||||
|
editClass(row) { |
||||||
|
this.$set(row, 'edit', 1) |
||||||
|
}, |
||||||
|
// 删除所属分类 |
||||||
|
delClass(row, i) { |
||||||
|
if (row.id) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.delClassif}?id=${row.id}`).then(res => { |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.getClassification() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
this.classifications.splice(i, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 提交所属分类 |
||||||
|
submitClass(row, showMsg = 1) { |
||||||
|
if (!row.classificationName) return Util.errorMsg('请输入分类名称') |
||||||
|
this.$post(`${this.api.checkClassif}?classificationName=${row.classificationName}&siteId=${this.site.id}&classificationId=${row.id}`).then(res => { |
||||||
|
this.$post(this.api[row.id ? 'updateClassif' : 'saveClassif'], { |
||||||
|
classificationName: row.classificationName, |
||||||
|
templateId: this.columnInfo.templateId, |
||||||
|
id: row.id, |
||||||
|
siteId: this.site.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId |
||||||
|
}).then(res => { |
||||||
|
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功') |
||||||
|
this.getClassification() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(res => {}) |
||||||
|
}, |
||||||
|
// 关闭所属分类 |
||||||
|
closeClass() { |
||||||
|
const list = this.classifications |
||||||
|
if (list.find(e => e.edit && e.classificationName)) { |
||||||
|
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
list.map(e => { |
||||||
|
e.edit && e.classificationName && this.submitClass(e, 0) |
||||||
|
}) |
||||||
|
this.classVisible = false |
||||||
|
}).catch(() => { |
||||||
|
this.classVisible = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.classVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
// 获取标签 |
||||||
|
getLabel() { |
||||||
|
this.$post(`${this.api.queryLabel}?siteId=${this.site.id}`).then(({ data }) => { |
||||||
|
this.labels = data |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
// 显示标签弹框 |
||||||
|
setLabel() { |
||||||
|
this.labelVisible = true |
||||||
|
}, |
||||||
|
// 新增标签 |
||||||
|
addLabel() { |
||||||
|
this.labels.push({ |
||||||
|
edit: true, |
||||||
|
id: '', |
||||||
|
labelName: '' |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 编辑标签 |
||||||
|
editLabel(row) { |
||||||
|
this.$set(row, 'edit', 1) |
||||||
|
}, |
||||||
|
// 删除标签 |
||||||
|
delLabel(row, i) { |
||||||
|
if (row.id) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.delLabel}?id=${row.id}`).then(res => { |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.getLabel() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
this.labels.splice(i, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 提交标签 |
||||||
|
submitLabel(row, showMsg = 1) { |
||||||
|
if (!row.labelName) return Util.errorMsg('请输入主题名称') |
||||||
|
this.$post(`${this.api.checkLabel}?labelName=${row.labelName}&siteId=${this.site.id}&labelId=${row.id}`).then(res => { |
||||||
|
this.$post(this.api[row.id ? 'updateLabel' : 'saveLabel'], { |
||||||
|
labelName: row.labelName, |
||||||
|
id: row.id, |
||||||
|
siteId: this.site.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId |
||||||
|
}).then(res => { |
||||||
|
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功') |
||||||
|
this.getLabel() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(res => {}) |
||||||
|
}, |
||||||
|
// 关闭所属分类 |
||||||
|
closeLabel() { |
||||||
|
const list = this.labels |
||||||
|
if (list.find(e => e.edit && e.labelName)) { |
||||||
|
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
list.map(e => { |
||||||
|
e.edit && e.labelName && this.submitLabel(e, 0) |
||||||
|
}) |
||||||
|
this.labelVisible = false |
||||||
|
}).catch(() => { |
||||||
|
this.labelVisible = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.labelVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 文章名称判重 |
||||||
|
nameChange(){ |
||||||
|
const { title, level, id } = this.form |
||||||
|
if(title && title !== this.originalName){ |
||||||
|
this.$post(this.api.checkIfTheTitleIsRepeat, { |
||||||
|
siteId: this.site.id, |
||||||
|
title, |
||||||
|
id: id || '' |
||||||
|
}).then(res => { |
||||||
|
this.nameRepeat = false |
||||||
|
}).catch(res => { |
||||||
|
this.nameRepeat = true |
||||||
|
}) |
||||||
|
}else{ |
||||||
|
this.nameRepeat = false |
||||||
|
} |
||||||
|
}, |
||||||
|
// 图片裁剪上传事件 |
||||||
|
customUpload(data) { |
||||||
|
const formData = new FormData() |
||||||
|
formData.append('file', data, this.file.name) |
||||||
|
this.imgUpload(formData) |
||||||
|
}, |
||||||
|
// 压缩图片 |
||||||
|
compress(img) { |
||||||
|
const canvas = document.createElement('canvas') |
||||||
|
const ctx = canvas.getContext('2d') |
||||||
|
// let initSize = img.src.length; |
||||||
|
const width = img.width |
||||||
|
const height = img.height |
||||||
|
canvas.width = width |
||||||
|
canvas.height = height |
||||||
|
// 铺底色 |
||||||
|
ctx.fillStyle = '#fff' |
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height) |
||||||
|
ctx.drawImage(img, 0, 0, width, height) |
||||||
|
// 进行压缩 |
||||||
|
const ndata = canvas.toDataURL('image/jpeg', 0.8) |
||||||
|
return ndata |
||||||
|
}, |
||||||
|
// base64转成bolb对象 |
||||||
|
dataURItoBlob(base64Data) { |
||||||
|
let byteString |
||||||
|
if (base64Data.split(',')[0].indexOf('base64') >= 0) { |
||||||
|
byteString = atob(base64Data.split(',')[1]) |
||||||
|
} else { |
||||||
|
byteString = unescape(base64Data.split(',')[1]) |
||||||
|
} |
||||||
|
const mimeString = base64Data |
||||||
|
.split(',')[0] |
||||||
|
.split(':')[1] |
||||||
|
.split(';')[0] |
||||||
|
const ia = new Uint8Array(byteString.length) |
||||||
|
for (let i = 0; i < byteString.length; i++) { |
||||||
|
ia[i] = byteString.charCodeAt(i) |
||||||
|
} |
||||||
|
return new Blob([ia], { |
||||||
|
type: mimeString |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 图片上传到服务器 |
||||||
|
imgUpload(formData) { |
||||||
|
this.isUpload = true |
||||||
|
Axios({ |
||||||
|
method: 'post', |
||||||
|
url: this.api.upload, |
||||||
|
data: formData, |
||||||
|
headers: { |
||||||
|
'Content-Type': 'multipart/form-data', |
||||||
|
token: Util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
}).then(({ data }) => { |
||||||
|
let url = this.form[this.isBanner ? 'bannerImg' : 'titleImg'] |
||||||
|
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => {}).catch(e => {}) // 删除替换掉的图片 |
||||||
|
this.form[this.isBanner ? 'bannerImg' : 'titleImg'] = data.url |
||||||
|
}).catch(res => {}) |
||||||
|
this.$refs.cropper.isDisabled = false |
||||||
|
this.isUpload = false |
||||||
|
this.cropperModel = false |
||||||
|
}, |
||||||
|
// 图片改变钩子 |
||||||
|
changeFile(file, isBanner) { |
||||||
|
this.fixedNumber = isBanner ? [1, 0.26] : [1.76, 1] |
||||||
|
this.isBanner = isBanner |
||||||
|
const { size, name } = file |
||||||
|
const ext = name.substring(name.lastIndexOf('.') + 1) |
||||||
|
if (!Util.isImg(ext)) { |
||||||
|
this.$message.error('请上传图片!') |
||||||
|
return false |
||||||
|
} |
||||||
|
// if (size / 1024 / 1024 > 5) { |
||||||
|
// this.$message.error('请上传5M以内的图片!') |
||||||
|
// return false |
||||||
|
// } |
||||||
|
this.file = file |
||||||
|
this.cropperModel = true |
||||||
|
this.$nextTick(() => { |
||||||
|
this.$refs.cropper.updateImg({ |
||||||
|
url: window.URL.createObjectURL(file.raw), |
||||||
|
size: file.size |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 附件删除 |
||||||
|
handleRemove(e, fileList) { |
||||||
|
e.id ? this.$post(`${this.api.delContentFile}?id=${e.id}`).then(res => { |
||||||
|
this.form.fileList = fileList |
||||||
|
}).catch(res => {}) : (this.form.fileList = fileList) |
||||||
|
}, |
||||||
|
// banner上传成功 |
||||||
|
uploadSuccessBanner(res) { |
||||||
|
let url = this.form.bannerImg |
||||||
|
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => {}).catch(e => {}) |
||||||
|
this.form.bannerImg = res.url |
||||||
|
}, |
||||||
|
// 附件上传之前的钩子 |
||||||
|
fileBeforeUpload(file) { |
||||||
|
this.uploading++ |
||||||
|
}, |
||||||
|
// 附件上传成功 |
||||||
|
uploadSuccessFile(res) { |
||||||
|
this.uploading-- |
||||||
|
this.form.id ? |
||||||
|
this.$post(this.api.saveContentFile, { |
||||||
|
contentId: this.form.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId, |
||||||
|
id: '', |
||||||
|
fileName: res.original, |
||||||
|
filePath: res.url |
||||||
|
}).then(({ data }) => { |
||||||
|
this.form.fileList.push({ |
||||||
|
name: res.original, |
||||||
|
url: res.url, |
||||||
|
id: data |
||||||
|
}) |
||||||
|
}).catch(res => {}) : |
||||||
|
this.form.fileList.push({ |
||||||
|
name: res.original, |
||||||
|
url: res.url |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 预览 |
||||||
|
preview() { |
||||||
|
window.open((Setting.isDev ? `http://${location.hostname}:8095` : this.$store.state.content.site.domainName) + `#/article?articleId=${this.form.id}&siteId=${this.form.siteId}&id=${this.form.columnId}`) |
||||||
|
}, |
||||||
|
// 返回 |
||||||
|
back() { |
||||||
|
this.pass = true |
||||||
|
const { updateTime } = this |
||||||
|
// 更改了信息才需要提示 |
||||||
|
if (updateTime > 1) { |
||||||
|
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.submit(this.form.isRelease) |
||||||
|
}).catch(() => { |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.$router.back() |
||||||
|
} |
||||||
|
}, |
||||||
|
// 更新附件的状态为发布 |
||||||
|
updateFile(files, form, quoteId) { |
||||||
|
files.map(e => { |
||||||
|
this.$post(this.api.updateFile, { |
||||||
|
id: e, |
||||||
|
isRelease: form.isRelease, |
||||||
|
quote: form.title, |
||||||
|
quoteId |
||||||
|
}).then(res => {}).catch(err => {}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 提交 |
||||||
|
submit(isRelease, next) { |
||||||
|
if (this.submiting) return false |
||||||
|
const form = JSON.parse(JSON.stringify(this.form)) |
||||||
|
if (!form.title) return Util.errorMsg('请填写标题') |
||||||
|
if (this.nameRepeat) return Util.errorMsg('该标题已重复!') |
||||||
|
if (typeof form.fatherId === 'object') form.fatherId = form.fatherId[form.fatherId.length - 1] |
||||||
|
const tId = form.articleTemplate |
||||||
|
// 如果是发布 |
||||||
|
if (isRelease) { |
||||||
|
if (tId !== 25) { |
||||||
|
if (!form.releaseTime) return Util.errorMsg('请选择发布日期') |
||||||
|
} |
||||||
|
if (tId === 22 || tId === 23 || tId === 24) { |
||||||
|
if (!form.titleImg ) return Util.errorMsg('请上传封面') |
||||||
|
} |
||||||
|
if (tId === 25) { |
||||||
|
if ((!form.time || !form.time.length) && isRelease) return Util.errorMsg('请选择起止时间') |
||||||
|
form.activityStartTime = form.time[0] |
||||||
|
form.activityEndTime = form.time[1] |
||||||
|
} |
||||||
|
if (tId === 24 && form.connectionType !== 2) { |
||||||
|
if (form.connectionType === 1) { |
||||||
|
if (!this.links.length) return Util.errorMsg('请选择站内链接') |
||||||
|
} |
||||||
|
if (!this.otherLink.length && form.connectionType === 3) { |
||||||
|
if (!this.otherLink.length) return Util.errorMsg('请选择栏目') |
||||||
|
} |
||||||
|
} |
||||||
|
if ((tId === 22 || tId === 23 || tId === 25) && !form.mainBody) return Util.errorMsg('请输入正文') |
||||||
|
} |
||||||
|
if (this.uploading) return Util.errorMsg('文件正在上传,请上传完成后再发布') |
||||||
|
if (form.connectionType === 1) { |
||||||
|
form.linkAddress = this.links.join() |
||||||
|
if (this.article) form.linkAddress += '-' + this.article |
||||||
|
} else if (form.connectionType === 3) { |
||||||
|
form.linkAddress = this.otherLink.join() |
||||||
|
if (this.otherArticle) form.linkAddress += '-' + this.otherArticle |
||||||
|
} |
||||||
|
const { columnId, bannerImg, fileList, titleImg } = form |
||||||
|
const fileId = [] |
||||||
|
if (typeof columnId === 'object') form.columnId = columnId[columnId.length - 1] // 如果更换了栏目id,值会变成数组,需要手动获取最后一个 |
||||||
|
// 获取几个附件的id,url后面的数字串即是附件id |
||||||
|
if (bannerImg) fileId.push(bannerImg.substr(bannerImg.lastIndexOf('/') + 1)) |
||||||
|
if (titleImg) fileId.push(titleImg.substr(titleImg.lastIndexOf('/') + 1)) |
||||||
|
fileList && fileList.map(e => { |
||||||
|
fileId.push(e[e.url ? 'url' : 'filePath'].substr(e[e.url ? 'url' : 'filePath'].lastIndexOf('/') + 1)) |
||||||
|
}) |
||||||
|
form.lableId = form.lableId.join(',') |
||||||
|
|
||||||
|
form.releaseTime = Util.formatDate('yyyy-MM-dd', new Date(form.releaseTime)) // 发布日期转化为年月日格式 |
||||||
|
|
||||||
|
form.isRelease = isRelease |
||||||
|
this.submiting = true |
||||||
|
if (form.id) { |
||||||
|
delete form.children |
||||||
|
form.editorId = +this.$store.state.user.userId |
||||||
|
this.$post(this.api.updateArticle, form).then(res => { |
||||||
|
this.updateFile(fileId, form, form.id) |
||||||
|
Util.successMsg('修改成功') |
||||||
|
next ? next() : this.$router.push(`list?columnId=` + form.columnId) |
||||||
|
}).catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.$post(this.api.saveArticle, form).then(({ data }) => { |
||||||
|
this.updateFile(fileId, form, data) |
||||||
|
// 新增文章完后需要把上传的附件添加到文章附件表 |
||||||
|
form.fileList.map(e => { |
||||||
|
this.$post(this.api.saveContentFile, { |
||||||
|
contentId: data, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId, |
||||||
|
id: '', |
||||||
|
fileName: e.name, |
||||||
|
filePath: e.url |
||||||
|
}).then(res => {}).catch(err => {}) |
||||||
|
}) |
||||||
|
Util.successMsg('创建成功') |
||||||
|
next ? next() : this.$router.back() |
||||||
|
}).catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$upload-width: 220px; |
||||||
|
$upload-height: 102px; |
||||||
|
$upload-lg-height: 102px; |
||||||
|
/deep/ .avatar-uploader { |
||||||
|
.el-upload { |
||||||
|
position: relative; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
border: 1px solid #DCDEE0; |
||||||
|
border-radius: 2px; |
||||||
|
cursor: pointer; |
||||||
|
overflow: hidden; |
||||||
|
.uploader-default { |
||||||
|
display: flex; |
||||||
|
height: $upload-height; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
text-align: center; |
||||||
|
background: #FAFAFA; |
||||||
|
p { |
||||||
|
margin-top: 10px; |
||||||
|
font-size: 14px; |
||||||
|
color: #333; |
||||||
|
line-height: 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&.avatar-uploader-lg { |
||||||
|
.el-upload { |
||||||
|
width: 100%; |
||||||
|
max-width: 820px; |
||||||
|
height: $upload-lg-height; |
||||||
|
|
||||||
|
.uploader-default { |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.avatar { |
||||||
|
display: block; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
} |
||||||
|
.avatar-lg { |
||||||
|
display: block; |
||||||
|
width: 100%; |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
.el-upload__tip { |
||||||
|
margin-top: 0; |
||||||
|
p { |
||||||
|
font-size: 12px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.style-wrap { |
||||||
|
display: flex; |
||||||
|
margin-top: 10px; |
||||||
|
.label { |
||||||
|
margin-right: 30px; |
||||||
|
} |
||||||
|
} |
||||||
|
.styles { |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
width: 955px; |
||||||
|
// height: 320px; |
||||||
|
margin-top: 20px; |
||||||
|
overflow: auto; |
||||||
|
li { |
||||||
|
margin: 0 20px 10px 0; |
||||||
|
text-align: center; |
||||||
|
cursor: pointer; |
||||||
|
&:hover .review { |
||||||
|
border-color: #2962FF; |
||||||
|
} |
||||||
|
} |
||||||
|
.review { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
width: 170px; |
||||||
|
height: 112px; |
||||||
|
margin-bottom: 10px; |
||||||
|
border: 1px solid #DCDEE0; |
||||||
|
border-radius: 2px; |
||||||
|
img { |
||||||
|
width: 80px; |
||||||
|
} |
||||||
|
.is-link { |
||||||
|
width: 50px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.info { |
||||||
|
position: absolute; |
||||||
|
top: 8px; |
||||||
|
left: -32px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.plus { |
||||||
|
margin-bottom: 10px; |
||||||
|
font-size: 18px; |
||||||
|
color: #2962FF; |
||||||
|
text-align: right; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.set-btn { |
||||||
|
margin-left: 10px !important; |
||||||
|
} |
||||||
|
.manage-dia { |
||||||
|
.edit, .del { |
||||||
|
font-size: 14px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.edit { |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
.input-form { |
||||||
|
&.model { |
||||||
|
height: calc(100vh - 200px); |
||||||
|
padding-right: 20px; |
||||||
|
overflow: auto; |
||||||
|
.el-form-item__label { |
||||||
|
padding-right: 20px; |
||||||
|
} |
||||||
|
.lg .el-form-item__label { |
||||||
|
padding-right: 43px; |
||||||
|
} |
||||||
|
} |
||||||
|
.item-line { |
||||||
|
display: flex; |
||||||
|
.el-form-item:not(:last-child) { |
||||||
|
margin-right: 200px; |
||||||
|
} |
||||||
|
} |
||||||
|
.line { |
||||||
|
margin-bottom: 24px; |
||||||
|
border-bottom: 1px dashed #C2C2C2; |
||||||
|
} |
||||||
|
.el-form-item--small.el-form-item { |
||||||
|
margin-bottom: 24px; |
||||||
|
} |
||||||
|
.el-input, .el-select { |
||||||
|
width: 300px; |
||||||
|
} |
||||||
|
.el-select .el-input { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
.el-textarea { |
||||||
|
width: 550px; |
||||||
|
} |
||||||
|
.auto, .auto .el-input { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
.el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label:before { |
||||||
|
font-size: 18px; |
||||||
|
vertical-align: -4px; |
||||||
|
color: #F5222D; |
||||||
|
} |
||||||
|
} |
||||||
|
.btns { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,187 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<div class="tool"> |
||||||
|
<div class="search-wrap"> |
||||||
|
<el-input class="keyword" placeholder="请输入标题" v-model.trim="keyword" clearable></el-input> |
||||||
|
</div> |
||||||
|
<div class="actions"> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:删除'" @click="batchDel">批量删除</el-button> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:新增'" type="primary" @click="add" >新增文章</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="list" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column show-overflow-tooltip prop="title" label="标题" align="center" min-width="150"></el-table-column> |
||||||
|
<el-table-column prop="classificationName" label="所属分类" align="center" min-width="120" sortable="custom"></el-table-column> |
||||||
|
<el-table-column prop="founderName" label="录入人" align="center" min-width="80"></el-table-column> |
||||||
|
<el-table-column prop="editorName" label="修改人" align="center" min-width="80"></el-table-column> |
||||||
|
<el-table-column prop="updateTime" label="修改日期" align="center" min-width="150"></el-table-column> |
||||||
|
<el-table-column prop="releaseTime" label="发布日期" align="center" min-width="100"></el-table-column> |
||||||
|
<el-table-column prop="totalBrowsing" label="已学习人数" align="center" min-width="70"></el-table-column> |
||||||
|
<el-table-column prop="workNumber" label="状态" align="center" min-width="80"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{ scope.row.isRelease ? '已发布' : '草稿' }} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="170"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:编辑'" type="text" @click="edit(scope.row)">编辑</el-button> |
||||||
|
<el-button v-auth="'/site/list:内容管理:文章管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button> |
||||||
|
<el-switch |
||||||
|
class="m-l-10" |
||||||
|
v-model="scope.row.isDisable" |
||||||
|
:active-value="0" |
||||||
|
:inactive-value="1" |
||||||
|
@change="switchOff($event, scope.row, scope.$index)"> |
||||||
|
</el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import util from '@/libs/util' |
||||||
|
import { mapMutations } from 'vuex' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
list: [], |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
modifiedTimeSort: '', |
||||||
|
publicationTimeSort: '', |
||||||
|
ordinalSort: 0, |
||||||
|
multipleSelection: [], |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.initData() |
||||||
|
}, 500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
// this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 文章列表 |
||||||
|
getData() { |
||||||
|
const { keyword } = this |
||||||
|
const data = { |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
ordinalSort: this.ordinalSort, |
||||||
|
title: this.field === 'title' ? keyword : '', |
||||||
|
founder: this.field === 'founder' ? keyword : '', |
||||||
|
column: this.field === 'column' ? keyword : '', |
||||||
|
editor: this.field === 'editor' ? keyword : '' |
||||||
|
} |
||||||
|
if (this.modifiedTimeSort !== '') data.modifiedTimeSort = this.modifiedTimeSort |
||||||
|
if (this.publicationTimeSort !== '') data.publicationTimeSort = this.publicationTimeSort |
||||||
|
this.$post(this.api.queryArticle, data).then(({ data }) => { |
||||||
|
this.list = data.records |
||||||
|
this.total = +data.total |
||||||
|
}).catch(err => {}) |
||||||
|
}, |
||||||
|
currentChange(val) { |
||||||
|
this.page = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
initData() { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.page = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
// 批量删除 |
||||||
|
batchDel() { |
||||||
|
const list = this.multipleSelection |
||||||
|
if (list.length) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
const data = [] |
||||||
|
list.map(e => { |
||||||
|
data.push('ids=' + e.id) |
||||||
|
}) |
||||||
|
this.$post(`${this.api.deleteArticle}?${data.join('&')}`).then(res => { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
util.successMsg("删除成功") |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
} else { |
||||||
|
util.errorMsg('请先选择数据 !') |
||||||
|
} |
||||||
|
}, |
||||||
|
// 删除 |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(`${this.api.deleteArticle}?ids=${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}).catch(() => {}) |
||||||
|
}, |
||||||
|
// 禁用启用 |
||||||
|
switchOff(val, row) { |
||||||
|
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => {}).catch((res) => {}) |
||||||
|
}, |
||||||
|
// 新增 |
||||||
|
add() { |
||||||
|
this.$router.push(`/learnMg`) |
||||||
|
}, |
||||||
|
// 排序回调 |
||||||
|
sortChange(column) { |
||||||
|
const { order } = column |
||||||
|
// 三个排序只能同时传1个,所以点了一个排序的时候要清除掉其余两个 |
||||||
|
// 两个时间0默认倒序 1升序 |
||||||
|
if (column.prop === 'updateTime') { |
||||||
|
this.modifiedTimeSort = order ? order === 'ascending' ? 1 : 0 : '' |
||||||
|
if (order) { |
||||||
|
this.publicationTimeSort = '' |
||||||
|
this.ordinalSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
if (column.prop === 'releaseTime') { |
||||||
|
this.publicationTimeSort = order ? order === 'ascending' ? 1 : 0 : '' |
||||||
|
if (order) { |
||||||
|
this.modifiedTimeSort = '' |
||||||
|
this.ordinalSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
// 序号排序 0默认升序 1倒序 |
||||||
|
if (column.prop === 'sequence') { |
||||||
|
this.ordinalSort = order ? order === 'ascending' ? 0 : 1 : '' |
||||||
|
if (order) { |
||||||
|
this.publicationTimeSort = '' |
||||||
|
this.modifiedTimeSort = '' |
||||||
|
} |
||||||
|
} |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
// 编辑 |
||||||
|
edit(row) { |
||||||
|
this.$router.push(`add?id=${row.id}&columnId=${this.$refs.column.getCurrentKey()}&columnName=${this.$refs.column.getCurrentNode().columnName}`) |
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
Loading…
Reference in new issue