npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qynpm/pickers

v0.0.5

Published

起印业务选择器组件包。

Readme

@qynpm/pickers

起印体系内业务选择器组件包。它承接“选什么”的薄业务封装,底层复用 @qynpm/ui 的通用选择能力。

当前提供:

  • QyShopPicker
  • QyStaffPicker
  • QyRoleStaffPicker
  • QyAttributePicker
  • QyMaterialAttributePicker
  • QyCraftPicker
  • QyFinishedProductPicker
  • QyCategoryTreeSelect
  • QyProductPicker
  • QyProductCategoryMenuPicker
  • QyQuoteOrderPicker

安装

pnpm add @qynpm/pickers

Peer Dependencies:

  • vue
  • element-plus
  • @qynpm/ui

使用

<template>
  <QyShopPicker
    :open="open"
    v-model="selectedShops"
    :fetch-method="ShopAPI.getErpShopList"
    @confirm="handleConfirm"
    @close="open = false"
  />
</template>

QyShopPicker 不直接内置宿主 API。店铺列表通过 fetchMethod(query) 注入,方便 ERP、market、录单独立项目复用同一个组件。

分层

  • @qynpm/ui:提供 QySelectionDialogQyTreeSelect 等底座。
  • @qynpm/pickers:提供店铺、人员、商品等业务选择器薄封装。
  • 宿主项目:提供接口、权限、页面字段回填和业务副作用。

ShopPicker

Props

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | open | boolean | true | 是否打开弹窗 | | modelValue | any[] | [] | 已确认选择的数据 | | selected | any[] | [] | 兼容初始已选数据 | | fetchMethod | Function | - | 店铺列表请求方法 | | multiple | boolean | false | 是否多选 | | rowKey | string | id | 行唯一键 | | labelKey | string | shopName | 已选标签展示字段 | | searchKey | string | shopName | 默认搜索字段 |

Events

| 事件 | 参数 | 说明 | | --- | --- | --- | | update:modelValue | rows | 点击确认后的选择结果 | | confirm | rows | 点击确认 | | cancel | - | 点击取消 | | close | - | 关闭弹窗 | | selection-change | rows | 弹窗草稿选择变化 | | loaded | rows | 数据加载完成 |

StaffPicker

使用

<QyStaffPicker
  :open="open"
  v-model="selectedStaff"
  :fetch-method="PermissionApiAPI.listUsingGET4"
  :dept-fetch-method="PermissionApiAPI.listUsingGET"
  @confirm="handleConfirm"
  @close="open = false"
/>

QyStaffPicker 不内置人员和部门接口。ERP、foundation、market、quotation 等模块通过 fetchMethoddeptFetchMethod 注入各自接口。

Props

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | open | boolean | true | 是否打开弹窗 | | modelValue | any[] | [] | 已确认选择的数据 | | selected | any[] | [] | 兼容初始已选数据 | | fetchMethod | Function | - | 人员列表请求方法 | | deptFetchMethod | Function | - | 部门树请求方法 | | deptFormatter | Function | - | 部门树响应格式转换 | | multiple | boolean | false | 是否多选 | | phoneFlag | boolean | false | 是否隐藏部门树,只保留人员搜索 | | rowKey | string | userId | 行唯一键 | | labelKey | string | userName | 已选标签展示字段 | | deptQueryKey | string | deptId | 部门筛选提交字段 | | deptColumnKey | string | dept.deptName | 部门列读取字段 |

Events

| 事件 | 参数 | 说明 | | --- | --- | --- | | update:modelValue | rows | 点击确认后的选择结果 | | confirm | rows | 点击确认 | | cancel | - | 点击取消 | | close | - | 关闭弹窗 | | selection-change | rows | 弹窗草稿选择变化 | | loaded | rows | 数据加载完成 |

RoleStaffPicker

QyRoleStaffPicker 组合 QyStaffPicker,只增加角色查询协议,不读取登录用户、权限 store 或内置业务接口。

<QyRoleStaffPicker
  v-model="selectedStaff"
  :open="open"
  :role-keys="['designer', 'manager']"
  role-match="any"
  :fetch-method="fetchStaffByRole"
  @confirm="handleConfirm"
  @close="open = false"
/>

fetchMethod 收到一个 Qy-owned RoleStaffFetchContext

type RoleStaffFetchContext = {
  query: Record<string, any>
  roleKeys: string[]
  roleMatch: 'any' | 'all'
}

function fetchStaffByRole(context: RoleStaffFetchContext) {
  return PermissionApi.listStaff(context.query, context.roleKeys, context.roleMatch)
}

角色条件会以 roleKeysroleMatch 写入最终查询;合并顺序为 queryParams → 搜索/分页查询 → 组件角色条件。宿主的其他 queryParams 保留,两个角色字段是组件拥有的保留键。空 roleKeys 也会原样传给宿主,由宿主定义空角色集合的业务含义。角色变化、关闭和重试都会使旧请求失效;旧结果不会触发 loaded、可见列表、确认或父级 modelValue

