daoyou_manage_web/src/views/manage/articleManage/index.vue

359 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 文章管理 -->
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]" id="search_div">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="标题" prop="title">
<el-input v-model="queryParams.title" class="inputWidth" placeholder="请输入标题" clearable
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="发布状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择发布状态" clearable class="inputWidth">
<el-option label="未发布" value="0"></el-option>
<el-option label="审核中" value="1"></el-option>
<el-option label="已发布" value="2"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="标签" prop="tagId">
<el-select class="inputWidth" filterable v-model="queryParams.tagId" placeholder="请选择标签" clearable>
<el-option v-for="dict in sys_user_tagOptions" :key="dict.id" :label="dict.title" :value="dict.id" />
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" plain icon="Plus" @click="handleAdd"
v-hasPermi="['manage:article:add']">新增</el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
v-hasPermi="['manage:article:edit']">修改</el-button>
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
v-hasPermi="['manage:article:remove']">删除</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-table v-loading="loading" :height="autoTableHeight" border :data="articleList"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" v-if="true" width="180px" />
<el-table-column label="标题" align="center" prop="title" width="300px" />
<el-table-column label="内容" align="center" prop="content" width="80px">
<template #default="scope">
<el-button link type="primary" @click="handleDetail(scope.row)">查看</el-button>
</template>
</el-table-column>
<el-table-column label="标签" align="center" prop="tagId" width="180px">
<template #default="scope">
<span>{{ formatTag(scope.row.tagId) }}</span>
</template>
</el-table-column>
<el-table-column label="喜欢数" align="center" prop="agreeCount" width="80px" />
<el-table-column label="评论数" align="center" prop="commentCount" width="80px" />
<el-table-column label="状态" align="center" prop="status" width="90px">
<template #default="scope">
<el-tag v-if="scope.row.status === 0" type="info">未发布</el-tag>
<el-tag v-if="scope.row.status === 1" type="success">审核中</el-tag>
<el-tag v-if="scope.row.status === 2" type="success">已发布</el-tag>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="120">
<template #default="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160px">
<template #default="scope">
<el-button link type="primary" v-if="scope.row.status === 0" @click="updateRow(scope.row,'2')"
v-hasPermi="['manage:article:edit']">发布</el-button>
<el-button link type="primary" v-if="scope.row.status === 2" @click="updateRow(scope.row,'0')"
v-hasPermi="['manage:article:edit']">撤销发布</el-button>
<el-tooltip content="修改" placement="top" v-if="scope.row.status === 0">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
v-hasPermi="['manage:article:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top" v-if="scope.row.status === 0">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
v-hasPermi="['manage:article:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination id="table_page" v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改文章对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px" append-to-body>
<el-form ref="articleFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="文章标题" prop="title">
<el-input v-model="form.title" placeholder="请输入文章标题" />
</el-form-item>
<el-form-item label="标签" prop="tagId_copy">
<el-select class="inputWidth" v-model="form.tagId_copy" multiple filterable placeholder="请选择标签" clearable>
<el-option v-for="dict in sys_user_tagOptions" :key="dict.id" :label="dict.title"
:value="String(dict.id)" />
</el-select>
</el-form-item>
<el-form-item label="内容" prop="content">
<editor v-model="form.content" :min-height="150" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 查看文章内容 -->
<el-dialog title="文章详情" v-model="articleVisible" width="500px" append-to-body center>
<div>
<div style="font-size: 18px;font-weight: bold;">{{ articleTitle }}</div>
<div v-html="articleContent" class="ql-editor"
style="height: 500px; overflow-y: auto;font-size: 16px;padding: 0px;padding-top: 15px;text-align: justify;">
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="cancel">关 闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Article" lang="ts">
import { listTag } from '@/api/manage/tag';
import { listArticle, getArticle, delArticle, addArticle, updateArticle } from '@/api/manage/article';
import { ArticleVO, ArticleQuery, ArticleForm } from '@/api/manage/article/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const sys_user_tagOptions = ref([]); //标签库
const autoTableHeight = ref<number>(750);
const articleList = ref<ArticleVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const articleVisible = ref(false); //文章弹层
const articleTitle = ref(''); //文章标题
const articleContent = ref(''); //文章内容
const queryFormRef = ref<ElFormInstance>();
const articleFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: ArticleForm = {
id: undefined,
tagId_copy: [],
title: undefined,
content: undefined,
userId: undefined,
tagId: undefined,
agreeCount: undefined,
commentCount: undefined,
status: 0,
}
const data = reactive<PageData<ArticleForm, ArticleQuery>>({
form: {...initFormData},
queryParams: {
pageNum: 1,
pageSize: 10,
title: undefined,
content: undefined,
userId: undefined,
tagId: undefined,
agreeCount: undefined,
commentCount: undefined,
status: undefined,
params: {
}
},
rules: {
title: [
{ required: true, message: "标题不能为空", trigger: "blur" }
],
content: [
{ required: true, message: "内容不能为空", trigger: "blur" }
],
tagId_copy: [
{ required: true, message: "标签不能为空", trigger: "blur" }
],
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询文章列表 */
const getList = async () => {
loading.value = true;
const res = await listArticle(queryParams.value);
articleList.value = res.rows;
total.value = res.total;
loading.value = false;
}
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
articleVisible.value = false;
}
// 获取标签库
const getTag = async () => {
const res = await listTag({ pageNum: 1, pageSize: 1000 });
sys_user_tagOptions.value = res.rows; //标签库
};
/**
* 标签格式化
*/
const formatTag = (tagId: string | null) => {
let tagString = '';
for (let i = 0; i < sys_user_tagOptions.value.length; i++) {
const element = sys_user_tagOptions.value[i];
if (tagId!=null) {
let filteredArray = tagId.split(',').filter((item) => item==element.id);
if (filteredArray.length>0) {
tagString += '' + element.title;
}
}
}
return tagString.substring(1);
};
/** 表单重置 */
const reset = () => {
form.value = {...initFormData};
articleFormRef.value?.resetFields();
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
}
/** 多选框选中数据 */
const handleSelectionChange = (selection: ArticleVO[]) => {
for (let i = 0; i < selection.length; i++) {
const element = selection[i];
if (element.status==2) {
proxy.$modal.msgError('已发布的数据不能修改或删除');
return
}
}
ids.value = selection.map(item => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = "添加文章";
}
/** 修改按钮操作 */
const handleUpdate = async (row?:any) => {
reset();
const _id = row?.id || ids.value[0]
const res = await getArticle(_id);
res.data.tagId_copy = res.data.tagId?.split(',');
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = "修改文章";
}
/**
*
* @param row 发布,撤销发布
* @param type
*/
const updateRow = async (row: any, type: string) => {
await proxy?.$modal.confirm('是否确认' + (type == '0' ? '撤销发布' : '发布') + '名称为"' + row.title + '"的数据项?');
row.status = type;
buttonLoading.value = true;
await updateArticle(row).finally(() => (buttonLoading.value = false));
proxy?.$modal.msgSuccess('操作成功');
getList();
};
const handleDetail = (row: any) => {
articleTitle.value= row.title;
articleContent.value = row.content;
articleVisible.value = true;
}
/** 提交按钮 */
const submitForm = () => {
articleFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
form.value.tagId = form.value.tagId_copy?.join(',');
if (form.value.id) {
await updateArticle(form.value).finally(() => buttonLoading.value = false);
} else {
await addArticle(form.value).finally(() => buttonLoading.value = false);
}
proxy?.$modal.msgSuccess("操作成功");
dialog.visible = false;
await getList();
}
});
}
/** 删除按钮操作 */
const handleDelete = async (row?: ArticleVO) => {
const _ids = row?.id || ids.value;
if (row?.id) {
await proxy?.$modal.confirm('是否确认删除名称为"' + row.title + '"的数据项?').finally(() => loading.value = false);
}else{
await proxy?.$modal.confirm('是否确认删除多项数据?').finally(() => loading.value = false);
}
await delArticle(_ids);
proxy?.$modal.msgSuccess("删除成功");
await getList();
}
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download('manage/article/export', {
...queryParams.value
}, `article_${new Date().getTime()}.xlsx`)
}
onMounted(() => {
getTag();
getList();
nextTick(() => {
autoTableHeight.value = proxy?.autoTableHeight();
});
window.onresize = () => {
autoTableHeight.value = proxy?.autoTableHeight();
};
});
</script>
<style lang="scss" scoped>
.el-card :deep(.el-card__body) {
padding-bottom: 0px !important;
}
#table_page {
height: 50px !important;
margin-top: 10px !important;
padding-bottom: 10px !important;
}
</style>