parent
c1b1a1e6a8
commit
5d997905c9
13 changed files with 1182 additions and 172 deletions
After Width: | Height: | Size: 242 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 579 KiB |
After Width: | Height: | Size: 486 KiB |
@ -0,0 +1,991 @@ |
|||||||
|
<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 class="lg" prop="articleTemplate" label="独立文章模板"> |
||||||
|
<el-popover placement="top-start" trigger="hover" content="默认使用栏目中设置的文章样式,如果需要为该篇文章指定专门的模板样式,可以设置此项"> |
||||||
|
<img slot="reference" class="info" src="@/assets/images/ques.png" alt=""> |
||||||
|
</el-popover> |
||||||
|
<div style="width: 940px;text-align: right;"> |
||||||
|
<el-switch v-model="form.templateStatus" :active-value="1" :inactive-value="0"> |
||||||
|
</el-switch> |
||||||
|
</div> |
||||||
|
<ul v-if="form.templateStatus" class="styles"> |
||||||
|
<template v-for="(item, i) in detailStyle"> |
||||||
|
<li v-if="item.id !== column.detailStyle" :key="i" @click="styleChange(item.id)"> |
||||||
|
<div class="review"> |
||||||
|
<img :class="{ 'is-link': item.id == 24 }" :src="require('@/assets/images/style/' + item.id + '.png')" |
||||||
|
alt=""> |
||||||
|
</div> |
||||||
|
<el-radio v-model="form.articleTemplate" :label="item.id">{{ item.style }}</el-radio> |
||||||
|
</li> |
||||||
|
</template> |
||||||
|
</ul> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="name" label="名称"> |
||||||
|
<el-input id="articleTitle" style="width: 940px" placeholder="请输入名称" v-model="form.name" clearable |
||||||
|
maxlength="100" @change="nameChange"></el-input> |
||||||
|
</el-form-item> |
||||||
|
|
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item label="分类"> |
||||||
|
<el-select style="width: 234px;" v-model="getModelData" clearable> |
||||||
|
<template v-for="item in classifications"> |
||||||
|
<el-option v-if="item.categoryId" :key="item.categoryId" :label="item.name" :value="item.categoryId"> |
||||||
|
</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.categoryId" multiple> |
||||||
|
<template v-for="item in categories"> |
||||||
|
<el-option v-if="item.categoryId" :key="item.categoryId" :label="item.name" :value="item.categoryId"> |
||||||
|
</el-option> |
||||||
|
</template> |
||||||
|
</el-select> |
||||||
|
<el-button class="set-btn" type="primary" @click="setLabel">设置</el-button> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<el-form-item prop="subjectSpecialtyList" label="适用学科专业"> |
||||||
|
<div class="subject-wrap"> |
||||||
|
<div class="subject"> |
||||||
|
<div v-for="(item, i) in form.subjectSpecialtyList" :key="i" class="subject-line"> |
||||||
|
<el-form-item label="学科类别"> |
||||||
|
<el-select v-model="item.subjectCategoryId" @change="getProfessionalClass(item)"> |
||||||
|
<el-option v-for="(item, i) in subjectList" :key="i" :label="item.disciplineName" |
||||||
|
:value="item.disciplineId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="专业类"> |
||||||
|
<el-select v-model="item.professionalCategoryId" :disabled="item.subjectCategoryId ? false : true" |
||||||
|
@change="getProfessional(item)"> |
||||||
|
<el-option v-for="(item, i) in item.professionalClassList" :key="i" |
||||||
|
:label="item.professionalClassName" :value="item.professionalClassId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="专业"> |
||||||
|
<el-select v-model="item.majorId" :disabled="item.professionalCategoryId ? false : true"> |
||||||
|
<el-option v-for="(item, i) in item.professionalList" :key="i" :label="item.professionalName" |
||||||
|
:value="item.majorId"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
<i v-if="i" class="del el-icon-delete" @click="form.subjectSpecialtyList.splice(i, 1)"></i> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="subject-plus" @click="addSubject"> |
||||||
|
<i class="el-icon-circle-plus-outline"></i> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<template v-if="form.articleTemplate === 78"> |
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item label="匹配课程" prop="matchedCourses"> |
||||||
|
<el-input placeholder="请输入匹配课程" v-model="form.matchedCourses" maxlength="30"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="预计课时" prop="estimatedHours"> |
||||||
|
<el-select v-model="form.estimatedHours" clearable placeholder="请选择预计课时"> |
||||||
|
<el-option label="32课时" value="32课时"></el-option> |
||||||
|
<el-option label="64课时" value="64课时"></el-option> |
||||||
|
</el-select> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<el-form-item label="适用场景" prop="applicableScenarios"> |
||||||
|
<el-input style="width: 940px;" placeholder="请输入适用场景" v-model="form.applicableScenarios" |
||||||
|
maxlength="50"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</template> |
||||||
|
<el-form-item prop="coverImageUrl" label="封面图"> |
||||||
|
<el-upload class="avatar-uploader" accept=".jpg,.png,.jpeg,.gif" :on-change="file => changeFile(file, 0)" |
||||||
|
:show-file-list="false" :action="this.api.upload" :auto-upload="false"> |
||||||
|
<img v-if="form.coverImageUrl" :src="form.coverImageUrl" class="avatar"> |
||||||
|
<div class="uploader-default" v-else> |
||||||
|
<img class="plus" src="@/assets/images/plus.png" alt=""> |
||||||
|
<p>点击上传</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
|
||||||
|
<div class="item-line"> |
||||||
|
<el-form-item label="来源" prop="source" style="margin-right: 40px;"> |
||||||
|
<el-input placeholder="请输入来源" v-model="form.source" maxlength="50"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="按钮跳转链接"> |
||||||
|
<el-input class="m-r-10" style="width: 150px;" placeholder="请设置按钮名称" v-model="form.jumpButtonName" |
||||||
|
maxlength="10"></el-input> |
||||||
|
<el-input placeholder="请设置跳转链接" v-model="form.jumpLinkUrl"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</div> |
||||||
|
<el-form-item label="简介" prop="introduction"> |
||||||
|
<el-input style="width: 940px;" v-model="form.introduction" type="textarea" maxlength="200"></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item prop="detailedDescription" label="详情"> |
||||||
|
<Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' v-model="form.detailedDescription" |
||||||
|
:init="editorConfig" /> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<div class="btns"> |
||||||
|
<el-button type="primary" @click="submit(1)">发布</el-button> |
||||||
|
<el-button v-if="$route.query.id" @click="preview">预览</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="name" label="分类名称" align="center" min-width="130"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input v-if="scope.row.edit" placeholder="请输入分类名称" v-model="scope.row.name" clearable |
||||||
|
maxlength="30"></el-input> |
||||||
|
<span v-else>{{ scope.row.name }}</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="categories" 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="name" label="类型" align="center" min-width="130"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input v-if="scope.row.edit" placeholder="请输入类型" v-model="scope.row.name" clearable |
||||||
|
maxlength="30"></el-input> |
||||||
|
<span v-else>{{ scope.row.name }}</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/tinymce-vue' |
||||||
|
import editorConfig from './editor' |
||||||
|
import Cropper from '@/components/img-upload/Cropper' |
||||||
|
import Axios from 'axios' |
||||||
|
export default { |
||||||
|
data () { |
||||||
|
return { |
||||||
|
site: this.$store.state.content.site, |
||||||
|
userId: this.$store.state.user.userId, |
||||||
|
headers: { |
||||||
|
token: Util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
nameRepeat: false, |
||||||
|
categories: [], |
||||||
|
detailStyle: [ |
||||||
|
{ |
||||||
|
id: 78, |
||||||
|
style: '产品详情' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 72, |
||||||
|
style: '富文本' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 24, |
||||||
|
style: '链接' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 79, |
||||||
|
style: '课程详情' |
||||||
|
}, |
||||||
|
], |
||||||
|
subjectList: [], //专业学科 |
||||||
|
form: { |
||||||
|
siteId: this.$store.state.content.site.id, |
||||||
|
id: this.$route.query.id || '', |
||||||
|
founderId: this.$store.state.user.userId, |
||||||
|
templateStatus: 0, |
||||||
|
articleTemplate: '', |
||||||
|
applicableScenarios: '', |
||||||
|
categoryId: '', |
||||||
|
classificationTagId: '', |
||||||
|
estimatedHours: '', |
||||||
|
introduction: '', |
||||||
|
jumpButtonName: '', |
||||||
|
jumpLinkUrl: '', |
||||||
|
matchedCourses: '', |
||||||
|
name: '', |
||||||
|
columnId: +this.$route.query.columnId, |
||||||
|
publishStatus: 0, |
||||||
|
detailedDescription: '', |
||||||
|
source: '平台官方', |
||||||
|
coverImageUrl: '', |
||||||
|
subjectSpecialtyList: [ |
||||||
|
{ |
||||||
|
professionalClassList: [], |
||||||
|
professionalList: [], |
||||||
|
subjectCategoryId: 1, |
||||||
|
professionalCategoryId: 1, |
||||||
|
majorId: 1, |
||||||
|
} |
||||||
|
], |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
name: [ |
||||||
|
{ required: true, message: '请输入名称', trigger: 'blur' } |
||||||
|
], |
||||||
|
subjectSpecialtyList: [ |
||||||
|
{ required: true, message: '请选择学科专业', trigger: 'change' } |
||||||
|
], |
||||||
|
source: [ |
||||||
|
{ required: true, message: '请输入来源', trigger: 'blur' } |
||||||
|
], |
||||||
|
coverImageUrl: [ |
||||||
|
{ required: true, message: '请上传封面图', trigger: 'change' } |
||||||
|
], |
||||||
|
detailedDescription: [ |
||||||
|
{ 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, |
||||||
|
categories: [], |
||||||
|
labelVisible: false, |
||||||
|
originalName: '', |
||||||
|
originColumnId: '' |
||||||
|
}; |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('user', [ |
||||||
|
'userName' |
||||||
|
]), |
||||||
|
...mapState('content', [ |
||||||
|
'column' |
||||||
|
]), |
||||||
|
getModelData: { |
||||||
|
get () { |
||||||
|
const data = this.classifications.find(item => item.id === this.form.classificationTagId) |
||||||
|
return data ? data.id : '' |
||||||
|
}, |
||||||
|
set (newVal) { |
||||||
|
this.form.classificationTagId = newVal |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
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.publishStatus, next) |
||||||
|
}).catch(() => { |
||||||
|
next() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
next() |
||||||
|
} |
||||||
|
} else { |
||||||
|
next() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
this.$store.commit('user/setCrumbs', [ |
||||||
|
{ |
||||||
|
name: '站点管理', |
||||||
|
route: '/site' |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '内容管理' |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '文章管理', |
||||||
|
route: '/article' |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: this.$route.query.columnName, |
||||||
|
route: '/article' |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: this.$route.query.id ? '编辑' : '新增' |
||||||
|
} |
||||||
|
]) |
||||||
|
this.form.id ? this.getData() : this.getColumn() |
||||||
|
this.getSubject() |
||||||
|
this.getLabel() |
||||||
|
// this.getTemplate() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 获取文章详情 |
||||||
|
getData () { |
||||||
|
this.$post(`${this.api.productDetailsFind}?id=${this.form.id}`).then(({ data }) => { |
||||||
|
data.categoryId = data.categoryId ? data.categoryId.split(',').map(e => +e) : [] |
||||||
|
this.originalName = data.name |
||||||
|
let lableData = [] |
||||||
|
data.categoryId.forEach(item => { |
||||||
|
this.categories.forEach(options => { |
||||||
|
if (item == options.id) { |
||||||
|
lableData.push(item) |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
data.categoryId = lableData |
||||||
|
this.form = data |
||||||
|
}).catch(err => { }) |
||||||
|
}, |
||||||
|
// 获取栏目详情 |
||||||
|
getColumn () { |
||||||
|
this.$post(`${this.api.findColumn}?id=${this.$route.query.columnId}`).then(({ data }) => { |
||||||
|
this.columnInfo = data |
||||||
|
const { form } = this |
||||||
|
// 如果独立文章模板未启用,并且该栏目的类型为常规/子级优先,则把栏目所选的详情样式赋值到文章模板;如果栏目类型为长页或者链接,则文章模板默认为产品详情(78) |
||||||
|
if (!form.templateStatus) { |
||||||
|
form.articleTemplate = (data.typeId === 1 || data.typeId === 4) ? data.detailStyleId : 78 |
||||||
|
} |
||||||
|
|
||||||
|
this.getClassification() |
||||||
|
this.$nextTick(() => { |
||||||
|
this.updateTime = 0 |
||||||
|
}) |
||||||
|
}).catch(err => { }) |
||||||
|
}, |
||||||
|
// 独立文章模板选择回调 |
||||||
|
styleChange (id) { |
||||||
|
this.form.articleTemplate = id |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
// 添加学科 |
||||||
|
addSubject () { |
||||||
|
const e = { |
||||||
|
professionalClassList: [], |
||||||
|
professionalList: [], |
||||||
|
subjectCategoryId: 1, |
||||||
|
professionalCategoryId: 1, |
||||||
|
majorId: 1, |
||||||
|
} |
||||||
|
this.form.subjectSpecialtyList.push(e) |
||||||
|
this.getProfessionalClassData(e) |
||||||
|
}, |
||||||
|
// 获取学科类别 |
||||||
|
async getSubject () { |
||||||
|
const { list } = await this.$get(this.api.courseDiscipline) |
||||||
|
this.subjectList = list |
||||||
|
this.form.subjectSpecialtyList.forEach(e => { |
||||||
|
e.subjectCategoryId === 1 && this.getProfessionalClass(e) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 清除学科类别 |
||||||
|
clearClass (item) { |
||||||
|
item.professionalCategoryId = item.subjectCategoryId === 1 ? 1 : '' |
||||||
|
item.majorId = item.subjectCategoryId === 1 ? 1 : '' |
||||||
|
}, |
||||||
|
// 获取专业类 |
||||||
|
getProfessionalClass (item) { |
||||||
|
this.clearClass(item) |
||||||
|
this.getProfessionalClassData(item) |
||||||
|
}, |
||||||
|
async getProfessionalClassData (item) { |
||||||
|
const { list } = await this.$get(this.api.courseProfessionalClass, { |
||||||
|
disciplineId: item.subjectCategoryId |
||||||
|
}) |
||||||
|
item.professionalClassList = list |
||||||
|
this.form.subjectSpecialtyList.forEach(e => { |
||||||
|
e.professionalCategoryId === 1 && this.getProfessional(e) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 清除专业类 |
||||||
|
clearProfess (item) { |
||||||
|
item.majorId = item.professionalCategoryId === 1 ? 1 : '' |
||||||
|
}, |
||||||
|
// 获取专业 |
||||||
|
getProfessional (item) { |
||||||
|
this.clearProfess(item) |
||||||
|
this.getProfessionalData(item) |
||||||
|
}, |
||||||
|
async getProfessionalData (item) { |
||||||
|
const { list } = await this.$get(this.api.courseProfessional, { |
||||||
|
professionalClassId: item.professionalCategoryId |
||||||
|
}) |
||||||
|
item.professionalList = list |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取所有模板 |
||||||
|
getTemplate () { |
||||||
|
this.$post(this.api.individualTemplateDetailsStyle).then(({ data }) => { |
||||||
|
const result = [] |
||||||
|
data.map(e => { |
||||||
|
result.find(n => n.style === e.style) || result.push(e) |
||||||
|
}) |
||||||
|
this.detailStyle = result |
||||||
|
}).catch(err => { }) |
||||||
|
}, |
||||||
|
// 获取所属分类 |
||||||
|
getClassification () { |
||||||
|
this.$post(`${this.api.categoryList}?siteId=${this.site.id}&type=0`).then(({ data }) => { |
||||||
|
this.classifications = data |
||||||
|
}).catch(err => { }) |
||||||
|
}, |
||||||
|
// 显示所属分类弹框 |
||||||
|
setClass () { |
||||||
|
this.classVisible = true |
||||||
|
}, |
||||||
|
// 新增所属分类 |
||||||
|
addClass () { |
||||||
|
this.classifications.push({ |
||||||
|
edit: true, |
||||||
|
categoryId: '', |
||||||
|
name: '' |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 编辑所属分类 |
||||||
|
editClass (row) { |
||||||
|
this.$set(row, 'edit', 1) |
||||||
|
}, |
||||||
|
// 删除所属分类 |
||||||
|
delClass (row, i) { |
||||||
|
if (row.categoryId) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(this.api.categoryDel, [row.categoryId]).then(res => { |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.getClassification() |
||||||
|
}).catch(res => { }) |
||||||
|
}).catch(() => { }) |
||||||
|
} else { |
||||||
|
this.classifications.splice(i, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 提交所属分类 |
||||||
|
submitClass (row, showMsg = 1) { |
||||||
|
if (!row.name) return Util.errorMsg('请输入分类') |
||||||
|
// this.$post(`${this.api.checkClassif}?name=${row.name}&siteId=${this.site.id}&classificationTagId=${row.id}`).then(res => { |
||||||
|
this.$post(this.api.categorySave, { |
||||||
|
type: 0, |
||||||
|
name: row.name, |
||||||
|
categoryId: row.categoryId, |
||||||
|
siteId: this.site.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId |
||||||
|
}).then(res => { |
||||||
|
showMsg && Util.successMsg((row.categoryId ? '修改' : '新增') + '成功') |
||||||
|
this.getClassification() |
||||||
|
}).catch(res => { }) |
||||||
|
// }).catch(res => { }) |
||||||
|
}, |
||||||
|
// 关闭所属分类 |
||||||
|
closeClass () { |
||||||
|
const list = this.classifications |
||||||
|
if (list.find(e => e.edit && e.name)) { |
||||||
|
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
list.map(e => { |
||||||
|
e.edit && e.name && this.submitClass(e, 0) |
||||||
|
}) |
||||||
|
this.classVisible = false |
||||||
|
}).catch(() => { |
||||||
|
this.classVisible = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.classVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
// 获取类型 |
||||||
|
getLabel () { |
||||||
|
this.$post(`${this.api.categoryList}?siteId=${this.site.id}&type=1`).then(({ data }) => { |
||||||
|
this.categories = data |
||||||
|
}).catch(err => { }) |
||||||
|
}, |
||||||
|
// 显示标签弹框 |
||||||
|
setLabel () { |
||||||
|
this.labelVisible = true |
||||||
|
}, |
||||||
|
// 新增标签 |
||||||
|
addLabel () { |
||||||
|
this.categories.push({ |
||||||
|
edit: true, |
||||||
|
id: '', |
||||||
|
name: '' |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 编辑标签 |
||||||
|
editLabel (row) { |
||||||
|
this.$set(row, 'edit', 1) |
||||||
|
}, |
||||||
|
// 删除标签 |
||||||
|
delLabel (row, i) { |
||||||
|
if (row.categoryId) { |
||||||
|
this.$confirm('确定要删除吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
this.$post(this.api.categoryDel, [row.categoryId]).then(res => { |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.getLabel() |
||||||
|
}).catch(res => { }) |
||||||
|
}).catch(() => { }) |
||||||
|
} else { |
||||||
|
this.categories.splice(i, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 提交标签 |
||||||
|
submitLabel (row, showMsg = 1) { |
||||||
|
if (!row.name) return Util.errorMsg('请输入类型') |
||||||
|
// this.$post(`${this.api.checkLabel}?name=${row.name}&siteId=${this.site.id}&labelId=${row.id}`).then(res => { |
||||||
|
this.$post(this.api.categorySave, { |
||||||
|
type: 1, |
||||||
|
name: row.name, |
||||||
|
categoryId: row.categoryId, |
||||||
|
siteId: this.site.id, |
||||||
|
editorId: this.userId, |
||||||
|
founderId: this.userId |
||||||
|
}).then(res => { |
||||||
|
showMsg && Util.successMsg((row.categoryId ? '修改' : '新增') + '成功') |
||||||
|
this.getLabel() |
||||||
|
}).catch(res => { }) |
||||||
|
// }).catch(res => { }) |
||||||
|
}, |
||||||
|
// 关闭所属分类 |
||||||
|
closeLabel () { |
||||||
|
const list = this.categories |
||||||
|
if (list.find(e => e.edit && e.name)) { |
||||||
|
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}).then(() => { |
||||||
|
list.map(e => { |
||||||
|
e.edit && e.name && this.submitLabel(e, 0) |
||||||
|
}) |
||||||
|
this.labelVisible = false |
||||||
|
}).catch(() => { |
||||||
|
this.labelVisible = false |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.labelVisible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 文章名称判重 |
||||||
|
nameChange () { |
||||||
|
const { name, id } = this.form |
||||||
|
if (name && name !== this.originalName) { |
||||||
|
this.$post(this.api.productDetailsCheck, { |
||||||
|
siteId: this.site.id, |
||||||
|
name, |
||||||
|
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) |
||||||
|
formData.append('quote', this.form.name) |
||||||
|
formData.append('site', this.site.siteName) |
||||||
|
formData.append('uploader', this.userName) |
||||||
|
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 }) => { |
||||||
|
if (data.code === 401) { |
||||||
|
Util.errorMsg(data.msg) |
||||||
|
setTimeout(() => { |
||||||
|
this.$store.dispatch('user/logout') |
||||||
|
}, 1000) |
||||||
|
return false |
||||||
|
} |
||||||
|
let url = this.form.coverImageUrl |
||||||
|
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => { }).catch(e => { }) // 删除替换掉的图片 |
||||||
|
this.form.coverImageUrl = data.url |
||||||
|
}).catch(res => { }) |
||||||
|
this.$refs.cropper.isDisabled = false |
||||||
|
this.isUpload = false |
||||||
|
this.cropperModel = false |
||||||
|
}, |
||||||
|
// 图片改变钩子 |
||||||
|
changeFile (file, isBanner) { |
||||||
|
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 |
||||||
|
}) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 预览 |
||||||
|
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.publishStatus) |
||||||
|
}).catch(() => { |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
} else { |
||||||
|
this.$router.back() |
||||||
|
} |
||||||
|
}, |
||||||
|
// 更新附件的状态为发布 |
||||||
|
updateFile (files, form, quoteId) { |
||||||
|
files.map(e => { |
||||||
|
this.$post(this.api.updateFile, { |
||||||
|
id: e, |
||||||
|
publishStatus: form.publishStatus, |
||||||
|
quote: form.name, |
||||||
|
quoteId |
||||||
|
}).then(res => { }).catch(err => { }) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 提交 |
||||||
|
submit (publishStatus, next) { |
||||||
|
if (this.submiting) return false |
||||||
|
const form = JSON.parse(JSON.stringify(this.form)) |
||||||
|
if (!form.name) return Util.errorMsg('请填写名称') |
||||||
|
if (this.nameRepeat) return Util.errorMsg('该名称已重复!') |
||||||
|
// 如果是发布 |
||||||
|
if (publishStatus) { |
||||||
|
if (!form.coverImageUrl) return Util.errorMsg('请上传封面') |
||||||
|
if (!form.coverImageUrl) return Util.errorMsg('请上传封面') |
||||||
|
if (!form.source) return Util.errorMsg('请输入来源') |
||||||
|
} |
||||||
|
if (this.uploading) return Util.errorMsg('文件正在上传,请上传完成后再发布') |
||||||
|
const { coverImageUrl } = form |
||||||
|
const fileId = [] |
||||||
|
// 获取几个附件的id,url后面的数字串即是附件id |
||||||
|
if (coverImageUrl) fileId.push(coverImageUrl.substr(coverImageUrl.lastIndexOf('/') + 1)) |
||||||
|
form.categoryId = form.categoryId.join(',') |
||||||
|
form.subjectSpecialtyList.map(e => { |
||||||
|
delete e.professionalClassList |
||||||
|
delete e.professionalList |
||||||
|
}) |
||||||
|
|
||||||
|
form.publishStatus = publishStatus |
||||||
|
this.submiting = true |
||||||
|
form.editorId = +this.$store.state.user.userId |
||||||
|
this.$post(this.api.productDetailsSave, form).then(res => { |
||||||
|
this.updateFile(fileId, form, form.id || res.data) |
||||||
|
Util.successMsg(form.id ? '修改成功' : '创建成功') |
||||||
|
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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.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; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.subject-wrap { |
||||||
|
width: 940px; |
||||||
|
|
||||||
|
.subject { |
||||||
|
padding: 10px; |
||||||
|
border: 1px dashed #ccc; |
||||||
|
|
||||||
|
.subject-line { |
||||||
|
position: relative; |
||||||
|
display: flex; |
||||||
|
padding-right: 50px; |
||||||
|
margin-bottom: 10px; |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-form-item { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.el-select { |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.del { |
||||||
|
position: absolute; |
||||||
|
top: 11px; |
||||||
|
right: 20px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.subject-plus { |
||||||
|
margin-top: 5px; |
||||||
|
text-align: center; |
||||||
|
font-size: 18px; |
||||||
|
color: #5481ff; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue