<template>
  <TableLayout
    :authorized="$hasPermissions(['cms:article:query'])"
    :fullscreen="fullscreen"
  >
    <!-- 搜索表单 -->
    <template #search-form>
      <SearchForm ref="searchForm" :model="searchForm" :collapse="false">
        <el-form-item label="文章标识" prop="uid">
          <el-input v-model="searchForm.uid" v-trim placeholder="请输入文章标识" @keypress.enter="search"/>
        </el-form-item>
        <el-form-item label="文章标题" prop="title">
          <el-input v-model="searchForm.title" v-trim placeholder="请输入文章标题" @keypress.enter="search"/>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <DictSelect
            code="ARTICLE_STATUS"
            v-model="searchForm.status"
            placeholder="请选择状态"
            :clearable="true"
            @change="search"
          />
        </el-form-item>
        <template #buttons>
          <el-button type="primary" @click="search">搜索</el-button>
          <el-button @click="reset">重置</el-button>
        </template>
      </SearchForm>
    </template>
    <!-- 表格和分页 -->
    <template #table-wrap>
      <div class="category-wrap">
        <el-tree
          style="max-width: 600px"
          :default-expand-all="true"
          :highlight-current="true"
          :expand-on-click-node="false"
          :props="{
            label: 'title',
            children: 'children'
          }"
          :data="categories"
          @node-click="selectCategory"
        />
      </div>
      <div class="search-table-wrap">
        <SearchTable
          v-loading="isWorking.search"
          :data="tableData.list"
          v-model:fullscreen="fullscreen"
          buttons-width="220px"
          @selection-change="handleSelectionChange"
          @refresh="refresh"
        >
          <template
            v-if="$hasAnyPermissions([
              'cms:article:publish',
              'cms:article:delete'
            ])"
            #toolbar
          >
            <el-button
              v-permissions="['cms:article:publish']"
              type="primary"
              icon="Plus"
              @click="$refs.articleEditorWindow.open('新建文章')"
            >新建</el-button>
            <el-button
              v-permissions="['cms:article:delete']"
              type="danger"
              icon="Delete"
              @click="deleteByIdInBatch"
            >删除</el-button>
            <el-button
              v-permissions="['cms:article:online']"
              @click="onlineInBatch"
            >批量上线</el-button>
            <el-button
              v-permissions="['cms:article:offline']"
              @click="offlineInBatch"
            >批量下线</el-button>
            <el-button
              icon="CollectionTag"
              v-permissions="['cms:article:tag:query']"
              @click="$refs.articleTagManageWindow.open()"
            >文章标签管理</el-button>
          </template>
          <el-table-column type="selection" fixed="left" width="55"/>
          <el-table-column prop="cover" label="文章封面图" min-width="100px">
            <template #default="{ row }">
              <el-image
                v-if="row.cover != null && row.cover !== ''"
                style="width: 100px; height: 50px; object-fit: cover;"
                :src="$getImageURL(row.cover)"
                :zoom-rate="1.2"
                :max-scale="3"
                :min-scale="0.5"
                :preview-src-list="[$getImageURL(row.cover)]"
                :preview-teleported="true"
                :hide-on-click-modal="true"
                :initial-index="0"
                fit="contain"
              />
              <template v-else>无封面</template>
            </template>
          </el-table-column>
          <el-table-column prop="title" label="文章标题" min-width="150px" class-name="table-column-title">
            <template #default="{ row }">
              <a :href="`${$c('WEBSITE_URL')}/article/${row.uid}?mode=preview`" target="_blank">
                <PopoverCellValue :only-text="true" :content="row.title"/>
              </a>
            </template>
          </el-table-column>
          <el-table-column prop="contentDigest" label="文章摘要" min-width="180px">
            <template #default="{ row }">
              <PopoverCellValue :content="row.contentDigest"/>
            </template>
          </el-table-column>
          <el-table-column prop="keywords" label="关键字" min-width="150px">
            <template #default="{ row }">
              <PopoverCellValue :content="row.keywords"/>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" min-width="100px">
            <template #default="{ row }">
              {{ $d(`ARTICLE_STATUS.${row.status}`) }}
            </template>
          </el-table-column>
          <el-table-column prop="categories" label="所属栏目" min-width="180px">
            <template #default="{ row }">
              <TagCellValue :data="row.categories" label-key="title"/>
            </template>
          </el-table-column>
          <el-table-column prop="tags" label="标签" min-width="180px">
            <template #default="{ row }">
              <TagCellValue :data="row.tags" label-key="name"/>
            </template>
          </el-table-column>
          <el-table-column prop="creatorRealName" label="创建人" min-width="100px"/>
          <el-table-column prop="createdAt" label="创建时间" min-width="185px"/>
          <el-table-column prop="updaterRealName" label="更新人" min-width="100px"/>
          <el-table-column prop="updatedAt" label="更新时间" min-width="185px"/>
          <template
            v-if="$hasAnyPermissions([
              'cms:article:online',
              'cms:article:offline',
              'cms:article:publish',
              'cms:article:delete'
            ])"
            #buttons="{ row }"
          >
            <el-button
              v-if="row.status === $const.ARTICLE_STATUS.OFFLINE"
              type="primary"
              v-permissions="['cms:article:online']"
              @click="online(row)"
              link
            >上线</el-button>
            <el-button
              v-if="row.status === $const.ARTICLE_STATUS.ONLINE"
              type="primary"
              v-permissions="['cms:article:offline']"
              @click="offline(row)"
              link
            >下线</el-button>
            <el-button
              type="primary"
              icon="EditPen"
              v-permissions="['cms:article:publish']"
              @click="$refs.articleEditorWindow.open('编辑文章', row)"
              link
            >编辑</el-button>
            <el-button
              type="danger"
              icon="Delete"
              v-permissions="['cms:article:delete']"
              @click="deleteById(row)"
              link
            >删除</el-button>
          </template>
        </SearchTable>
        <pagination
          :pagination="tableData.pagination"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>
    </template>
    <!-- 新建编辑窗口 -->
    <ArticleEditorWindow
      ref="articleEditorWindow"
      @exit="refresh"
    />
    <!-- 标签管理 -->
    <ArticleTagManageWindow ref="articleTagManageWindow"/>
  </TableLayout>
