2025-09-02 17:35:30 +08:00

339 lines
12 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">
<el-row :gutter="20">
<!-- 部门树 -->
<el-col :lg="4" :xs="24" style="">
<el-card shadow="hover">
<!-- <el-input v-model="deptName" placeholder="请输入分类名称" prefix-icon="Search" clearable /> -->
<el-tree
ref="deptTreeRef"
class="mt-2"
node-key="id"
:data="deptOptions"
:props="{ label: 'name', children: 'children' } as any"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</el-card>
</el-col>
<el-col :lg="20" :xs="24">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="80px">
<el-form-item label="文章标题:" prop="postCode">
<el-input v-model="queryParams.title" placeholder="请输入文章标题" clearable @keyup.enter="handleQuery" />
</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-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="hover">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button v-hasPermi="['content:article:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
</el-col>
</el-row>
</template>
<el-table v-loading="loading" border :data="postList">
<el-table-column label="分类名称" align="center" prop="type" />
<el-table-column label="文章标题" align="center" prop="title" />
<el-table-column label="是否显示" align="center" prop="status" width="100">
<template #default="{ row }">
<!-- <el-switch v-model="row.status" active-value="0" inactive-value="1" @change="(val) => handleStatusChange(row, val)"> </el-switch> -->
{{ row.status == 1 ? '显示' : '隐藏' }}
</template>
</el-table-column>
<el-table-column label="排序" align="center" prop="sort" />
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button v-hasPermi="['content:article:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button v-hasPermi="['content:article:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" v-model:page="queryParams.current" v-model:limit="queryParams.size" :total="total" @pagination="getList" />
</el-card>
<!-- 添加或修改岗位对话框 -->
<el-dialog v-model="dialog.visible" :title="dialog.title" width="1000px" append-to-body>
<el-form ref="postFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="文章标题" prop="title" label-width="100px">
<el-input style="width: 100%" v-model="form.title" placeholder="请输入文章标题" />
</el-form-item>
<el-form-item label="文章分类" prop="categoryId" label-width="100px">
<el-cascader
style="width: 100%"
v-model="form.categoryId"
:options="deptOptions"
:props="{
value: 'id',
label: 'name',
children: 'children',
checkStrictly: true,
emitPath: false
}"
placeholder="请选择文章分类"
clearable
filterable
/>
</el-form-item>
<el-form-item label="文章类型" prop="type" label-width="100px">
<el-select v-model="form.type" placeholder="请选择文章分类" style="width: 100%">
<el-option v-for="item in enterpriseList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="文章排序" prop="sort" label-width="100px">
<el-input v-model="form.sort" placeholder="请输入文章排序" style="width: 100%" />
</el-form-item>
<el-form-item label="文章内容" prop="content" label-width="100px">
<Editor ref="editorRef" v-model="form.content" />
</el-form-item>
<el-form-item label="文章状态" prop="status">
<!-- <DictRadio v-model="form.status" radioData="cont_article_status" :show-all="'all'" /> -->
<el-select v-model="form.status" placeholder="请选择文章状态" style="width: 100%">
<el-option v-for="item in mingList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</el-col>
</el-row>
</div>
</template>
<script setup name="Post" lang="ts">
import { listPost, addPost, delPost, getPost, updatePost, listCategory } from '@/api/system/article';
import { PostForm, PostQuery, PostVO } from '@/api/system/article/types';
import { DeptVO } from '@/api/system/dept/types';
import api from '@/api/system/user';
import Editor from '@/components/Editor/index.vue';
import { getDictionaryByKey } from '@/utils/dict';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_normal_disable } = toRefs<any>(proxy?.useDict('sys_normal_disable'));
const postList = ref<PostVO[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const deptName = ref('');
const deptOptions = ref<any[]>([]);
const deptTreeRef = ref<ElTreeInstance>();
const postFormRef = ref<ElFormInstance>();
const queryFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: PostForm = {
id: undefined,
title: '',
type: undefined,
sort: undefined,
categoryId: undefined,
content: '',
status: undefined
};
const data = reactive<PageData<PostForm, PostQuery>>({
form: { ...initFormData },
queryParams: {
current: 1,
size: 10,
title: undefined,
categoryId: undefined
},
rules: {
title: [{ required: true, message: '文章标题不能为空', trigger: 'blur' }],
type: [{ required: true, message: '文章类型不能为空', trigger: 'blur' }],
categoryId: [{ required: true, message: '文章分类不能为空', trigger: 'blur' }],
sort: [{ required: true, message: '文章排序不能为空', trigger: 'blur' }],
content: [{ required: true, message: '文章内容不能为空', trigger: 'blur' }],
status: [{ required: true, message: '文章状态不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs<PageData<PostForm, PostQuery>>(data);
/** 角色状态修改 */
const handleStatusChange = async (row: any) => {
const text = row.status === '0' ? '启用' : '停用';
try {
await proxy?.$modal.confirm('确认要"' + text + '""' + row.title + '"文章吗?');
await changeRoleStatus(row.roleId, row.status);
proxy?.$modal.msgSuccess(text + '成功');
} catch {
row.status = row.status === '0' ? '1' : '0';
}
};
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
const enterpriseList = ref([]); // 种类
const mingList = ref([]);
const getByKey = async () => {
const value1 = await getDictionaryByKey('cont_article_type');
console.log(value1);
value1.forEach((item: any) => {
item.value = Number(item.value);
});
enterpriseList.value = value1;
const value2 = await getDictionaryByKey('cont_article_status');
value2.forEach((item: any) => {
item.value = Number(item.value);
});
mingList.value = value2;
console.log(value2);
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
deptTreeRef.value?.filter(deptName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发此属性控制在DOM元素更新后运行
}
);
watch(deptName, (val) => {
deptTreeRef.value?.filter(val);
});
const queryTree = ref({
current: 1,
size: 10,
id: '',
name: undefined,
parentId: undefined,
sort: undefined,
level: undefined,
type: undefined
});
/** 查询文章分类下拉树结构 */
const getTreeSelect = async () => {
const res = await listCategory(queryTree.value);
deptOptions.value = res.data;
};
/** 节点单击事件 */
const handleNodeClick = (data: DeptVO) => {
queryParams.value.categoryId = data.id;
handleQuery();
};
/** 查询岗位列表 */
const getList = async () => {
loading.value = true;
const res = await listPost(queryParams.value);
postList.value = res.data.records;
total.value = res.data.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
postFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
queryParams.value.categoryId = undefined;
queryParams.value.title = undefined;
queryParams.value.current = 1;
handleQuery();
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加岗位';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: any) => {
reset();
getByKey();
const postId = row.id;
const res = await getPost(postId);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改岗位';
};
/** 提交按钮 */
const submitForm = () => {
postFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
form.value.id ? await updatePost(form.value) : await addPost(form.value);
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: any) => {
const postIds = row.id;
await proxy?.$modal.confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?');
await delPost(postIds);
await getList();
proxy?.$modal.msgSuccess('删除成功');
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'system/post/export',
{
...queryParams.value
},
`post_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getTreeSelect(); // 初始化部门数据
getList();
getByKey();
});
</script>