除角色属性外,QyRoleStaffPicker 继承 QyStaffPicker 的人员、部门、单/多选、回显和 showSelected 属性与事件。

AttributePicker

QyAttributePicker 复用 QySelectionDialog,只负责属性行协议、查询格式化和属性列展示;分类、类型和属性接口均由宿主注入。

<QyAttributePicker
  v-model="selectedAttributes"
  :open="open"
  multiple
  :fetch-method="fetchAttributes"
  :category-options="categories"
  :type-options="attributeTypes"
  :selectable="(row) => row.attrKeyType !== 'readonly'"
  @confirm="handleConfirm"
  @close="open = false"
>
  <template #code="{ row, value }">
    <span :title="row.attrName">{{ value }}</span>
  </template>
</QyAttributePicker>

fetchMethod(query) 收到 Qy-owned 查询对象,默认包含 categorytypekeywordpagepageSizequeryFormatterresponseFormatter 用于宿主字段映射。没有 v-model 绑定时,可用 selected 传入完整已选行,或用 defaultCodes + detailsFetchMethod{ code } 回显详情。空的受控 modelValue 仍然表示空选择,不会回退到旧字段。

默认列展示编码、名称、单/多选、类型和属性值;codevalues 是 Qy-owned row slots,作用域只包含 rowvaluevalues

MaterialAttributePicker

QyMaterialAttributePicker 组合 QyAttributePicker,只增加材质属性摘要展示,不请求或编辑 SKU。它默认在 Qy 查询对象中加入 material: true;宿主可用 queryParams 覆盖该条件,或用 queryFormatter 映射到自己的接口字段。

<QyMaterialAttributePicker
  v-model="selectedAttributes"
  :open="open"
  multiple
  :fetch-method="fetchMaterialAttributes"
  @confirm="handleConfirm"
  @close="open = false"
/>

默认兼容 row.spuDetail.saleFinishedProductAttrValuesmaterialSpuNameselectSkusallSkusmaterialSkuNameoriginMaterialSkuCode。摘要只读归一,不会修改属性行;确认事件仍返回原始属性行引用。

需要其他字段结构时,使用 Qy-owned materialFormattermaterialFieldMap

const materialFieldMap = {
  spuList: 'materials',
  spuCode: 'id',
  spuName: 'name',
  selectedSkus: 'selected',
  allSkus: 'available',
  skuCode: 'code',
  skuName: 'label'
}

values slot 会额外收到 materialSummaries,每个摘要包含 codenameselectedCounttotalCount 和只读 selectedSkus;默认展示 已选数/总数、QyPopover 悬浮明细和无 SKU 空状态。

CraftPicker

QyCraftPicker 复用 QySelectionDialog,只负责工艺分页查询、分类/关键词筛选、跨页多选、回显、互斥工艺展示和原始行确认;工艺、分类与详情接口由宿主注入。

<QyCraftPicker
  v-model="selectedCrafts"
  :open="open"
  :fetch-method="fetchCrafts"
  :category-options="categories"
  :default-codes="defaultCodes"
  :details-fetch-method="fetchCraftDetails"
  @confirm="handleConfirm"
  @close="open = false"
>
  <template #toolbar="{ reload }">
    <button type="button" @click="reload">刷新</button>
  </template>
</QyCraftPicker>

fetchMethod(query) 收到 Qy 查询对象 categorykeywordpagepageSize;分类路径只提交末级值。queryFormatterresponseFormatter 用于宿主字段映射。未绑定 modelValue 时可使用 selected,或使用 defaultCodes + detailsFetchMethod({ code }) 异步回显;显式传入的空 modelValue 不会回退到旧字段。

默认字段为 effectCraftCodeeffectCraftNameeffectCraftMutexRelsmutexCraftName,可通过 Qy-owned rowKeycodeKeylabelKeynameKeymutexListKeymutexCodeKeymutexLabelKey 覆盖。codemutextoolbar 插槽只接收 Qy 定义的行、值、互斥项、查询和刷新能力。

组件固定多选,v-modelconfirm 和其它选择事件均返回原始工艺行数组;只公开 reload(),不暴露底层弹窗、表格或 Element Plus 实例。公共入口为 @qynpm/pickers@qynpm/pickers/craft-picker

FinishedProductPicker

QyFinishedProductPicker 面向基础产品,不承接销售商品 QyProductPicker 的接口或字段。它复用 QySelectionDialog,负责基础产品的分类、类型、关键词、分页、跨页选择、属性摘要、编码回显和原始行确认;产品接口、字典和新增表单由宿主注入。

