index.vue 3.15 KB
<!--
  列表项操作按钮组件

  @description 统一的列表项操作按钮组件,支持查看、收藏、删除三种操作
  @example
  <ListItemActions
    :viewable="true"
    :collectable="true"
    :deletable="true"
    :collected="item.collected"
    :item-id="item.id"
    @view="onView(item)"
    @collect="onCollect(item)"
    @delete="onDelete(item)"
  />
-->
<template>
  <view class="flex justify-end gap-[24rpx]">
    <!-- 查看按钮 -->
    <view v-if="viewable" class="flex items-center text-blue-600" @tap.stop="handleView">
      <IconFont name="eye" size="14" class="mr-[8rpx]" />
      <text class="text-[24rpx]">查看</text>
    </view>

    <!-- 收藏按钮 -->
    <view v-if="collectable" class="flex items-center" :class="isCollected ? 'text-red-500' : 'text-gray-400'" @tap.stop="handleCollect">
      <IconFont :name="isCollected ? 'heart-fill' : 'heart'" size="14" class="mr-[8rpx]" />
      <text class="text-[24rpx]">{{ isCollected ? '已收藏' : '收藏' }}</text>
    </view>

    <!-- 删除按钮 -->
    <view v-if="deletable" class="flex items-center text-red-500" @tap.stop="handleDelete">
      <IconFont name="del" size="14" class="mr-[8rpx]" />
      <text class="text-[24rpx]">删除</text>
    </view>
  </view>
</template>

<script setup>
import { computed } from 'vue'
import IconFont from '@/components/icons/IconFont.vue'
import { useEventTracking } from '@/composables/useEventTracking'
import { usePermission } from '@/composables/usePermission'

/**
 * 组件属性
 */
const props = defineProps({
  /**
   * 是否显示查看按钮
   * @type {boolean}
   * @default true
   */
  viewable: {
    type: Boolean,
    default: true
  },
  /**
   * 是否显示收藏按钮
   * @type {boolean}
   * @default false
   */
  collectable: {
    type: Boolean,
    default: false
  },
  /**
   * 是否显示删除按钮
   * @type {boolean}
   * @default false
   */
  deletable: {
    type: Boolean,
    default: false
  },
  /**
   * 是否已收藏
   * @type {boolean}
   * @default false
   */
  collected: {
    type: Boolean,
    default: false
  },
  /**
   * 关联对象 ID(用于埋点)
   * @type {string}
   */
  itemId: {
    type: String,
    default: ''
  }
})

/**
 * 组件事件
 */
const emit = defineEmits({
  /**
   * 点击查看按钮时触发
   */
  view: null,
  /**
   * 点击收藏按钮时触发
   */
  collect: null,
  /**
   * 点击删除按钮时触发
   */
  delete: null
})

const isCollected = computed(() => props.collected)

// 初始化埋点功能
const { trackFileRead } = useEventTracking()

// 初始化权限检查
const { requireAction } = usePermission()

/**
 * 处理查看点击
 *
 * @description 先检查权限,通过后发送埋点并通知父组件
 */
const handleView = () => {
  requireAction('view_material', () => {
    // 权限检查通过后,发送埋点
    if (props.itemId) {
      trackFileRead(props.itemId)
    }
    // 通知父组件执行实际业务逻辑
    emit('view')
  })
}

/**
 * 处理收藏点击
 */
const handleCollect = () => {
  emit('collect')
}

/**
 * 处理删除点击
 */
const handleDelete = () => {
  emit('delete')
}
</script>

<style lang="less" scoped>
</style>