跳转正文

YDataSelectionTask ​

适用范围:Legacy Admin Kit / Schema 与旧 admin-vue。新 admin-nuxtui 的开发入口见管理端 Nuxt UI 指南。

定位 / Owner ​

YDataSelectionTask 是从远程、可分页数据集中选择多个记录的共享任务构图。它复用 LegacyYDataTable 与 Data Workbench runtime,负责选择会话、Dialog body/footer 关系和显式确认,不拥有业务写入。

权威边界:

  • Data Workbench runtime 拥有 query、filter、pagination 与 selection;
  • YDataSelectionTask 只保留当前打开会话的待确认 row keys;
  • feature 在 confirm 后调用已有 mutation,并决定何时关闭;
  • parent 的 selectedRowKeys 是下一次打开时的已确认基线。

文档内可运行示例 ​

可运行示例

搜索与跨页选择

第一页选择 member-01,下一页选择 member-11;取消后页面结果仍为 member-02。重新打开可搜索 member-24,确认后查看结果。

查看同源 Vue 代码
<script setup lang="ts">
import { ref } from 'vue'
import { YButton, YDataSelectionTask, type YDataRuntimeInput } from '@yoyoboot/yoyo-admin-kit'
import { compileYoyoPageSchema } from '@yoyoboot/yoyo-admin-schema'

const open = ref(false)
const confirmed = ref<readonly string[]>(['member-02'])
const rows = Array.from({ length: 24 }, (_, index) => ({
  id: `member-${String(index + 1).padStart(2, '0')}`,
  name: `演示成员 ${index + 1}`,
}))
const input: YDataRuntimeInput = {
  environment: 'test',
  page: compileYoyoPageSchema({
    schemaVersion: 1,
    pageKind: 'query',
    pageKey: 'docs-member-selection',
    title: '选择演示成员',
    query: {
      datasource: 'docs.members',
      fields: [{ key: 'keyword', kind: 'text', label: '成员编号或名称' }],
      presentation: { pageSize: 10 },
    },
    table: {
      rowKey: 'id',
      columns: [
        { key: 'id', title: '编号', renderer: 'text', role: 'identity', priority: 'high', mobilePlacement: 'headline' },
        { key: 'name', title: '名称', renderer: 'text', role: 'key', priority: 'high', mobilePlacement: 'supporting' },
      ],
    },
    actions: [],
  }).ir,
  binding: {
    kind: 'fixture',
    datasource: {
      id: 'docs.members',
      async query({ state, filter, signal }) {
        if (signal.aborted) throw new DOMException('Aborted', 'AbortError')
        const keyword = String(filter.keyword ?? '').trim().toLowerCase()
        const matching = rows.filter(row => `${row.id} ${row.name}`.toLowerCase().includes(keyword))
        return {
          ...state,
          items: matching.slice(state.skipCount, state.skipCount + state.pageSize),
          totalCount: matching.length,
          pageCount: Math.max(1, Math.ceil(matching.length / state.pageSize)),
        }
      },
    },
  },
}

function confirm(keys: readonly string[]) {
  confirmed.value = [...keys]
  open.value = false
}
</script>

<template>
  <YButton type="button" @click="open = true">打开成员选择</YButton>
  <p role="status">已确认:{{ confirmed.join('、') || '无' }}</p>
  <p>24 条内存数据,每页 10 条;取消不回填。确认只更新本例结果,不调用业务 API。</p>
  <YDataSelectionTask
    v-model:open="open"
    title="选择演示成员"
    description="可搜索并跨页选择,确认后才更新页面结果。"
    :input="input"
    :selected-row-keys="confirmed"
    @confirm="confirm"
  />
</template>

运行和源码展示来自同一 Vue 文件,只从公开包入口导入;筛选/分页由演示 datasource 适配,选择状态由正式 Data runtime 拥有。本地示例不是 npm 已发布或后端写入证据。

真实接入参见组织机构选择消费说明,作者入口见 Authoring,独立项目安装见 External Consumption。

Public API ​

ts
open: boolean
title: string
description?: string
input: YDataRuntimeInput
presentation?: YoyoAdminKitDataTablePresentation
selectedRowKeys: readonly string[]
busy?: boolean
error?: string
confirmText?: string
cancelText?: string
selectionLabel?: string

'update:open': [value: boolean]
confirm: [rowKeys: readonly string[]]

当前首批合同是显式多选:内部固定 allowAllMatching: false。全匹配选择、单选、树选择和 remote field renderer 不属于本组件当前合同。

什么时候使用 ​

  • 候选记录来自远程分页 API,固定加载前 100 条已经不可靠;
  • 用户需要搜索、跨页勾选,再一次确认业务动作;
  • feature 已有 purpose-specific datasource 和 mutation owner。

例如 Organization Unit 的“加入用户”:候选查询继续调用 FindUsers,确认后仍由 feature 调用 AddUsers。

什么时候不使用 ​

  • 少量静态枚举继续使用 YSelect,不要为统一外观引入 Data Workbench;
  • 层级关系使用正式 tree owner,不把树拍平成表格选择;
  • 不在 task 外再维护一份分页、筛选或当前页选择;
  • 不在共享组件中调用业务 mutation、自动关闭成功任务或吞掉服务端错误。

会话与失败语义 ​

text
每次 open
  → 以 selectedRowKeys 创建新的选择会话
  → 搜索/分页时 runtime 保留显式 row keys
  → cancel 只关闭,不发出 confirm
  → confirm 发出去重 row keys
  → feature mutation 成功后关闭
  → mutation 失败时保持打开并显示 error,选择草稿不丢失

busy 时禁止关闭和重复确认。错误信息由 feature 提供,因为业务 mutation 和错误解释仍属于 feature owner。

每次打开时固定当前 input,父级在会话期间替换输入不会重建当前选择;下一次打开才采用新输入。任务标题由外层 YModal 唯一呈现,内部通过 presentation.hidePageHeader 隐藏整个页面标题区,避免重复标题和页面级操作。独立 LegacyYDataTable 默认仍显示页面标题。

Live Workbench ​

Admin Vue 稳定路径:

/frontend-module-demo/component-workbench/data-selection-task

该 fixture 场景覆盖搜索、跨页显式选择、取消/重开以及确认结果;真实业务 consumer 位于 Identity Organization Units。

Verification / Source ​

  • packages/yoyo-admin/admin-kit/src/kit/data/selection-task/YDataSelectionTask.vue
  • packages/yoyo-admin/admin-kit/tests/unit/kit/data/data-selection-task.spec.ts
  • apps/yoyo-admin/admin-vue/src/app/administration/identity/organization-units/
  • Component Workbench focused tests

YoyoBoot · 从真实项目走向可复用能力