|
@@ -2,73 +2,82 @@
|
|
|
<div class="article-edit">
|
|
<div class="article-edit">
|
|
|
<el-card>
|
|
<el-card>
|
|
|
<div slot="header">
|
|
<div slot="header">
|
|
|
- <span>{{ isEdit ? '编辑文章' : '新建文章' }}</span>
|
|
|
|
|
|
|
+ <span>{{ readonly ? '文章详情' : (isEdit ? '编辑文章' : '新建文章') }}</span>
|
|
|
<div style="float: right;">
|
|
<div style="float: right;">
|
|
|
<el-button @click="$router.push('/article-manage')">返回列表</el-button>
|
|
<el-button @click="$router.push('/article-manage')">返回列表</el-button>
|
|
|
- <el-button type="primary" @click="handleSave(false)" :loading="saving">保存草稿</el-button>
|
|
|
|
|
- <el-button type="success" @click="handleSave(true)" :loading="publishing">发布</el-button>
|
|
|
|
|
|
|
+ <template v-if="readonly">
|
|
|
|
|
+ <el-button type="default" @click="handleCopyAsNew">复制并新建</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <el-button type="primary" @click="handleSave(false)" :loading="saving">保存草稿</el-button>
|
|
|
|
|
+ <el-button type="success" @click="handleSave(true)" :loading="publishing">发布</el-button>
|
|
|
|
|
+ </template>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<el-form :model="form" label-width="120px" v-loading="loading">
|
|
<el-form :model="form" label-width="120px" v-loading="loading">
|
|
|
<el-form-item label="标题">
|
|
<el-form-item label="标题">
|
|
|
- <el-input v-model="form.title" placeholder="请输入文章标题" maxlength="200" show-word-limit />
|
|
|
|
|
|
|
+ <el-input v-model="form.title" placeholder="请输入文章标题" maxlength="200" show-word-limit :disabled="readonly" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="分类">
|
|
<el-form-item label="分类">
|
|
|
- <el-select v-model="form.categoryId" placeholder="选择分类" style="width: 300px;">
|
|
|
|
|
|
|
+ <el-select v-model="form.categoryId" placeholder="选择分类" style="width: 300px;" :disabled="readonly">
|
|
|
<el-option v-for="cat in categories" :key="cat.id" :label="cat.name" :value="cat.id" />
|
|
<el-option v-for="cat in categories" :key="cat.id" :label="cat.name" :value="cat.id" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="摘要">
|
|
<el-form-item label="摘要">
|
|
|
- <el-input v-model="form.summary" type="textarea" :rows="3" placeholder="请输入文章摘要" maxlength="500" show-word-limit />
|
|
|
|
|
|
|
+ <el-input v-model="form.summary" type="textarea" :rows="3" placeholder="请输入文章摘要" maxlength="500" show-word-limit :disabled="readonly" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="封面图">
|
|
<el-form-item label="封面图">
|
|
|
- <el-upload
|
|
|
|
|
- :action="uploadActionUrl"
|
|
|
|
|
- :headers="uploadHeaders"
|
|
|
|
|
- :on-success="handleUploadSuccess"
|
|
|
|
|
- :on-error="handleUploadError"
|
|
|
|
|
- :before-upload="beforeUpload"
|
|
|
|
|
- :show-file-list="false"
|
|
|
|
|
- accept="image/jpeg,image/png,image/gif,image/webp"
|
|
|
|
|
- >
|
|
|
|
|
- <img v-if="form.coverImage" :src="form.coverImage" class="cover-preview" />
|
|
|
|
|
- <el-button v-else type="primary" plain>+ 上传封面</el-button>
|
|
|
|
|
- </el-upload>
|
|
|
|
|
- <el-button v-if="form.coverImage" size="mini" type="text" style="margin-left: 10px;" @click="form.coverImage = ''">清除</el-button>
|
|
|
|
|
|
|
+ <template v-if="!readonly">
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ :action="uploadActionUrl"
|
|
|
|
|
+ :headers="uploadHeaders"
|
|
|
|
|
+ :on-success="handleUploadSuccess"
|
|
|
|
|
+ :on-error="handleUploadError"
|
|
|
|
|
+ :before-upload="beforeUpload"
|
|
|
|
|
+ :show-file-list="false"
|
|
|
|
|
+ accept="image/jpeg,image/png,image/gif,image/webp"
|
|
|
|
|
+ >
|
|
|
|
|
+ <img v-if="form.coverImage" :src="form.coverImage" class="cover-preview" />
|
|
|
|
|
+ <el-button v-else type="primary" plain>+ 上传封面</el-button>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ <el-button v-if="form.coverImage" size="mini" type="text" style="margin-left: 10px;" @click="form.coverImage = ''">清除</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <img v-else-if="form.coverImage" :src="form.coverImage" class="cover-preview" />
|
|
|
|
|
+ <span v-else class="text-muted">无封面图</span>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="内容">
|
|
<el-form-item label="内容">
|
|
|
- <el-input v-model="form.content" type="textarea" :rows="15" placeholder="请输入文章内容(支持 HTML) 提示:此为纯文本编辑器,后续将升级为富文本编辑器" />
|
|
|
|
|
|
|
+ <el-input v-model="form.content" type="textarea" :rows="15" placeholder="请输入文章内容(支持 HTML) 提示:此为纯文本编辑器,后续将升级为富文本编辑器" :disabled="readonly" />
|
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">当前为纯文本输入,后续将升级为富文本编辑器</div>
|
|
<div style="color: #999; font-size: 12px; margin-top: 4px;">当前为纯文本输入,后续将升级为富文本编辑器</div>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="标签">
|
|
<el-form-item label="标签">
|
|
|
- <el-input v-model="form.tags" placeholder="逗号分隔,如: 育儿,亲子,心理" />
|
|
|
|
|
|
|
+ <el-input v-model="form.tags" placeholder="逗号分隔,如: 育儿,亲子,心理" :disabled="readonly" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="作者">
|
|
<el-form-item label="作者">
|
|
|
- <el-input v-model="form.author" placeholder="文章作者" />
|
|
|
|
|
|
|
+ <el-input v-model="form.author" placeholder="文章作者" :disabled="readonly" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="阅读时间(分)">
|
|
<el-form-item label="阅读时间(分)">
|
|
|
- <el-input-number v-model="form.readTime" :min="1" :max="999" />
|
|
|
|
|
|
|
+ <el-input-number v-model="form.readTime" :min="1" :max="999" :disabled="readonly" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
|
|
|
|
|
<el-form-item label="五维权重">
|
|
<el-form-item label="五维权重">
|
|
|
- <dimension-weight-picker v-model="form.dimensionWeights" :show-presets="true" />
|
|
|
|
|
|
|
+ <dimension-weight-picker v-model="form.dimensionWeights" :show-presets="true" :readonly="readonly" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="浏览权限">
|
|
<el-form-item label="浏览权限">
|
|
|
- <el-radio-group v-model="form.visibility">
|
|
|
|
|
|
|
+ <el-radio-group v-model="form.visibility" :disabled="readonly">
|
|
|
<el-radio label="public">公开</el-radio>
|
|
<el-radio label="public">公开</el-radio>
|
|
|
<el-radio label="login">登录可见</el-radio>
|
|
<el-radio label="login">登录可见</el-radio>
|
|
|
<el-radio label="private">私密</el-radio>
|
|
<el-radio label="private">私密</el-radio>
|
|
@@ -99,6 +108,8 @@ export default {
|
|
|
loading: false,
|
|
loading: false,
|
|
|
saving: false,
|
|
saving: false,
|
|
|
publishing: false,
|
|
publishing: false,
|
|
|
|
|
+ readonly: false,
|
|
|
|
|
+ articleWasPublished: false,
|
|
|
categories: [],
|
|
categories: [],
|
|
|
form: {
|
|
form: {
|
|
|
id: null,
|
|
id: null,
|
|
@@ -130,7 +141,13 @@ export default {
|
|
|
created() {
|
|
created() {
|
|
|
this.loadCategories()
|
|
this.loadCategories()
|
|
|
const id = this.$route.query.id
|
|
const id = this.$route.query.id
|
|
|
- if (id) {
|
|
|
|
|
|
|
+ const copyId = this.$route.query.copyId
|
|
|
|
|
+ this.readonly = this.$route.query.readonly === '1'
|
|
|
|
|
+
|
|
|
|
|
+ if (copyId) {
|
|
|
|
|
+ this.isEdit = false
|
|
|
|
|
+ this.loadForCopy(copyId)
|
|
|
|
|
+ } else if (id) {
|
|
|
this.isEdit = true
|
|
this.isEdit = true
|
|
|
this.loadDetail(id)
|
|
this.loadDetail(id)
|
|
|
}
|
|
}
|
|
@@ -152,6 +169,10 @@ export default {
|
|
|
const res = await adminArticleDetail({ id })
|
|
const res = await adminArticleDetail({ id })
|
|
|
if (res.data) {
|
|
if (res.data) {
|
|
|
const d = res.data
|
|
const d = res.data
|
|
|
|
|
+ this.articleWasPublished = !!(d.publishedAt || d.status === 'published')
|
|
|
|
|
+ if (this.readonly || this.articleWasPublished) {
|
|
|
|
|
+ this.readonly = true
|
|
|
|
|
+ }
|
|
|
this.form = {
|
|
this.form = {
|
|
|
id: d.id,
|
|
id: d.id,
|
|
|
categoryId: d.categoryId,
|
|
categoryId: d.categoryId,
|
|
@@ -181,6 +202,42 @@ export default {
|
|
|
this.loading = false
|
|
this.loading = false
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ async loadForCopy(id) {
|
|
|
|
|
+ this.loading = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await adminArticleDetail({ id })
|
|
|
|
|
+ if (res.data) {
|
|
|
|
|
+ const d = res.data
|
|
|
|
|
+ this.form = {
|
|
|
|
|
+ id: null,
|
|
|
|
|
+ categoryId: d.categoryId,
|
|
|
|
|
+ title: (d.title || '') + '(副本)',
|
|
|
|
|
+ summary: d.summary || '',
|
|
|
|
|
+ coverImage: d.coverImage || '',
|
|
|
|
|
+ content: d.content || '',
|
|
|
|
|
+ tags: d.tags || '',
|
|
|
|
|
+ author: d.author || '',
|
|
|
|
|
+ readTime: d.readTime || 3,
|
|
|
|
|
+ relatedDimensions: d.relatedDimensions || [],
|
|
|
|
|
+ dimensionWeights: [],
|
|
|
|
|
+ visibility: d.visibility || 'public',
|
|
|
|
|
+ visibleTo: d.visibleTo || []
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ const dwRes = await getDimensionWeights('article', d.id)
|
|
|
|
|
+ if (dwRes.data && dwRes.data.length) {
|
|
|
|
|
+ await saveDimensionWeights('article', null, dwRes.data)
|
|
|
|
|
+ this.form.dimensionWeights = dwRes.data
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ this.$message.error('加载文章失败')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ this.loading = false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
beforeUpload(file) {
|
|
beforeUpload(file) {
|
|
|
const isImage = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/webp'
|
|
const isImage = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/webp'
|
|
|
if (!isImage) {
|
|
if (!isImage) {
|
|
@@ -261,6 +318,25 @@ export default {
|
|
|
this.saving = false
|
|
this.saving = false
|
|
|
this.publishing = false
|
|
this.publishing = false
|
|
|
}
|
|
}
|
|
|
|
|
+ },
|
|
|
|
|
+ handleCopyAsNew() {
|
|
|
|
|
+ const data = this.buildSubmitData()
|
|
|
|
|
+ delete data.id
|
|
|
|
|
+ data.title = (data.title || '').replace('(副本)', '') + '(副本)'
|
|
|
|
|
+ data.status = 'draft'
|
|
|
|
|
+ this.saving = true
|
|
|
|
|
+ adminArticleCreate(data).then(res => {
|
|
|
|
|
+ if (res.data && res.data.id) {
|
|
|
|
|
+ this.$message.success('已复制为草稿')
|
|
|
|
|
+ this.$router.push('/article-edit?id=' + res.data.id)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$message.error('复制失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(e => {
|
|
|
|
|
+ this.$message.error(e.message || '复制失败')
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ this.saving = false
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|