<QyFinishedProductPicker
  v-model="selectedProducts"
  multiple
  :fetch-method="fetchProducts"
  :category-options="categories"
  :type-options="typeOptions"
  @confirm="handleConfirm"
>
  <template #toolbar="{ reload }">
    <button type="button" @click="reload">刷新</button>
  </template>
</QyFinishedProductPicker>

fetchMethod(query) 收到 Qy 查询对象 categorytypekeywordpagepageSize;分类路径只提交末级值。fixedType 会覆盖用户可编辑类型并禁用类型筛选。未绑定 modelValue 时可用 selected,或使用 defaultCodes + detailsFetchMethod({ code }) 异步回显;显式传入的空 modelValue 不会回退到旧字段。

默认字段为 finishedProductCodefinishedProductNameproductTypeCodeproprietaryAttrListmaterialAttrListcraftAttrRelList,属性项名称默认读取 productAttrName,可通过 Qy-owned 字段属性、rowFormatterqueryFormatterresponseFormatter 覆盖。默认列展示编码、名称、产品类型、专有属性、材质属性和工艺属性;codetypeproprietary-attributesmaterial-attributescraft-attributestoolbar 插槽不接收 Element Plus 实例或行对象。

v-modelconfirmselection-changeloaded 均返回基础产品原始行数组;只公开 reload()。公共入口为 @qynpm/pickers@qynpm/pickers/finished-product-picker

ProcessPicker

QyProcessPicker 复用 QySelectionDialog,负责工序分类、类型、关键词、分页、单/多选、跨页选择、编码回显、状态展示和原始工序行确认;宿主注入列表、分类、类型与详情请求。

<QyProcessPicker
  v-model="selectedProcesses"
  :open="open"
  multiple
  :fetch-method="fetchProcesses"
  :category-options="categories"
  :type-options="typeOptions"
  @confirm="handleConfirm"
  @close="open = false"
>
  <template #toolbar="{ reload }">
    <button type="button" @click="reload">刷新</button>
  </template>
</QyProcessPicker>

fetchMethod(query) 接收 Qy 查询对象 categorytypekeywordpagepageSize;分类路径只提交末级值,fixedType 非空时覆盖用户类型并禁用类型筛选。未绑定 modelValue 时可用 selected,或使用 defaultCodes + detailsFetchMethod({ code }) 回显;显式空 modelValue 不回退。

默认字段为 craftProcessCodecraftProcessNamecraftProcessTypecraftProcessTypeNamesortNocurStatus,可用 Qy-owned 字段属性和 rowFormatter 覆盖。默认状态 0 为启用,其余为停用;statusFormatter(row) 可返回 { label, tone }。默认列展示编码、名称、类型、排序和状态。

selectionMode 优先于 multiplev-modelconfirmselection-changeloaded 都返回原始工序行。codetypesortstatustoolbar 插槽以及唯一公开方法 reload() 均不暴露 Element Plus 实例。公共入口为 @qynpm/pickers@qynpm/pickers/process-picker

工艺选择继续由 QyCraftPicker 负责;工序属性值选择、复制粘贴与多工序详情聚合不属于 QyProcessPicker

ProcessAttributePicker

QyProcessAttributePicker 按宿主传入的工序编码加载详情,负责多工序属性值选择、受控草稿、确认回填以及旧版完整对象数组的复制/粘贴。详情接口由宿主注入,组件不读取业务 API 或权限状态。

<QyProcessAttributePicker
  v-model="selectedValues"
  :open="open"
  :process-codes="['PROCESS-A', 'PROCESS-B']"
  :details-fetch-method="fetchProcessDetails"
  @confirm="handleConfirm"
  @close="open = false"
/>

detailsFetchMethod({ code }) 可以返回直接工序详情,也可以返回 { data: detail }。默认字段兼容 craftProcessCodecraftProcessNamemainAttr.attrCodeprocessValueRelListprocessCodedevelopValuedisplayValue,可通过对应的 Qy-owned *Key 属性映射其他字段。

每个选择返回 processCodeattributeCodedevelopValuedisplayValuerawProcessrawValue;身份由三元组组合,允许不同工序使用相同开发值。复制内容保持旧版格式:[{ ...rawValue, process: rawProcess }],粘贴会在任一条目非法时整次拒绝,并保留未知附加字段与嵌套对象。公共入口为 @qynpm/pickers@qynpm/pickers/process-attribute-picker

CategoryTreeSelect

使用

<QyCategoryTreeSelect
  v-model="categoryCode"
  :fetch-method="RequestAPI.getSellingWareCategory"
  @change="handleCategoryChange"
/>

QyCategoryTreeSelect 不内置分类接口。ERP、market、录单独立项目通过 fetchMethod 注入各自的分类树请求。