</template>

<script>
import BaseTable from '@/components/base/BaseTable'
import ArticleEditorWindow from '@/components/cms/article/editor/ArticleEditorWindow'
import ArticleTagManageWindow from "@/components/cms/article/ArticleTagManageWindow.vue";
import { fetchAll } from '@/api/cms/category'
import { offline, offlineInBatch, online, onlineInBatch, deleteByIdInBatch } from '@/api/cms/article'

export default {
  extends: BaseTable,
  components: { ArticleTagManageWindow, ArticleEditorWindow },
  data () {
    return {
      // 栏目树
      categories: [],
      // 搜索
      searchForm: {
        uid: '',
        categoryIds: [],
        title: '',
        status: ''
      }
    }
  },
  methods: {
    // 查询栏目树
    fetchCategoryTree () {
      fetchAll()
        .then(data => {
          this.categories = [{
            id: -1,
            title: '全部',
            children: data
          }]
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    // 选择栏目
    selectCategory (node) {
      this.searchForm.categoryIds = []
      // 不是点击全部，则填充当前栏目及所有的子栏目
      if (node.id !== -1) {
        this.__fillCategoryIds(node, this.searchForm.categoryIds)
      }
      this.search()
    },
    // 下线
    offline (row) {
      this.$dialog.confirm(`确认下线文章《${row.title}》吗？`, '确认下线', {
        confirmButtonText: '确认下线',
        confirmButtonClass: 'el-button--danger',
        type: 'warning',
        showCancelButton: true
      })
        .then(() => {
          return offline(row.id)
        })
        .then(() => {
          this.refresh()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    // 批量下线
    offlineInBatch () {
      if (this.tableData.selectedRows.length === 0) {
        this.$tip.warning('请至少选择一篇文章')
        return
      }
      this.$dialog.confirm(`确认下线已选中的 ${this.tableData.selectedRows.length} 篇文章吗？`, '确认下线', {
        confirmButtonText: '确认下线',
        confirmButtonClass: 'el-button--danger',
        type: 'warning',
        showCancelButton: true
      })
        .then(() => {
          return offlineInBatch(this.tableData.selectedRows.map(item => item.id).join(','))
        })
        .then(count => {
          // 组装提示消息
          let type = 'success'
          let message = `成功下线 ${count} 篇文章`
          if (count !== this.tableData.selectedRows.length) {
            type = 'warning'
            message = `成功下线 ${count} 篇文章，其中 ${this.tableData.selectedRows.length - count} 篇文章因状态不符合条件不可下线！`
          }
          // 采用确认框进行提示
          return this.$dialog.confirm(message, '提醒', {
            confirmButtonText: '确定',
            type,
            showCancelButton: false
          })
        })
        .then(() => {
          this.refresh()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    // 上线
    online (row) {
      this.$dialog.confirm(`确认上线文章《${row.title}》吗？`, '确认上线', {
        confirmButtonText: '确认上线',
        type: 'warning',
        showCancelButton: true
      })
        .then(() => {
          return online(row.id)
        })
        .then(() => {
          this.refresh()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    // 批量上线
    onlineInBatch () {
      if (this.tableData.selectedRows.length === 0) {
        this.$tip.warning('请至少选择一篇文章')
        return
      }
      this.$dialog.confirm(`确认上线已选中的 ${this.tableData.selectedRows.length} 篇文章吗？`, '确认上线', {
        confirmButtonText: '确认上线',
        type: 'warning',
        showCancelButton: true
      })
        .then(() => {
          return onlineInBatch(this.tableData.selectedRows.map(item => item.id).join(','))
        })
        .then(count => {
          // 组装提示消息
          let type = 'success'
          let message = `成功上线 ${count} 篇文章`
          if (count !== this.tableData.selectedRows.length) {
            type = 'warning'
            message = `成功上线 ${count} 篇文章，其中 ${this.tableData.selectedRows.length - count} 篇文章因状态不符合条件不可上线！`
          }
          // 采用确认框进行提示
          return this.$dialog.confirm(message, '提醒', {
            confirmButtonText: '确定',
            type,
            showCancelButton: false
          })
        })
        .then(() => {
          this.refresh()
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    // 批量删除（点击批量删除时触发）
    deleteByIdInBatch () {
      if (this.tableData.selectedRows.length === 0) {
        this.$tip.warning('请至少选择一篇文章')
        return
      }
      this.$dialog.deleteConfirm(`确认删除已选中的 ${this.tableData.selectedRows.length} 篇文章吗?`)
        .then(() => {
          this.isWorking.delete = true
          return deleteByIdInBatch(this.tableData.selectedRows.map(row => row.id).join(','))
        })
        .then(count => {
          // 组装提示消息
          let type = 'success'
          let message = `成功删除 ${count} 篇文章`
          if (count !== this.tableData.selectedRows.length) {
            type = 'warning'
            message = `成功删除 ${count} 篇文章，其中 ${this.tableData.selectedRows.length - count} 篇已发布状态的文章需要先执行下线操作后才可删除！`
          }
          // 采用确认框进行提示
          return this.$dialog.confirm(message, '提醒', {
            confirmButtonText: '确定',
            type,
            showCancelButton: false
          })
        })
        .then(() => {
          this.__afterDelete(this.tableData.selectedRows.length)
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.isWorking.delete = false
        })
    },
    // 获取栏目ID集
    __fillCategoryIds (node, pool) {
      pool.push(node.id)
      if (node.children != null && node.children.length > 0) {
        for (const child of node.children) {
          this.__fillCategoryIds(child, pool)
        }
      }
    }
  },
  async created () {
    this.config({
      module: '文章',
      api: await import('@/api/cms/article')
    })
    // 查询栏目树
    this.fetchCategoryTree()
    // 执行搜索
    this.search()
  }
}
</script>
<style scoped lang="scss">
:deep(.table-wrap) {
  display: flex;
  overflow: hidden;
  padding-bottom: 16px;
  // 栏目树
  .category-wrap {
    width: 200px;
    flex-shrink: 0;
    padding: 0 16px 0 0;
    border-right: 1px solid #eee;
    .el-tree-node {
      // 选中状态
      &.is-current {
        // 背景色
        --el-color-primary-light-9: var(--color-primary);
        // 文字
        & > .el-tree-node__content > .el-tree-node__label{
          color: #fff;
        }
        // 图标
        & > .el-tree-node__content > .el-tree-node__expand-icon{
          color: #fff;
        }
      }
    }
  }
  // 表格
  .search-table-wrap {
    padding: 0 0 0 16px;
    flex-grow: 1;
    overflow: hidden;
    .el-table {
      // 文章标题列
      .table-column-title {
        a {
          color: var(--color-primary);
        }
      }
    }
  }
}
</style>
