| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- <template>
- <div class="ele-body">
- <el-card shadow="never">
- <!-- 搜索表单 -->
- <el-form :model="table.where" label-width="90px" class="ele-form-search"
- @keyup.enter.native="$refs.table.reload()" @submit.native.prevent>
- <el-row :gutter="15">
- <el-col :md="8" :sm="12">
- <el-form-item label="关键词:">
- <el-input v-model="table.where.keyword" placeholder="请输入标题关键词" clearable />
- </el-form-item>
- </el-col>
- <el-col :md="6" :sm="12" v-if="!this.defaultType">
- <el-form-item label="类型:">
- <el-select v-model="table.where.type" placeholder="请选择类型" class="ele-fluid">
- <el-option label="全部" :value="0" />
- <el-option v-for="(item, k) in typeArr" :key="k" :label="item.name" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :md="6" :sm="12">
- <el-form-item label="状态:">
- <el-select v-model="table.where.status" placeholder="请选择" class="ele-fluid">
- <el-option label="全部" :value="0" />
- <el-option label="发布" :value="1" />
- <el-option label="未发布" :value="2" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :md="6" :sm="12">
- <div class="ele-form-actions">
- <el-button type="primary" @click="$refs.table.reload()" icon="el-icon-search" class="ele-btn-icon">查询
- </el-button>
- <el-button @click="reloadTable()">
- 重置
- </el-button>
- <el-button v-if="permission.includes(permissionMap['add'])" type="primary" icon="el-icon-plus"
- size="small" @click="openCreate">
- 创建
- </el-button>
- <!-- 导入按钮,仅在 defaultType 为 9 时可见 -->
- <el-button v-if="defaultType == 9 && permission.includes(permissionMap['add'])" type="success"
- icon="el-icon-upload2" size="small" @click="openImportDialog">
- 导入
- </el-button>
- </div>
- </el-col>
- </el-row>
- </el-form>
- <ele-data-table :key="tableKey" ref="table" :config="table" :choose.sync="choose" height="calc(100vh - 315px)"
- highlight-current-row>
- <template>
- <el-table-column type="selection" width="45" align="center" fixed="left" />
- <el-table-column prop="id" label="ID" width="60" align="center" fixed="left" show-overflow-tooltip />
- <el-table-column prop="title" label="标题" show-overflow-tooltip min-width="200" />
- <el-table-column v-if="defaultType == 1" prop="author" label="作者" show-overflow-tooltip min-width="100">
- <template slot-scope="{row}">
- <span>{{ row.author }}</span>
- </template>
- </el-table-column>
- <el-table-column v-if="defaultType != 1" prop="type_name" label="类型" show-overflow-tooltip min-width="100">
- <template slot-scope="{row}">
- <span class="ele-text-primary">{{ getTypeName(row.type) }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="status" label="发布" :resizable="false" min-width="120">
- <template slot-scope="{row}">
- <el-switch v-model="row.status" @change="handleStatusChange(row)" :active-value="1" :inactive-value="2" />
- </template>
- </el-table-column>
- <el-table-column label="操作" width="130px" align="center" :resizable="false" fixed="right">
- <template slot-scope="{row}">
- <el-link @click="edit(row)" icon="el-icon-edit" type="primary" :underline="false"
- v-if="permission.includes(permissionMap['edit'])">修改</el-link>
- </template>
- </el-table-column>
- </template>
- </ele-data-table>
- </el-card>
- <article-form :defaultType="this.defaultType" :visible.sync="showArticleForm" :defaultData="editArticle"
- @success="reloadTable" />
- <excel-import-dialog :visible.sync="importVisible" @imported="handleImportSuccess" />
- </div>
- </template>
- <script>
- import ExcelImportDialog from './ExcelImportDialog.vue'; // 引入导入弹窗组件
- import ArticleForm from './ArticleForm.vue'
- import { mapGetters } from "vuex";
- export default {
- props: {
- defaultType: { type: [Number, String], default: null },
- permissionMap: { type: Object, default: null },
- },
- name: "Sysarticle",
- components: {
- ArticleForm,
- ExcelImportDialog,
- },
- data() {
- return {
- tableKey: 0,
- table: { url: '/article/index', where: { status: 0, type: 0, show_type: 1, type: null } }, // 表格配置
- choose: [], // 表格选中数据
- showEdit: false, // 是否显示表单弹窗
- editForm: { status: 1, type: 1 }, // 表单数据
- // 类型写死在前端
- typeArr: [
- { id: 1, name: '文章资讯' },
- { id: 2, name: '注册协议' },
- { id: 3, name: '隐私政策' },
- { id: 4, name: 'VIP购买协议' },
- { id: 9, name: '智能问答' },
- ],
- editRules: { // 表单验证规则
- title: [
- { required: true, message: '请输入名称', trigger: 'blur' }
- ],
- type: [
- { required: true, message: '请选择分类', trigger: 'blur' }
- ],
- },
- // 分类
- cates: [],
- loading: false,
- // 自定义文件上传(这里使用把选择的文件转成blob演示)
- file_picker_callback: (callback, value, meta) => {
- let input = document.createElement('input');
- input.setAttribute('type', 'file');
- // 设定文件可选类型
- if (meta.filetype === 'image') {
- input.setAttribute('accept', 'image/*');
- } else if (meta.filetype === 'media') {
- input.setAttribute('accept', 'video/*');
- }
- input.onchange = () => {
- let file = input.files[0];
- let reader = new FileReader();
- reader.onload = (e) => {
- let blob = new Blob([e.target.result], { type: file.type });
- callback(URL.createObjectURL(blob));
- };
- reader.readAsArrayBuffer(file);
- }
- input.click();
- },
- showArticleForm: false,
- editArticle: { status: 1, type: 1 },
- importVisible: false, // 控制导入弹窗显示
- }
- },
- mounted() {
- // 如果父组件传入 defaultType,则直接作为表格过滤条件并刷新表格
- if (this.defaultType) {
- // 创建新对象,保证引用变化
- this.table = {
- ...this.table,
- where: { ...this.table.where, type: Number(this.defaultType) }
- }
- // 通过设置 key 强制刷新整个表格组件
- this.$nextTick(() => {
- this.$refs.table.reload()
- this.tableKey = Date.now() // 新增 data 属性 tableKey
- })
- }
- },
- computed: {
- ...mapGetters(["permission"]),
- editContent() {
- return {
- menubar: false,
- file_picker_callback: this.file_picker_callback,
- skin_url: this.$store.state.theme.theme === 'dark' ? '/tinymce/skins/ui/oxide-dark' : '/tinymce/skins/ui/oxide',
- content_css: this.$store.state.theme.theme === 'dark' ? '/tinymce/skins/content/dark/content.css' : '/tinymce/skins/content/default/content.css'
- };
- }
- },
- methods: {
- getTypeName(typeId) {
- const item = this.typeArr.find(t => t.id === typeId)
- return item ? item.name : '未知类型'
- },
- openCreate() {
- this.editArticle = { status: 1, type: this.defaultType ? Number(this.defaultType) : 1 }
- this.showArticleForm = true
- },
- openEdit(article) {
- this.editArticle = Object.assign({}, article)
- this.showArticleForm = true
- },
- reloadTable() {
- this.$refs.table.reload()
- },
- edit(row) {
- this.editArticle = Object.assign({}, row)
- this.showArticleForm = true
- },
- /* 保存编辑 */
- save() {
- this.$refs['editForm'].validate((valid) => {
- if (valid) {
- const loading = this.$loading({ lock: true });
- this.$http.post('/article/edit', this.editForm).then(res => {
- loading.close();
- if (res.data.code === 0) {
- this.showEdit = false;
- this.$message({ type: 'success', message: res.data.msg });
- this.$refs.table.reload();
- } else {
- this.$message.error(res.data.msg);
- }
- }).catch(e => {
- loading.close();
- this.$message.error(e.message);
- });
- } else {
- return false;
- }
- });
- },
- /* 删除 */
- remove(row) {
- if (!row) { // 批量删除
- if (this.choose.length === 0) return this.$message.error('请至少选择一条数据');
- let ids = this.choose.map(d => d.id);
- this.$confirm('确定要删除选中的记录吗?', '提示', { type: 'warning' }).then(() => {
- const loading = this.$loading({ lock: true });
- this.$http.post('/article/delete', { id: ids }).then(res => {
- loading.close();
- if (res.data.code === 0) {
- this.$message({ type: 'success', message: res.data.msg });
- this.$refs.table.reload();
- } else {
- this.$message.error(res.data.msg);
- }
- }).catch(e => {
- loading.close();
- this.$message.error(e.message);
- });
- }).catch(() => 0);
- } else { // 单个删除
- const loading = this.$loading({ lock: true });
- this.$http.post('/article/delete', { id: row.id }).then(res => {
- loading.close();
- if (res.data.code === 0) {
- this.$message({ type: 'success', message: res.data.msg });
- this.$refs.table.reload();
- } else {
- this.$message.error(res.data.msg);
- }
- }).catch(e => {
- loading.close();
- this.$message.error(e.message);
- });
- }
- },
- /* 处理状态切换 */
- handleStatusChange(row) {
- this.editStatus(row);
- },
- /* 更改状态 */
- editStatus(row) {
- this.$message.closeAll()
- const loading = this.$loading({ lock: true });
- let params = { id: row.id, status: row.status };
- this.$http.post('/article/status', params).then(res => {
- loading.close();
- if (res.data.code === 0) {
- this.$message({ type: 'success', message: res.data.msg });
- } else {
- // 失败时恢复原状态
- row.status = row.status === 1 ? 2 : 1;
- this.$message.error(res.data.msg);
- }
- }).catch(e => {
- loading.close();
- // 失败时恢复原状态
- row.status = row.status === 1 ? 2 : 1;
- this.$message.error(e.message);
- });
- },
- openImportDialog() {
- this.importVisible = true; // 显示导入弹窗
- },
- handleImportSuccess() {
- // 处理导入成功后的操作
- this.reloadTable()
- this.$message.success('导入操作完成');
- },
- }
- }
- </script>
- <style scoped>
- .ele-block>>>.el-upload,
- .ele-block>>>.el-upload-dragger {
- width: 100%;
- }
- </style>
|