Props

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | modelValue | string \| number \| Array | - | 当前选中分类 | | options | any[] | [] | 外部传入分类树 | | fetchMethod | Function | - | 分类树请求方法 | | formatter | Function | - | 响应格式转换 | | multiple | boolean | false | 是否多选 | | labelKey | string | cateName | 分类名称字段 | | valueKey | string | sellingWareCateCode | 分类值字段 | | childrenKey | string | children | 子节点字段 |

Events

| 事件 | 参数 | 说明 | | --- | --- | --- | | update:modelValue | value | 选择值变化 | | change | value, nodes | 选择变化,附带命中的原始节点 | | loaded | nodes | 分类树加载完成 |

ProductPicker

使用

<QyProductPicker
  :open="open"
  v-model="selectedProducts"
  :fetch-method="RequestAPI.getAllSellingWarePage"
  :category-fetch-method="RequestAPI.getSellingWareCategory"
  @confirm="handleConfirm"
  @close="open = false"
/>

QyProductPicker 不内置商品和分类接口。宿主通过 fetchMethodcategoryFetchMethodresponseFormatter 注入接口与响应格式。

Props

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | open | boolean | true | 是否打开弹窗 | | modelValue | any[] | [] | 已确认选择的数据 | | fetchMethod | Function | - | 商品分页请求方法 | | getPageRequest | Function | - | 兼容旧命名的商品分页请求 | | categoryFetchMethod | Function | - | 分类树请求方法 | | getCategoryRequest | Function | - | 兼容旧命名的分类树请求 | | categorySearchMethod | Function | - | 分类关键词远端搜索方法,调用参数为 { conditions } | | responseFormatter | Function | - | 商品响应格式转换 | | multiple | boolean | false | 是否多选 | | selectCate | Array | [] | 初始分类筛选 | | productType | string | '' | 商品类型筛选 |

第一版只做查询、分类筛选、选择和确认回填;不做新增商品、编辑商品、查看详情和已选项拖拽排序。

ProductCategoryMenuPicker

使用

<QyProductCategoryMenuPicker
  :data="cates"
  @select="selectProduct"
/>

QyProductCategoryMenuPicker 是录单旧商品分类菜单的公共化版本。它不内置接口,只负责把宿主传入的分类树渲染成 ElMenu,并保留旧组件的 select 参数形态:selectProduct(code) 中继续通过 code[0] 读取 finishedProductCode

Props

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | data | any[] | [] | 分类树数据 | | categoryLabelKey | string | cateName | 分类名称字段 | | categoryValueKey | string | cateProductCode | 分类编码字段 | | childrenKey | string | children | 子分类字段 | | productListKey | string | productList | 分类下商品列表字段 | | productLabelKey | string | finishedProductName | 商品名称字段 | | productValueKey | string | finishedProductCode | 商品编码字段 | | productImageKey | string | displayImage | 商品图片字段 | | uniqueOpened | boolean | true | 是否只展开一个分类 | | lazyImageOnOpen | boolean | true | 展开分类后延迟渲染图片,复刻旧录单性能策略 | | imageDelayBase | number | 3 | 图片延迟基数,默认兼容旧 (index + 3) * 200 | | imageDelayStep | number | 200 | 图片延迟步长 | | previewWidth | number | 350 | hover 预览 popover 宽度 | | previewImageWidth | number | 310 | 预览图宽度 | | previewImageHeight | number | 200 | 预览图高度 |

Events

| 事件 | 参数 | 说明 | | --- | --- | --- | | select | [index, indexPath, item, routerResult] | 兼容旧录单的数组参数 | | product-select | { value, product, args } | 新项目可使用的结构化商品选择事件 | | open | index, indexPath | 分类展开事件 |

Slots

| 插槽 | 说明 | | --- | --- | | header | 菜单顶部内容 | | category-title | 自定义分类标题 | | product-title | 自定义商品标题 |

QuoteOrderPicker

使用

<QyQuoteOrderPicker
  v-model="quoteOrderCode"
  @search="handleQuoteSearch"
/>

QyQuoteOrderPicker 只负责报价单输入、清空和回车触发。它会按默认正则 (BJ\d{8}.{4}) 提取 code,但默认不改写输入框内容,避免影响旧页面里后续的业务校验和提示。

Props

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | modelValue | string | '' | 输入内容 | | placeholder | string | 填写报价单,回车搜索 | 占位文案 | | size | string | small | Element Plus 输入框尺寸 | | clearable | boolean | true | 是否允许清空 | | extractPattern | RegExp \| string | (BJ\d{8}.{4}) | 报价单号提取规则 | | autoExtract | boolean | false | 搜索时是否把输入框自动改成提取后的单号 |

Events

| 事件 | 参数 | 说明 | | --- | --- | --- | | search | { value, code, raw } | 回车搜索;value 默认是 trim 后原输入,code 是正则提取结果 | | clear | - | 清空输入 | | update:modelValue | value | 输入内容变化 |