新增加文章发布
This commit is contained in:
parent
face320c24
commit
763dc329fc
@ -20,7 +20,7 @@
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<!-- <el-button type="primary" plain icon="plus" v-hasPermi="['system:article:add']" @click="handleAdd">发布文章</el-button> -->
|
||||
<el-button type="primary" plain icon="plus" v-hasPermi="['system:article:add']" @click="handleAdd">发布文章</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch="showSearch"></right-toolbar>
|
||||
</el-row>
|
||||
@ -44,7 +44,7 @@
|
||||
<el-table-column label="操作" align="center" width="190">
|
||||
<template #default="scope">
|
||||
<el-button type="text" icon="view" @click="handleView(scope.row)">查看</el-button>
|
||||
<!-- <el-button type="text" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:article:update']">编辑</el-button> -->
|
||||
<el-button type="text" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:article:update']">编辑</el-button>
|
||||
<el-popconfirm title="确定删除吗?" @onConfirm="handleDelete(scope.row)" style="margin-left:10px">
|
||||
<template #reference>
|
||||
<el-button type="text" icon="delete" v-hasPermi="['system:article:delete']">删除</el-button>
|
||||
@ -59,26 +59,16 @@
|
||||
</template>
|
||||
<script setup name="articleindex">
|
||||
import { listArticle, delArticle } from '@/api/system/article.js'
|
||||
import { getCurrentInstance, reactive, toRefs } from 'vue-demi'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
const { proxy } = getCurrentInstance()
|
||||
const router = useRouter()
|
||||
// 遮罩层
|
||||
const loading = ref(true)
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true)
|
||||
// 弹出层标题
|
||||
const title = ref('')
|
||||
// 是否显示弹出层
|
||||
const open = ref(false)
|
||||
// 文章状态下拉框
|
||||
const statusOptions = ref([])
|
||||
// 数据列表
|
||||
const dataList = ref([])
|
||||
// 总记录数
|
||||
const total = ref(0)
|
||||
// 提交按钮是否显示
|
||||
const btnSubmitVisible = ref(true)
|
||||
// 文章预览地址
|
||||
const previewUrl = ref('')
|
||||
|
||||
@ -87,7 +77,7 @@ const data = reactive({
|
||||
queryParams: {},
|
||||
})
|
||||
|
||||
const { form, queryParams } = toRefs(data)
|
||||
const { queryParams } = toRefs(data)
|
||||
|
||||
proxy.getDicts('sys_article_status').then((response) => {
|
||||
statusOptions.value = response.data
|
||||
|
||||
@ -2,69 +2,59 @@
|
||||
<div class="app-container">
|
||||
<el-row :gutter="24">
|
||||
<!-- :model属性用于表单验证使用 比如下面的el-form-item 的 prop属性用于对表单值进行验证操作 -->
|
||||
<el-form :model="form" ref="form" label-width="100px" :rules="rules" @submit.prevent>
|
||||
<el-col :lg="12">
|
||||
<el-form-item label="文章标题" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入文章标题(必须)" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-form-item label="文章分类" prop="category_id">
|
||||
<!-- <treeselect v-model="form.category_id" :options="categoryOptions" :normalizer="normalizer" :show-count="true" /> -->
|
||||
<tree-select v-model:value="form.category_id" :options="categoryOptions"
|
||||
:objMap="{ value: 'category_id', label: 'name', children: 'children' }" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form :model="form" ref="formRef" label-width="100px" :rules="rules" @submit.prevent>
|
||||
<el-form-item label="文章标题" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入文章标题(必须)" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="文章分类" prop="category_id">
|
||||
<el-cascader
|
||||
class="w100"
|
||||
:options="categoryOptions"
|
||||
:props="{ checkStrictly: true, value: 'category_Id', label: 'name', emitPath: false }"
|
||||
placeholder="请选择文章分类"
|
||||
clearable
|
||||
v-model="form.category_Id"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="文章标签">
|
||||
<el-tag v-for="tag in form.dynamicTags" :key="tag" class="mr10" closable :disable-transitions="false" @close="handleCloseTag(tag)">
|
||||
{{ tag }}
|
||||
</el-tag>
|
||||
<el-input v-if="inputVisible" ref="inputRef" v-model="inputValue" class="w20" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" />
|
||||
|
||||
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ 文章标签</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="content" label="文章内容">
|
||||
<MdEditor v-model="form.content" :onUploadImg="onUploadImg" />
|
||||
</el-form-item>
|
||||
|
||||
<el-col :lg="24">
|
||||
<el-form-item label="文章标签">
|
||||
<el-tag size="large" :key="tag" v-for="tag in form.dynamicTags" closable :disable-transitions="false" @close="handleCloseTag(tag)">
|
||||
{{tag}}
|
||||
</el-tag>
|
||||
<el-input class="input-new-tag" v-if="inputVisible" v-model="inputValue" ref="saveTagInput" size="small" @keyup.enter="handleInputConfirm"
|
||||
@blur="handleInputConfirm">
|
||||
</el-input>
|
||||
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ 文章标签</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="24">
|
||||
<el-form-item prop="content" label="文章内容">
|
||||
<!-- <mavon-editor v-model="form.content" ref=md /> -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="24">
|
||||
<el-form-item label="" style="text-align:right;">
|
||||
<el-form-item style="text-align: right">
|
||||
<el-button @click="handlePublish('1')">发布文章</el-button>
|
||||
<el-button type="success" @click="handlePublish('2')">存为草稿</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-form>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="articlepublish">
|
||||
import {
|
||||
addArticle,
|
||||
updateArticle,
|
||||
listArticleCategoryTree,
|
||||
getArticle,
|
||||
} from '@/api/system/article.js'
|
||||
import { addArticle, updateArticle, listArticleCategoryTree, getArticle } from '@/api/system/article.js'
|
||||
import { upload } from '@/api/common.js'
|
||||
// import mavonEditor from 'mavon-editor'
|
||||
// import 'mavon-editor/dist/css/index.css'
|
||||
import MdEditor from 'md-editor-v3';
|
||||
import 'md-editor-v3/lib/style.css'
|
||||
|
||||
import { getCurrentInstance, reactive, toRefs, watch, nextTick } from 'vue-demi'
|
||||
import { useRoute } from 'vue-router'
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
// 文章目录下拉框
|
||||
const categoryOptions = ref([])
|
||||
// 提交按钮是否显示
|
||||
const btnSubmitVisible = ref(true)
|
||||
const inputVisible = ref(false)
|
||||
const inputValue = ref('')
|
||||
const html = ref('')
|
||||
|
||||
const formRef = ref()
|
||||
const inputRef = ref()
|
||||
const data = reactive({
|
||||
form: {
|
||||
dynamicTags: [],
|
||||
@ -95,18 +85,21 @@ function getCategoryTreeselect() {
|
||||
}
|
||||
|
||||
// 将图片上传到服务器,返回地址替换到md中
|
||||
function $imgAdd(pos, $file) {
|
||||
var formdata = new FormData()
|
||||
formdata.append('file', $file)
|
||||
upload(formdata).then((res) => {
|
||||
console.log(JSON.stringify(res))
|
||||
proxy.$refs.md.$img2Url(pos, res.data.url)
|
||||
})
|
||||
}
|
||||
async function onUploadImg(files, callback) {
|
||||
const res = await Promise.all(
|
||||
Array.from(files).map((file) => {
|
||||
return new Promise((rev, rej) => {
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
|
||||
function change(value, render) {
|
||||
// render 为 markdown 解析后的结果
|
||||
html.value = render
|
||||
upload(form)
|
||||
.then((res) => rev(res))
|
||||
.catch((error) => rej(error))
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
callback(res.map((item) => item.data.url))
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
@ -114,7 +107,7 @@ function handlePublish(status) {
|
||||
form.value.status = status
|
||||
form.value.tags = form.value.dynamicTags.toString()
|
||||
|
||||
proxy.$refs['form'].validate((valid) => {
|
||||
proxy.$refs['formRef'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (form.value.cid != undefined) {
|
||||
updateArticle(form.value).then((res) => {
|
||||
@ -142,27 +135,21 @@ function handleCloseTag(tag) {
|
||||
form.value.dynamicTags.splice(form.value.dynamicTags.indexOf(tag), 1)
|
||||
}
|
||||
|
||||
function showInput() {
|
||||
const showInput = () => {
|
||||
inputVisible.value = true
|
||||
proxy.nextTick((_) => {
|
||||
proxy.$refs.saveTagInput.$refs.input.focus()
|
||||
nextTick(() => {
|
||||
inputRef.value.input.focus()
|
||||
})
|
||||
}
|
||||
// 标签确认
|
||||
function handleInputConfirm() {
|
||||
let inputValue = form.value.inputValue.trim()
|
||||
|
||||
if (
|
||||
inputValue &&
|
||||
inputValue.length > 0 &&
|
||||
form.value.dynamicTags.length < 4
|
||||
) {
|
||||
form.value.dynamicTags.push(inputValue)
|
||||
if (inputValue.value) {
|
||||
form.value.dynamicTags.push(inputValue.value)
|
||||
}
|
||||
inputVisible.value = false
|
||||
inputValue.value = ''
|
||||
}
|
||||
getInfo(cid)
|
||||
function handleTreeSelect() {}
|
||||
function getInfo(cid) {
|
||||
if (!cid || cid == undefined) return
|
||||
getArticle(cid).then((res) => {
|
||||
@ -173,9 +160,8 @@ function getInfo(cid) {
|
||||
cid: parseInt(cid),
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
category_id: data.category_id,
|
||||
dynamicTags:
|
||||
data.tags != null && data.tags.length > 0 ? data.tags.split(',') : [],
|
||||
category_Id: data.category_Id,
|
||||
dynamicTags: data.tags != null && data.tags.length > 0 ? data.tags.split(',') : [],
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -183,28 +169,17 @@ function getInfo(cid) {
|
||||
getCategoryTreeselect()
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-tag + .el-tag {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.el-tag {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.button-new-tag {
|
||||
/* margin-left: 10px; */
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.input-new-tag {
|
||||
width: 90px;
|
||||
margin-right: 10px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.el-col {
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.vue-treeselect {
|
||||
z-index: 1501;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user