跳到主要内容
版本:next

文章数据列表操作菜单

此扩展点用于扩展文章数据列表的操作菜单项。

文章数据列表操作菜单

定义方式

export default definePlugin({
  extensionPoints: {
    "post:list-item:operation:create": (
      post: Ref<ListedPost>
    ): OperationItem<ListedPost>[] | Promise<OperationItem<ListedPost>[]> => {
      return [
        {
          priority: 10,
          component: markRaw(VDropdownItem),
          props: {},
          action: (item?: ListedPost) => {
            // do something
          },
          label: "foo",
          hidden: false,
          permissions: [],
          children: [],
        },
      ];
    },
  },
});
OperationItem
export interface OperationItem<T> {
  priority: number;                 // 排序优先级
  component: Raw<Component>;        // 菜单项组件
  props?: Record\<string, unknown\>;  // 菜单项组件属性
  action?: (item?: T) => void;      // 菜单项点击事件
  label?: string;                   // 菜单项标题
  hidden?: boolean;                 // 菜单项是否隐藏
  permissions?: string[];           // 菜单项 UI 权限
  children?: OperationItem<T>[];    // 子菜单项
}

示例

此示例将实现一个操作菜单项,点击后会将文章内容作为文件下载到本地。

import type { ListedPost } from "@halo-dev/api-client";
import { VDropdownItem } from "@halo-dev/components";
import { definePlugin } from "@halo-dev/console-shared";
import axios from "axios";
import { markRaw } from "vue";

export default definePlugin({
  extensionPoints: {
    "post:list-item:operation:create": () => {
      return [
        {
          priority: 21,
          component: markRaw(VDropdownItem),
          label: "下载到本地",
          visible: true,
          permissions: [],
          action: async (post: ListedPost) => {
            const { data } = await axios.get(
              `/apis/api.console.halo.run/v1alpha1/posts/${post.post.metadata.name}/head-content`
            );
            const blob = new Blob([data.raw], {
              type: "text/plain;charset=utf-8",
            });
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement("a");
            link.href = url;
            link.download = `${post.post.spec.title}.${data.rawType}`;
            link.click();
          },
        },
      ];
    },
  },
});

类型定义

ListedPost

export interface ListedPost {
  categories: Array<{                             // 文章的分类集合
    apiVersion: "content.halo.run/v1alpha1";
    kind: "Category";
    metadata: {
      annotations: {};
      creationTimestamp: string;
      labels: {};
      name: string;                               // 分类的唯一标识
      version: number;
    };
    spec: {
      children: Array<string>;                    // 子分类
      cover: string;                              // 分类封面图
      description: string;                        // 分类描述
      displayName: string;                        // 分类名称
      priority: number;                           // 分类优先级
      slug: string;                               // 分类别名
      template: string;                           // 分类渲染模板
    };
    status: {
      permalink: string;                          // 分类的永久链接
    };
    postCount: number;                            // 分类下的文章总数
  }>;
  contributors: Array<{                           // 文章的贡献者集合
    avatar: string;                               // 贡献者头像
    displayName: string;                          // 贡献者名称
    name: string;                                 // 贡献者唯一标识
  }>;
  owner: {                                        // 文章的作者信息
    avatar: string;                               // 作者头像
    displayName: string;                          // 作者名称
    name: string;                                 // 作者唯一标识
  };
  post: {                                         // 文章信息
    apiVersion: "content.halo.run/v1alpha1";
    kind: "Post";
    metadata: {
      annotations: {};
      creationTimestamp: string;
      labels: {};
      name: string;                               // 文章的唯一标识
      version: number;
    };
    spec: {
      allowComment: boolean;                      // 是否允许评论
      baseSnapshot: string;                       // 内容基础快照
      categories: Array<string>;                  // 文章所属分类
      cover: string;                              // 文章封面图
      deleted: boolean;                           // 是否已删除
      excerpt: {                                  // 文章摘要
        autoGenerate: boolean;                    // 是否自动生成
        raw: string;                              // 摘要内容
      };
      headSnapshot: string;                       // 内容最新快照
      htmlMetas: Array<{}>;
      owner: string;                              // 文章作者的唯一标识
      pinned: boolean;                            // 是否置顶
      priority: number;                           // 文章优先级
      publish: boolean;                           // 是否发布
      publishTime: string;                        // 发布时间
      releaseSnapshot: string;                    // 已发布的内容快照
      slug: string;                               // 文章别名
      tags: Array<string>;                        // 文章所属标签
      template: string;                           // 文章渲染模板
      title: string;                              // 文章标题
      visible: string;                            // 文章可见性
    };
    status: {
      commentsCount: number;                      // 文章评论总数
      conditions: Array<{
        lastTransitionTime: string;
        message: string;
        reason: string;
        status: string;
        type: string;
      }>;
      contributors: Array<string>;
      excerpt: string;                            // 最终的文章摘要,根据是否自动生成计算
      inProgress: boolean;                        // 是否有未发布的内容
      lastModifyTime: string;                     // 文章最后修改时间
      permalink: string;                          // 文章的永久链接
      phase: string;
    };
  };
  stats: {
    approvedComment: number;                      // 已审核的评论数
    totalComment: number;                         // 评论总数
    upvote: number;                               // 点赞数
    visit: number;                                // 访问数
  };
  tags: Array<{                                   // 文章的标签集合
    apiVersion: "content.halo.run/v1alpha1";
    kind: "Tag";
    metadata: {
      annotations: {};
      creationTimestamp: string;
      labels: {};
      name: string;                               // 标签的唯一标识
      version: number;
    };
    spec: {
      color: string;                              // 标签颜色
      cover: string;                              // 标签封面图
      displayName: string;                        // 标签名称
      slug: string;                               // 标签别名
    };
    status: {
      permalink: string;                          // 标签的永久链接
    };
    postCount: number;                            // 标签下的文章总数
  }>;
}